From 025e084b099bc3a4e1bfd84c8a6345861c62a702 Mon Sep 17 00:00:00 2001 From: false_genesis Date: Thu, 3 Apr 2008 18:20:11 +0000 Subject: [PATCH] * irrlicht upgrade PART 2: upped irr 1.4 * someone please fix sln/vcproj for vc80 --- PseuWoW.sln | 38 +- src/PseuWoW.vcproj | 94 +- src/dep/include/irrlicht/CMeshBuffer.h | 166 + src/dep/include/irrlicht/ECullingTypes.h | 39 + src/dep/include/irrlicht/EDebugSceneTypes.h | 47 + src/dep/include/irrlicht/EDriverFeatures.h | 88 + src/dep/include/irrlicht/EDriverTypes.h | 56 + src/dep/include/irrlicht/EGUIElementTypes.h | 123 + src/dep/include/irrlicht/EMaterialFlags.h | 74 + src/dep/include/irrlicht/EMaterialTypes.h | 223 + src/dep/include/irrlicht/EMeshWriterEnums.h | 48 + src/dep/include/irrlicht/EMessageBoxFlags.h | 35 + .../irrlicht/ESceneNodeAnimatorTypes.h | 53 + src/dep/include/irrlicht/ESceneNodeTypes.h | 89 + src/dep/include/irrlicht/ETerrainElements.h | 36 + src/dep/include/irrlicht/IAnimatedMesh.h | 103 + src/dep/include/irrlicht/IAnimatedMeshMD2.h | 79 + src/dep/include/irrlicht/IAnimatedMeshMD3.h | 258 + .../include/irrlicht/IAnimatedMeshSceneNode.h | 213 + .../irrlicht/IAttributeExchangingObject.h | 71 + src/dep/include/irrlicht/IAttributes.h | 753 ++ .../include/irrlicht/IBillboardSceneNode.h | 56 + src/dep/include/irrlicht/IBoneSceneNode.h | 103 + src/dep/include/irrlicht/ICameraSceneNode.h | 148 + src/dep/include/irrlicht/ICursorControl.h | 81 + .../irrlicht/IDummyTransformationSceneNode.h | 42 + src/dep/include/irrlicht/IEventReceiver.h | 263 + src/dep/include/irrlicht/IFileList.h | 58 + src/dep/include/irrlicht/IFileSystem.h | 197 + .../irrlicht/IGPUProgrammingServices.h | 274 + src/dep/include/irrlicht/IGUIButton.h | 136 + src/dep/include/irrlicht/IGUICheckBox.h | 38 + .../include/irrlicht/IGUIColorSelectDialog.h | 33 + src/dep/include/irrlicht/IGUIComboBox.h | 54 + src/dep/include/irrlicht/IGUIContextMenu.h | 108 + src/dep/include/irrlicht/IGUIEditBox.h | 114 + src/dep/include/irrlicht/IGUIElement.h | 943 +++ src/dep/include/irrlicht/IGUIElementFactory.h | 70 + src/dep/include/irrlicht/IGUIEnvironment.h | 428 + src/dep/include/irrlicht/IGUIFileOpenDialog.h | 36 + src/dep/include/irrlicht/IGUIFont.h | 95 + src/dep/include/irrlicht/IGUIFontBitmap.h | 49 + src/dep/include/irrlicht/IGUIImage.h | 55 + src/dep/include/irrlicht/IGUIInOutFader.h | 69 + src/dep/include/irrlicht/IGUIListBox.h | 126 + src/dep/include/irrlicht/IGUIMeshViewer.h | 56 + src/dep/include/irrlicht/IGUIScrollBar.h | 59 + src/dep/include/irrlicht/IGUISkin.h | 515 ++ src/dep/include/irrlicht/IGUISpinBox.h | 70 + src/dep/include/irrlicht/IGUISpriteBank.h | 73 + src/dep/include/irrlicht/IGUIStaticText.h | 104 + src/dep/include/irrlicht/IGUITabControl.h | 87 + src/dep/include/irrlicht/IGUIToolbar.h | 43 + src/dep/include/irrlicht/IGUIWindow.h | 44 + src/dep/include/irrlicht/IImage.h | 113 + src/dep/include/irrlicht/IImageLoader.h | 48 + src/dep/include/irrlicht/IImageWriter.h | 36 + src/dep/include/irrlicht/ILightSceneNode.h | 49 + src/dep/include/irrlicht/ILogger.h | 95 + src/dep/include/irrlicht/IMaterialRenderer.h | 97 + .../irrlicht/IMaterialRendererServices.h | 93 + src/dep/include/irrlicht/IMesh.h | 62 + src/dep/include/irrlicht/IMeshBuffer.h | 117 + src/dep/include/irrlicht/IMeshCache.h | 131 + src/dep/include/irrlicht/IMeshLoader.h | 48 + src/dep/include/irrlicht/IMeshManipulator.h | 121 + src/dep/include/irrlicht/IMeshSceneNode.h | 49 + src/dep/include/irrlicht/IMeshWriter.h | 48 + .../include/irrlicht/IMetaTriangleSelector.h | 44 + src/dep/include/irrlicht/IOSOperator.h | 47 + src/dep/include/irrlicht/IParticleAffector.h | 84 + .../IParticleAnimatedMeshSceneNodeEmitter.h | 56 + .../irrlicht/IParticleAttractionAffector.h | 59 + .../include/irrlicht/IParticleBoxEmitter.h | 36 + .../irrlicht/IParticleCylinderEmitter.h | 59 + src/dep/include/irrlicht/IParticleEmitter.h | 113 + .../irrlicht/IParticleFadeOutAffector.h | 43 + .../irrlicht/IParticleGravityAffector.h | 43 + .../include/irrlicht/IParticleMeshEmitter.h | 56 + .../include/irrlicht/IParticleRingEmitter.h | 47 + .../irrlicht/IParticleRotationAffector.h | 41 + .../include/irrlicht/IParticleSphereEmitter.h | 41 + .../irrlicht/IParticleSystemSceneNode.h | 416 + src/dep/include/irrlicht/IQ3LevelMesh.h | 42 + src/dep/include/irrlicht/IQ3Shader.h | 609 ++ src/dep/include/irrlicht/IReadFile.h | 60 + src/dep/include/irrlicht/IReferenceCounted.h | 159 + .../include/irrlicht/ISceneCollisionManager.h | 151 + src/dep/include/irrlicht/ISceneManager.h | 1238 +++ src/dep/include/irrlicht/ISceneNode.h | 710 ++ src/dep/include/irrlicht/ISceneNodeAnimator.h | 59 + .../ISceneNodeAnimatorCollisionResponse.h | 93 + .../irrlicht/ISceneNodeAnimatorFactory.h | 71 + src/dep/include/irrlicht/ISceneNodeFactory.h | 70 + .../irrlicht/ISceneUserDataSerializer.h | 48 + .../irrlicht/IShaderConstantSetCallBack.h | 66 + .../include/irrlicht/IShadowVolumeSceneNode.h | 33 + src/dep/include/irrlicht/ISkinnedMesh.h | 204 + src/dep/include/irrlicht/ITerrainSceneNode.h | 141 + src/dep/include/irrlicht/ITextSceneNode.h | 37 + src/dep/include/irrlicht/ITexture.h | 180 + src/dep/include/irrlicht/ITimer.h | 71 + src/dep/include/irrlicht/ITriangleSelector.h | 91 + src/dep/include/irrlicht/IVideoDriver.h | 811 ++ src/dep/include/irrlicht/IVideoModeList.h | 58 + src/dep/include/irrlicht/IWriteFile.h | 52 + src/dep/include/irrlicht/IXMLReader.h | 31 + src/dep/include/irrlicht/IXMLWriter.h | 77 + src/dep/include/irrlicht/IrrCompileConfig.h | 314 + src/dep/include/irrlicht/IrrlichtDevice.h | 183 + src/dep/include/irrlicht/Keycodes.h | 163 + src/dep/include/irrlicht/S3DVertex.h | 219 + src/dep/include/irrlicht/SAnimatedMesh.h | 155 + src/dep/include/irrlicht/SColor.h | 541 ++ src/dep/include/irrlicht/SExposedVideoData.h | 87 + .../include/irrlicht/SIrrCreationParameters.h | 140 + src/dep/include/irrlicht/SKeyMap.h | 37 + src/dep/include/irrlicht/SLight.h | 91 + src/dep/include/irrlicht/SMaterial.h | 387 + src/dep/include/irrlicht/SMaterialLayer.h | 170 + src/dep/include/irrlicht/SMesh.h | 112 + src/dep/include/irrlicht/SMeshBuffer.h | 7 + .../include/irrlicht/SMeshBufferLightMap.h | 7 + .../include/irrlicht/SMeshBufferTangents.h | 7 + src/dep/include/irrlicht/SParticle.h | 48 + src/dep/include/irrlicht/SSharedMeshBuffer.h | 141 + src/dep/include/irrlicht/SSkinMeshBuffer.h | 228 + src/dep/include/irrlicht/SViewFrustum.h | 342 + src/dep/include/irrlicht/SceneParameters.h | 114 + src/dep/include/irrlicht/aabbox3d.h | 292 + src/dep/include/irrlicht/coreutil.h | 53 + src/dep/include/irrlicht/dimension2d.h | 78 + src/dep/include/irrlicht/fast_atof.h | 116 + src/dep/include/irrlicht/heapsort.h | 71 + src/dep/include/irrlicht/irrAllocator.h | 116 + src/dep/include/irrlicht/irrArray.h | 521 ++ src/dep/include/irrlicht/irrList.h | 392 + src/dep/include/irrlicht/irrMap.h | 946 +++ src/dep/include/irrlicht/irrMath.h | 445 + src/dep/include/irrlicht/irrString.h | 875 ++ src/dep/include/irrlicht/irrTypes.h | 160 + src/dep/include/irrlicht/irrXML.h | 541 ++ src/dep/include/irrlicht/irrlicht.h | 333 + src/dep/include/irrlicht/line2d.h | 171 + src/dep/include/irrlicht/line3d.h | 126 + src/dep/include/irrlicht/matrix4.h | 1639 ++++ src/dep/include/irrlicht/plane3d.h | 224 + src/dep/include/irrlicht/position2d.h | 116 + src/dep/include/irrlicht/quaternion.h | 563 ++ src/dep/include/irrlicht/rect.h | 257 + src/dep/include/irrlicht/triangle3d.h | 235 + src/dep/include/irrlicht/vector2d.h | 256 + src/dep/include/irrlicht/vector3d.h | 286 + src/dep/src/irrlicht/BuiltInFont.h | 1065 +++ src/dep/src/irrlicht/C3DSMeshFileLoader.cpp | 1268 +++ src/dep/src/irrlicht/C3DSMeshFileLoader.h | 177 + src/dep/src/irrlicht/CAnimatedMeshMD2.cpp | 759 ++ src/dep/src/irrlicht/CAnimatedMeshMD2.h | 109 + src/dep/src/irrlicht/CAnimatedMeshMD3.cpp | 404 + src/dep/src/irrlicht/CAnimatedMeshMD3.h | 138 + .../src/irrlicht/CAnimatedMeshSceneNode.cpp | 1010 +++ src/dep/src/irrlicht/CAnimatedMeshSceneNode.h | 203 + src/dep/src/irrlicht/CAttributeImpl.h | 1991 +++++ src/dep/src/irrlicht/CAttributes.cpp | 1553 ++++ src/dep/src/irrlicht/CAttributes.h | 732 ++ src/dep/src/irrlicht/CB3DMeshFileLoader.cpp | 993 +++ src/dep/src/irrlicht/CB3DMeshFileLoader.h | 118 + src/dep/src/irrlicht/CBSPMeshFileLoader.cpp | 83 + src/dep/src/irrlicht/CBSPMeshFileLoader.h | 50 + src/dep/src/irrlicht/CBillboardSceneNode.cpp | 243 + src/dep/src/irrlicht/CBillboardSceneNode.h | 88 + src/dep/src/irrlicht/CBoneSceneNode.cpp | 124 + src/dep/src/irrlicht/CBoneSceneNode.h | 88 + src/dep/src/irrlicht/CCSMLoader.cpp | 877 ++ src/dep/src/irrlicht/CCSMLoader.h | 83 + src/dep/src/irrlicht/CCameraFPSSceneNode.cpp | 302 + src/dep/src/irrlicht/CCameraFPSSceneNode.h | 104 + src/dep/src/irrlicht/CCameraMayaSceneNode.cpp | 329 + src/dep/src/irrlicht/CCameraMayaSceneNode.h | 90 + src/dep/src/irrlicht/CCameraSceneNode.cpp | 309 + src/dep/src/irrlicht/CCameraSceneNode.h | 145 + src/dep/src/irrlicht/CColladaFileLoader.cpp | 1571 ++++ src/dep/src/irrlicht/CColladaFileLoader.h | 313 + src/dep/src/irrlicht/CColladaMeshWriter.cpp | 690 ++ src/dep/src/irrlicht/CColladaMeshWriter.h | 69 + src/dep/src/irrlicht/CColorConverter.cpp | 571 ++ src/dep/src/irrlicht/CColorConverter.h | 84 + src/dep/src/irrlicht/CCubeSceneNode.cpp | 173 + src/dep/src/irrlicht/CCubeSceneNode.h | 69 + src/dep/src/irrlicht/CD3D8Driver.cpp | 2128 +++++ src/dep/src/irrlicht/CD3D8Driver.h | 297 + src/dep/src/irrlicht/CD3D8MaterialRenderer.h | 596 ++ .../src/irrlicht/CD3D8NormalMapRenderer.cpp | 238 + src/dep/src/irrlicht/CD3D8NormalMapRenderer.h | 56 + .../src/irrlicht/CD3D8ParallaxMapRenderer.cpp | 306 + .../src/irrlicht/CD3D8ParallaxMapRenderer.h | 61 + .../irrlicht/CD3D8ShaderMaterialRenderer.cpp | 316 + .../irrlicht/CD3D8ShaderMaterialRenderer.h | 82 + src/dep/src/irrlicht/CD3D8Texture.cpp | 646 ++ src/dep/src/irrlicht/CD3D8Texture.h | 120 + src/dep/src/irrlicht/CD3D9Driver.cpp | 2215 +++++ src/dep/src/irrlicht/CD3D9Driver.h | 305 + .../irrlicht/CD3D9HLSLMaterialRenderer.cpp | 291 + .../src/irrlicht/CD3D9HLSLMaterialRenderer.h | 79 + src/dep/src/irrlicht/CD3D9MaterialRenderer.h | 622 ++ .../src/irrlicht/CD3D9NormalMapRenderer.cpp | 296 + src/dep/src/irrlicht/CD3D9NormalMapRenderer.h | 53 + .../src/irrlicht/CD3D9ParallaxMapRenderer.cpp | 399 + .../src/irrlicht/CD3D9ParallaxMapRenderer.h | 59 + .../irrlicht/CD3D9ShaderMaterialRenderer.cpp | 528 ++ .../irrlicht/CD3D9ShaderMaterialRenderer.h | 100 + src/dep/src/irrlicht/CD3D9Texture.cpp | 689 ++ src/dep/src/irrlicht/CD3D9Texture.h | 127 + src/dep/src/irrlicht/CDMFLoader.cpp | 448 + src/dep/src/irrlicht/CDMFLoader.h | 97 + .../irrlicht/CDefaultGUIElementFactory.cpp | 154 + .../src/irrlicht/CDefaultGUIElementFactory.h | 70 + .../CDefaultSceneNodeAnimatorFactory.cpp | 138 + .../CDefaultSceneNodeAnimatorFactory.h | 68 + .../src/irrlicht/CDefaultSceneNodeFactory.cpp | 163 + .../src/irrlicht/CDefaultSceneNodeFactory.h | 80 + src/dep/src/irrlicht/CDepthBuffer.cpp | 119 + src/dep/src/irrlicht/CDepthBuffer.h | 51 + .../CDummyTransformationSceneNode.cpp | 59 + .../irrlicht/CDummyTransformationSceneNode.h | 52 + src/dep/src/irrlicht/CEmptySceneNode.cpp | 69 + src/dep/src/irrlicht/CEmptySceneNode.h | 46 + src/dep/src/irrlicht/CFPSCounter.cpp | 76 + src/dep/src/irrlicht/CFPSCounter.h | 54 + src/dep/src/irrlicht/CFileList.cpp | 183 + src/dep/src/irrlicht/CFileList.h | 78 + src/dep/src/irrlicht/CFileSystem.cpp | 359 + src/dep/src/irrlicht/CFileSystem.h | 106 + src/dep/src/irrlicht/CGUIButton.cpp | 469 ++ src/dep/src/irrlicht/CGUIButton.h | 133 + src/dep/src/irrlicht/CGUICheckBox.cpp | 198 + src/dep/src/irrlicht/CGUICheckBox.h | 55 + .../src/irrlicht/CGUIColorSelectDialog.cpp | 486 ++ src/dep/src/irrlicht/CGUIColorSelectDialog.h | 80 + src/dep/src/irrlicht/CGUIComboBox.cpp | 433 + src/dep/src/irrlicht/CGUIComboBox.h | 90 + src/dep/src/irrlicht/CGUIContextMenu.cpp | 754 ++ src/dep/src/irrlicht/CGUIContextMenu.h | 151 + src/dep/src/irrlicht/CGUIEditBox.cpp | 1360 +++ src/dep/src/irrlicht/CGUIEditBox.h | 156 + src/dep/src/irrlicht/CGUIEnvironment.cpp | 1497 ++++ src/dep/src/irrlicht/CGUIEnvironment.h | 294 + src/dep/src/irrlicht/CGUIFileOpenDialog.cpp | 329 + src/dep/src/irrlicht/CGUIFileOpenDialog.h | 72 + src/dep/src/irrlicht/CGUIFont.cpp | 648 ++ src/dep/src/irrlicht/CGUIFont.h | 113 + src/dep/src/irrlicht/CGUIImage.cpp | 158 + src/dep/src/irrlicht/CGUIImage.h | 70 + src/dep/src/irrlicht/CGUIInOutFader.cpp | 180 + src/dep/src/irrlicht/CGUIInOutFader.h | 76 + src/dep/src/irrlicht/CGUIListBox.cpp | 857 ++ src/dep/src/irrlicht/CGUIListBox.h | 176 + src/dep/src/irrlicht/CGUIMenu.cpp | 260 + src/dep/src/irrlicht/CGUIMenu.h | 51 + src/dep/src/irrlicht/CGUIMeshViewer.cpp | 171 + src/dep/src/irrlicht/CGUIMeshViewer.h | 62 + src/dep/src/irrlicht/CGUIMessageBox.cpp | 433 + src/dep/src/irrlicht/CGUIMessageBox.h | 60 + src/dep/src/irrlicht/CGUIModalScreen.cpp | 160 + src/dep/src/irrlicht/CGUIModalScreen.h | 58 + src/dep/src/irrlicht/CGUIScrollBar.cpp | 528 ++ src/dep/src/irrlicht/CGUIScrollBar.h | 100 + src/dep/src/irrlicht/CGUISkin.cpp | 858 ++ src/dep/src/irrlicht/CGUISkin.h | 246 + src/dep/src/irrlicht/CGUISpinBox.cpp | 269 + src/dep/src/irrlicht/CGUISpinBox.h | 101 + src/dep/src/irrlicht/CGUISpriteBank.cpp | 136 + src/dep/src/irrlicht/CGUISpriteBank.h | 62 + src/dep/src/irrlicht/CGUIStaticText.cpp | 457 ++ src/dep/src/irrlicht/CGUIStaticText.h | 113 + src/dep/src/irrlicht/CGUITabControl.cpp | 500 ++ src/dep/src/irrlicht/CGUITabControl.h | 132 + src/dep/src/irrlicht/CGUIToolBar.cpp | 159 + src/dep/src/irrlicht/CGUIToolBar.h | 52 + src/dep/src/irrlicht/CGUIWindow.cpp | 266 + src/dep/src/irrlicht/CGUIWindow.h | 63 + src/dep/src/irrlicht/CGeometryCreator.cpp | 639 ++ src/dep/src/irrlicht/CGeometryCreator.h | 54 + src/dep/src/irrlicht/CImage.cpp | 1436 ++++ src/dep/src/irrlicht/CImage.h | 152 + src/dep/src/irrlicht/CImageLoaderBMP.cpp | 367 + src/dep/src/irrlicht/CImageLoaderBMP.h | 110 + src/dep/src/irrlicht/CImageLoaderJPG.cpp | 260 + src/dep/src/irrlicht/CImageLoaderJPG.h | 113 + src/dep/src/irrlicht/CImageLoaderPCX.cpp | 188 + src/dep/src/irrlicht/CImageLoaderPCX.h | 92 + src/dep/src/irrlicht/CImageLoaderPNG.cpp | 272 + src/dep/src/irrlicht/CImageLoaderPNG.h | 45 + src/dep/src/irrlicht/CImageLoaderPPM.cpp | 277 + src/dep/src/irrlicht/CImageLoaderPPM.h | 55 + src/dep/src/irrlicht/CImageLoaderPSD.cpp | 375 + src/dep/src/irrlicht/CImageLoaderPSD.h | 84 + src/dep/src/irrlicht/CImageLoaderTGA.cpp | 198 + src/dep/src/irrlicht/CImageLoaderTGA.h | 91 + src/dep/src/irrlicht/CImageWriterBMP.cpp | 136 + src/dep/src/irrlicht/CImageWriterBMP.h | 37 + src/dep/src/irrlicht/CImageWriterJPG.cpp | 236 + src/dep/src/irrlicht/CImageWriterJPG.h | 37 + src/dep/src/irrlicht/CImageWriterPCX.cpp | 46 + src/dep/src/irrlicht/CImageWriterPCX.h | 37 + src/dep/src/irrlicht/CImageWriterPNG.cpp | 208 + src/dep/src/irrlicht/CImageWriterPNG.h | 37 + src/dep/src/irrlicht/CImageWriterPPM.cpp | 105 + src/dep/src/irrlicht/CImageWriterPPM.h | 37 + src/dep/src/irrlicht/CImageWriterPSD.cpp | 46 + src/dep/src/irrlicht/CImageWriterPSD.h | 37 + src/dep/src/irrlicht/CImageWriterTGA.cpp | 143 + src/dep/src/irrlicht/CImageWriterTGA.h | 37 + src/dep/src/irrlicht/CIrrDeviceLinux.cpp | 1339 +++ src/dep/src/irrlicht/CIrrDeviceLinux.h | 349 + src/dep/src/irrlicht/CIrrDeviceSDL.cpp | 533 ++ src/dep/src/irrlicht/CIrrDeviceSDL.h | 206 + src/dep/src/irrlicht/CIrrDeviceStub.cpp | 226 + src/dep/src/irrlicht/CIrrDeviceStub.h | 124 + src/dep/src/irrlicht/CIrrDeviceWin32.cpp | 957 +++ src/dep/src/irrlicht/CIrrDeviceWin32.h | 261 + src/dep/src/irrlicht/CIrrMeshFileLoader.cpp | 585 ++ src/dep/src/irrlicht/CIrrMeshFileLoader.h | 96 + src/dep/src/irrlicht/CIrrMeshWriter.cpp | 289 + src/dep/src/irrlicht/CIrrMeshWriter.h | 59 + src/dep/src/irrlicht/CLMTSMeshFileLoader.cpp | 325 + src/dep/src/irrlicht/CLMTSMeshFileLoader.h | 125 + src/dep/src/irrlicht/CLightSceneNode.cpp | 192 + src/dep/src/irrlicht/CLightSceneNode.h | 69 + src/dep/src/irrlicht/CLimitReadFile.cpp | 117 + src/dep/src/irrlicht/CLimitReadFile.h | 64 + src/dep/src/irrlicht/CLogger.cpp | 89 + src/dep/src/irrlicht/CLogger.h | 53 + src/dep/src/irrlicht/CMD2MeshFileLoader.cpp | 53 + src/dep/src/irrlicht/CMD2MeshFileLoader.h | 39 + src/dep/src/irrlicht/CMD3MeshFileLoader.cpp | 53 + src/dep/src/irrlicht/CMD3MeshFileLoader.h | 48 + src/dep/src/irrlicht/CMS3DMeshFileLoader.cpp | 610 ++ src/dep/src/irrlicht/CMS3DMeshFileLoader.h | 59 + src/dep/src/irrlicht/CMY3DHelper.h | 335 + src/dep/src/irrlicht/CMY3DMeshFileLoader.cpp | 842 ++ src/dep/src/irrlicht/CMY3DMeshFileLoader.h | 114 + src/dep/src/irrlicht/CMY3DStuff.h | 188 + src/dep/src/irrlicht/CMemoryReadFile.cpp | 111 + src/dep/src/irrlicht/CMemoryReadFile.h | 58 + src/dep/src/irrlicht/CMeshCache.cpp | 239 + src/dep/src/irrlicht/CMeshCache.h | 120 + src/dep/src/irrlicht/CMeshManipulator.cpp | 1128 +++ src/dep/src/irrlicht/CMeshManipulator.h | 107 + src/dep/src/irrlicht/CMeshSceneNode.cpp | 343 + src/dep/src/irrlicht/CMeshSceneNode.h | 92 + .../src/irrlicht/CMetaTriangleSelector.cpp | 140 + src/dep/src/irrlicht/CMetaTriangleSelector.h | 64 + src/dep/src/irrlicht/CNullDriver.cpp | 1753 ++++ src/dep/src/irrlicht/CNullDriver.h | 529 ++ src/dep/src/irrlicht/COBJMeshFileLoader.cpp | 778 ++ src/dep/src/irrlicht/COBJMeshFileLoader.h | 103 + src/dep/src/irrlicht/COCTLoader.cpp | 375 + src/dep/src/irrlicht/COCTLoader.h | 136 + src/dep/src/irrlicht/COSOperator.cpp | 183 + src/dep/src/irrlicht/COSOperator.h | 51 + src/dep/src/irrlicht/COctTreeSceneNode.cpp | 421 + src/dep/src/irrlicht/COctTreeSceneNode.h | 83 + .../src/irrlicht/COctTreeTriangleSelector.cpp | 192 + .../src/irrlicht/COctTreeTriangleSelector.h | 75 + src/dep/src/irrlicht/COgreMeshFileLoader.cpp | 1038 +++ src/dep/src/irrlicht/COgreMeshFileLoader.h | 241 + src/dep/src/irrlicht/COpenGLDriver.cpp | 2418 ++++++ src/dep/src/irrlicht/COpenGLDriver.h | 370 + .../src/irrlicht/COpenGLExtensionHandler.cpp | 430 + .../src/irrlicht/COpenGLExtensionHandler.h | 1330 +++ .../src/irrlicht/COpenGLMaterialRenderer.h | 672 ++ .../src/irrlicht/COpenGLNormalMapRenderer.cpp | 296 + .../src/irrlicht/COpenGLNormalMapRenderer.h | 49 + .../irrlicht/COpenGLParallaxMapRenderer.cpp | 361 + .../src/irrlicht/COpenGLParallaxMapRenderer.h | 54 + .../irrlicht/COpenGLSLMaterialRenderer.cpp | 363 + .../src/irrlicht/COpenGLSLMaterialRenderer.h | 124 + .../COpenGLShaderMaterialRenderer.cpp | 237 + .../irrlicht/COpenGLShaderMaterialRenderer.h | 92 + src/dep/src/irrlicht/COpenGLTexture.cpp | 556 ++ src/dep/src/irrlicht/COpenGLTexture.h | 144 + src/dep/src/irrlicht/CPakReader.cpp | 226 + src/dep/src/irrlicht/CPakReader.h | 93 + .../CParticleAnimatedMeshSceneNodeEmitter.cpp | 203 + .../CParticleAnimatedMeshSceneNodeEmitter.h | 127 + .../irrlicht/CParticleAttractionAffector.cpp | 59 + .../irrlicht/CParticleAttractionAffector.h | 81 + src/dep/src/irrlicht/CParticleBoxEmitter.cpp | 160 + src/dep/src/irrlicht/CParticleBoxEmitter.h | 99 + .../src/irrlicht/CParticleCylinderEmitter.cpp | 108 + .../src/irrlicht/CParticleCylinderEmitter.h | 123 + .../src/irrlicht/CParticleFadeOutAffector.cpp | 79 + .../src/irrlicht/CParticleFadeOutAffector.h | 63 + .../src/irrlicht/CParticleGravityAffector.cpp | 75 + .../src/irrlicht/CParticleGravityAffector.h | 65 + src/dep/src/irrlicht/CParticleMeshEmitter.cpp | 196 + src/dep/src/irrlicht/CParticleMeshEmitter.h | 126 + .../src/irrlicht/CParticlePointEmitter.cpp | 119 + src/dep/src/irrlicht/CParticlePointEmitter.h | 90 + src/dep/src/irrlicht/CParticleRingEmitter.cpp | 99 + src/dep/src/irrlicht/CParticleRingEmitter.h | 111 + .../irrlicht/CParticleRotationAffector.cpp | 50 + .../src/irrlicht/CParticleRotationAffector.h | 50 + .../src/irrlicht/CParticleSphereEmitter.cpp | 100 + src/dep/src/irrlicht/CParticleSphereEmitter.h | 102 + .../src/irrlicht/CParticleSystemSceneNode.cpp | 638 ++ .../src/irrlicht/CParticleSystemSceneNode.h | 209 + src/dep/src/irrlicht/CQ3LevelMesh.cpp | 1844 +++++ src/dep/src/irrlicht/CQ3LevelMesh.h | 443 + .../src/irrlicht/CQuake3ShaderSceneNode.cpp | 704 ++ src/dep/src/irrlicht/CQuake3ShaderSceneNode.h | 87 + src/dep/src/irrlicht/CReadFile.cpp | 117 + src/dep/src/irrlicht/CReadFile.h | 67 + src/dep/src/irrlicht/CSTLMeshFileLoader.cpp | 266 + src/dep/src/irrlicht/CSTLMeshFileLoader.h | 52 + src/dep/src/irrlicht/CSTLMeshWriter.cpp | 246 + src/dep/src/irrlicht/CSTLMeshWriter.h | 55 + .../src/irrlicht/CSceneCollisionManager.cpp | 737 ++ src/dep/src/irrlicht/CSceneCollisionManager.h | 126 + src/dep/src/irrlicht/CSceneManager.cpp | 2239 +++++ src/dep/src/irrlicht/CSceneManager.h | 615 ++ .../CSceneNodeAnimatorCollisionResponse.cpp | 211 + .../CSceneNodeAnimatorCollisionResponse.h | 104 + .../src/irrlicht/CSceneNodeAnimatorDelete.cpp | 46 + .../src/irrlicht/CSceneNodeAnimatorDelete.h | 44 + .../irrlicht/CSceneNodeAnimatorFlyCircle.cpp | 74 + .../irrlicht/CSceneNodeAnimatorFlyCircle.h | 51 + .../CSceneNodeAnimatorFlyStraight.cpp | 87 + .../irrlicht/CSceneNodeAnimatorFlyStraight.h | 58 + .../CSceneNodeAnimatorFollowSpline.cpp | 120 + .../irrlicht/CSceneNodeAnimatorFollowSpline.h | 54 + .../irrlicht/CSceneNodeAnimatorRotation.cpp | 62 + .../src/irrlicht/CSceneNodeAnimatorRotation.h | 47 + .../irrlicht/CSceneNodeAnimatorTexture.cpp | 125 + .../src/irrlicht/CSceneNodeAnimatorTexture.h | 54 + .../src/irrlicht/CShadowVolumeSceneNode.cpp | 473 ++ src/dep/src/irrlicht/CShadowVolumeSceneNode.h | 85 + src/dep/src/irrlicht/CSkinnedMesh.cpp | 1372 ++++ src/dep/src/irrlicht/CSkinnedMesh.h | 199 + src/dep/src/irrlicht/CSkyBoxSceneNode.cpp | 255 + src/dep/src/irrlicht/CSkyBoxSceneNode.h | 62 + src/dep/src/irrlicht/CSkyDomeSceneNode.cpp | 172 + src/dep/src/irrlicht/CSkyDomeSceneNode.h | 40 + .../src/irrlicht/CSoftware2MaterialRenderer.h | 83 + src/dep/src/irrlicht/CSoftwareDriver.cpp | 918 +++ src/dep/src/irrlicht/CSoftwareDriver.h | 167 + src/dep/src/irrlicht/CSoftwareDriver2.cpp | 1919 +++++ src/dep/src/irrlicht/CSoftwareDriver2.h | 259 + src/dep/src/irrlicht/CSoftwareTexture.cpp | 164 + src/dep/src/irrlicht/CSoftwareTexture.h | 79 + src/dep/src/irrlicht/CSoftwareTexture2.cpp | 123 + src/dep/src/irrlicht/CSoftwareTexture2.h | 134 + src/dep/src/irrlicht/CSphereSceneNode.cpp | 157 + src/dep/src/irrlicht/CSphereSceneNode.h | 71 + src/dep/src/irrlicht/CTRFlat.cpp | 301 + src/dep/src/irrlicht/CTRFlatWire.cpp | 282 + src/dep/src/irrlicht/CTRGouraud.cpp | 359 + src/dep/src/irrlicht/CTRGouraud2.cpp | 672 ++ src/dep/src/irrlicht/CTRGouraudAlpha2.cpp | 683 ++ src/dep/src/irrlicht/CTRGouraudAlphaNoZ2.cpp | 684 ++ src/dep/src/irrlicht/CTRGouraudWire.cpp | 327 + src/dep/src/irrlicht/CTRTextureBlend.cpp | 712 ++ src/dep/src/irrlicht/CTRTextureDetailMap2.cpp | 690 ++ src/dep/src/irrlicht/CTRTextureFlat.cpp | 340 + src/dep/src/irrlicht/CTRTextureFlatWire.cpp | 314 + src/dep/src/irrlicht/CTRTextureGouraud.cpp | 469 ++ src/dep/src/irrlicht/CTRTextureGouraud.h | 67 + src/dep/src/irrlicht/CTRTextureGouraud2.cpp | 703 ++ src/dep/src/irrlicht/CTRTextureGouraudAdd.cpp | 421 + .../src/irrlicht/CTRTextureGouraudAdd2.cpp | 711 ++ .../src/irrlicht/CTRTextureGouraudAddNoZ2.cpp | 672 ++ .../src/irrlicht/CTRTextureGouraudAlpha.cpp | 734 ++ .../irrlicht/CTRTextureGouraudAlphaNoZ.cpp | 732 ++ src/dep/src/irrlicht/CTRTextureGouraudNoZ.cpp | 366 + .../src/irrlicht/CTRTextureGouraudNoZ2.cpp | 677 ++ .../CTRTextureGouraudVertexAlpha2.cpp | 720 ++ .../src/irrlicht/CTRTextureGouraudWire.cpp | 361 + .../src/irrlicht/CTRTextureLightMap2_Add.cpp | 705 ++ .../src/irrlicht/CTRTextureLightMap2_M1.cpp | 678 ++ .../src/irrlicht/CTRTextureLightMap2_M2.cpp | 674 ++ .../src/irrlicht/CTRTextureLightMap2_M4.cpp | 1404 ++++ .../CTRTextureLightMapGouraud2_M4.cpp | 718 ++ src/dep/src/irrlicht/CTRTextureWire2.cpp | 322 + src/dep/src/irrlicht/CTerrainSceneNode.cpp | 1384 ++++ src/dep/src/irrlicht/CTerrainSceneNode.h | 338 + .../src/irrlicht/CTerrainTriangleSelector.cpp | 190 + .../src/irrlicht/CTerrainTriangleSelector.h | 89 + src/dep/src/irrlicht/CTextSceneNode.cpp | 418 + src/dep/src/irrlicht/CTextSceneNode.h | 129 + src/dep/src/irrlicht/CTimer.h | 102 + src/dep/src/irrlicht/CTriangleBBSelector.cpp | 64 + src/dep/src/irrlicht/CTriangleBBSelector.h | 33 + src/dep/src/irrlicht/CTriangleSelector.cpp | 158 + src/dep/src/irrlicht/CTriangleSelector.h | 60 + src/dep/src/irrlicht/CVideoModeList.cpp | 98 + src/dep/src/irrlicht/CVideoModeList.h | 79 + .../src/irrlicht/CWaterSurfaceSceneNode.cpp | 171 + src/dep/src/irrlicht/CWaterSurfaceSceneNode.h | 63 + src/dep/src/irrlicht/CWriteFile.cpp | 119 + src/dep/src/irrlicht/CWriteFile.h | 59 + src/dep/src/irrlicht/CXMLReader.cpp | 70 + src/dep/src/irrlicht/CXMLReader.h | 26 + src/dep/src/irrlicht/CXMLReaderImpl.h | 797 ++ src/dep/src/irrlicht/CXMLWriter.cpp | 249 + src/dep/src/irrlicht/CXMLWriter.h | 76 + src/dep/src/irrlicht/CXMeshFileLoader.cpp | 2132 +++++ src/dep/src/irrlicht/CXMeshFileLoader.h | 199 + src/dep/src/irrlicht/CZBuffer.cpp | 109 + src/dep/src/irrlicht/CZBuffer.h | 52 + src/dep/src/irrlicht/CZipReader.cpp | 484 ++ src/dep/src/irrlicht/CZipReader.h | 157 + src/dep/src/irrlicht/IBurningShader.cpp | 105 + src/dep/src/irrlicht/IBurningShader.h | 129 + src/dep/src/irrlicht/IDepthBuffer.h | 47 + src/dep/src/irrlicht/IImagePresenter.h | 36 + src/dep/src/irrlicht/ITriangleRenderer.h | 71 + src/dep/src/irrlicht/IZBuffer.h | 47 + src/dep/src/irrlicht/Irrlicht.cpp | 71 + src/dep/src/irrlicht/Irrlicht.dev | 5969 ++++++++++++++ src/dep/src/irrlicht/Irrlicht.dsp | 2365 ++++++ src/dep/src/irrlicht/Irrlicht.dsw | 29 + src/dep/src/irrlicht/Irrlicht.opt | Bin 0 -> 53760 bytes src/dep/src/irrlicht/Irrlicht7.1.sln | 24 + src/dep/src/irrlicht/Irrlicht7.1.vcproj | 2071 +++++ src/dep/src/irrlicht/Irrlicht8.0.sln | 20 + src/dep/src/irrlicht/Irrlicht8.0.vcproj | 2815 +++++++ src/dep/src/irrlicht/Irrlicht_Win32-gcc.cbp | 854 ++ src/dep/src/irrlicht/MacOSX/._MainMenu.nib | Bin 0 -> 82 bytes src/dep/src/irrlicht/MacOSX/AppDelegate.h | 16 + src/dep/src/irrlicht/MacOSX/AppDelegate.mm | 61 + .../src/irrlicht/MacOSX/CIrrDeviceMacOSX.h | 214 + .../src/irrlicht/MacOSX/CIrrDeviceMacOSX.mm | 629 ++ .../src/irrlicht/MacOSX/DemoApp-Info.plist | 24 + .../MacOSX/MacOSX.xcodeproj/epetitje.mode1 | 1366 ++++ .../MacOSX/MacOSX.xcodeproj/epetitje.pbxuser | 1222 +++ .../MacOSX/MacOSX.xcodeproj/project.pbxproj | 4105 ++++++++++ .../MacOSX/MacOSX.xcodeproj/susanne.mode1 | 1316 +++ .../MacOSX/MacOSX.xcodeproj/susanne.pbxuser | 682 ++ src/dep/src/irrlicht/MacOSX/MacOSX_Prefix.pch | 5 + .../irrlicht/MacOSX/MainMenu.nib/classes.nib | 4 + .../src/irrlicht/MacOSX/MainMenu.nib/info.nib | 17 + .../MacOSX/MainMenu.nib/keyedobjects.nib | Bin 0 -> 13030 bytes src/dep/src/irrlicht/MacOSX/OSXClipboard.h | 14 + src/dep/src/irrlicht/MacOSX/OSXClipboard.mm | 33 + src/dep/src/irrlicht/Makefile | 134 + src/dep/src/irrlicht/OctTree.h | 381 + src/dep/src/irrlicht/S2DVertex.h | 30 + src/dep/src/irrlicht/S4DVertex.h | 501 ++ .../irrlicht/SoftwareDriver2_compile_config.h | 84 + src/dep/src/irrlicht/SoftwareDriver2_helper.h | 886 ++ src/dep/src/irrlicht/builtInFont.bmp | Bin 0 -> 8266 bytes src/dep/src/irrlicht/dmfsupport.h | 781 ++ src/dep/src/irrlicht/glext.h | 7260 +++++++++++++++++ src/dep/src/irrlicht/glxext.h | 785 ++ src/dep/src/irrlicht/irrXML.cpp | 147 + src/dep/src/irrlicht/jpeglib/README | 385 + src/dep/src/irrlicht/jpeglib/Tcdjpeg.c | 182 + src/dep/src/irrlicht/jpeglib/ansi2knr | Bin 0 -> 15546 bytes src/dep/src/irrlicht/jpeglib/ansi2knr.1 | 36 + src/dep/src/irrlicht/jpeglib/ansi2knr.c | 693 ++ src/dep/src/irrlicht/jpeglib/cderror.h | 132 + src/dep/src/irrlicht/jpeglib/cdjpeg.c | 181 + src/dep/src/irrlicht/jpeglib/cdjpeg.h | 184 + src/dep/src/irrlicht/jpeglib/change.log | 217 + src/dep/src/irrlicht/jpeglib/cjpeg.1 | 292 + src/dep/src/irrlicht/jpeglib/cjpeg.c | 606 ++ src/dep/src/irrlicht/jpeglib/ckconfig.c | 402 + src/dep/src/irrlicht/jpeglib/coderules.doc | 118 + src/dep/src/irrlicht/jpeglib/config.guess | 883 ++ src/dep/src/irrlicht/jpeglib/config.sub | 954 +++ src/dep/src/irrlicht/jpeglib/configure | 2011 +++++ src/dep/src/irrlicht/jpeglib/djpeg.1 | 253 + src/dep/src/irrlicht/jpeglib/djpeg.c | 616 ++ src/dep/src/irrlicht/jpeglib/example.c | 433 + src/dep/src/irrlicht/jpeglib/filelist.doc | 210 + src/dep/src/irrlicht/jpeglib/install-sh | 250 + src/dep/src/irrlicht/jpeglib/install.doc | 1063 +++ src/dep/src/irrlicht/jpeglib/jcapimin.c | 280 + src/dep/src/irrlicht/jpeglib/jcapistd.c | 161 + src/dep/src/irrlicht/jpeglib/jccoefct.c | 449 + src/dep/src/irrlicht/jpeglib/jccolor.c | 459 ++ src/dep/src/irrlicht/jpeglib/jcdctmgr.c | 387 + src/dep/src/irrlicht/jpeglib/jchuff.c | 909 +++ src/dep/src/irrlicht/jpeglib/jchuff.h | 47 + src/dep/src/irrlicht/jpeglib/jcinit.c | 72 + src/dep/src/irrlicht/jpeglib/jcmainct.c | 293 + src/dep/src/irrlicht/jpeglib/jcmarker.c | 664 ++ src/dep/src/irrlicht/jpeglib/jcmaster.c | 590 ++ src/dep/src/irrlicht/jpeglib/jcomapi.c | 106 + src/dep/src/irrlicht/jpeglib/jconfig.bcc | 48 + src/dep/src/irrlicht/jpeglib/jconfig.cfg | 44 + src/dep/src/irrlicht/jpeglib/jconfig.dj | 38 + src/dep/src/irrlicht/jpeglib/jconfig.doc | 155 + src/dep/src/irrlicht/jpeglib/jconfig.h | 45 + src/dep/src/irrlicht/jpeglib/jconfig.mac | 43 + src/dep/src/irrlicht/jpeglib/jconfig.manx | 43 + src/dep/src/irrlicht/jpeglib/jconfig.mc6 | 52 + src/dep/src/irrlicht/jpeglib/jconfig.sas | 43 + src/dep/src/irrlicht/jpeglib/jconfig.st | 42 + src/dep/src/irrlicht/jpeglib/jconfig.vc | 45 + src/dep/src/irrlicht/jpeglib/jconfig.vms | 37 + src/dep/src/irrlicht/jpeglib/jconfig.wat | 38 + src/dep/src/irrlicht/jpeglib/jcparam.c | 610 ++ src/dep/src/irrlicht/jpeglib/jcphuff.c | 833 ++ src/dep/src/irrlicht/jpeglib/jcprepct.c | 354 + src/dep/src/irrlicht/jpeglib/jcsample.c | 519 ++ src/dep/src/irrlicht/jpeglib/jctrans.c | 388 + src/dep/src/irrlicht/jpeglib/jdapimin.c | 395 + src/dep/src/irrlicht/jpeglib/jdapistd.c | 275 + src/dep/src/irrlicht/jpeglib/jdatadst.c | 151 + src/dep/src/irrlicht/jpeglib/jdatasrc.c | 212 + src/dep/src/irrlicht/jpeglib/jdcoefct.c | 736 ++ src/dep/src/irrlicht/jpeglib/jdcolor.c | 396 + src/dep/src/irrlicht/jpeglib/jdct.h | 176 + src/dep/src/irrlicht/jpeglib/jddctmgr.c | 269 + src/dep/src/irrlicht/jpeglib/jdhuff.c | 651 ++ src/dep/src/irrlicht/jpeglib/jdhuff.h | 201 + src/dep/src/irrlicht/jpeglib/jdinput.c | 381 + src/dep/src/irrlicht/jpeglib/jdmainct.c | 512 ++ src/dep/src/irrlicht/jpeglib/jdmarker.c | 1360 +++ src/dep/src/irrlicht/jpeglib/jdmaster.c | 557 ++ src/dep/src/irrlicht/jpeglib/jdmerge.c | 400 + src/dep/src/irrlicht/jpeglib/jdphuff.c | 668 ++ src/dep/src/irrlicht/jpeglib/jdpostct.c | 290 + src/dep/src/irrlicht/jpeglib/jdsample.c | 478 ++ src/dep/src/irrlicht/jpeglib/jdtrans.c | 143 + src/dep/src/irrlicht/jpeglib/jerror.c | 252 + src/dep/src/irrlicht/jpeglib/jerror.h | 291 + src/dep/src/irrlicht/jpeglib/jfdctflt.c | 168 + src/dep/src/irrlicht/jpeglib/jfdctfst.c | 224 + src/dep/src/irrlicht/jpeglib/jfdctint.c | 283 + src/dep/src/irrlicht/jpeglib/jidctflt.c | 242 + src/dep/src/irrlicht/jpeglib/jidctfst.c | 368 + src/dep/src/irrlicht/jpeglib/jidctint.c | 389 + src/dep/src/irrlicht/jpeglib/jidctred.c | 398 + src/dep/src/irrlicht/jpeglib/jinclude.h | 91 + src/dep/src/irrlicht/jpeglib/jmemansi.c | 167 + src/dep/src/irrlicht/jpeglib/jmemdos.c | 638 ++ src/dep/src/irrlicht/jpeglib/jmemdosa.asm | 379 + src/dep/src/irrlicht/jpeglib/jmemmac.c | 289 + src/dep/src/irrlicht/jpeglib/jmemmgr.c | 1118 +++ src/dep/src/irrlicht/jpeglib/jmemname.c | 276 + src/dep/src/irrlicht/jpeglib/jmemnobs.c | 109 + src/dep/src/irrlicht/jpeglib/jmemsys.h | 198 + src/dep/src/irrlicht/jpeglib/jmorecfg.h | 363 + src/dep/src/irrlicht/jpeglib/jpegint.h | 392 + src/dep/src/irrlicht/jpeglib/jpeglib.h | 1096 +++ src/dep/src/irrlicht/jpeglib/jpegtran.1 | 238 + src/dep/src/irrlicht/jpeglib/jpegtran.c | 504 ++ src/dep/src/irrlicht/jpeglib/jquant1.c | 856 ++ src/dep/src/irrlicht/jpeglib/jquant2.c | 1310 +++ src/dep/src/irrlicht/jpeglib/jutils.c | 179 + src/dep/src/irrlicht/jpeglib/jversion.h | 14 + src/dep/src/irrlicht/jpeglib/libjpeg.doc | 3006 +++++++ src/dep/src/irrlicht/jpeglib/ltconfig | 1512 ++++ src/dep/src/irrlicht/jpeglib/ltmain.sh | 2453 ++++++ src/dep/src/irrlicht/jpeglib/makcjpeg.st | 38 + src/dep/src/irrlicht/jpeglib/makdjpeg.st | 38 + src/dep/src/irrlicht/jpeglib/makeapps.ds | 828 ++ src/dep/src/irrlicht/jpeglib/makefile.ansi | 214 + src/dep/src/irrlicht/jpeglib/makefile.bcc | 285 + src/dep/src/irrlicht/jpeglib/makefile.cfg | 319 + src/dep/src/irrlicht/jpeglib/makefile.dj | 220 + src/dep/src/irrlicht/jpeglib/makefile.manx | 214 + src/dep/src/irrlicht/jpeglib/makefile.mc6 | 249 + src/dep/src/irrlicht/jpeglib/makefile.mms | 218 + src/dep/src/irrlicht/jpeglib/makefile.sas | 252 + src/dep/src/irrlicht/jpeglib/makefile.unix | 228 + src/dep/src/irrlicht/jpeglib/makefile.vc | 211 + src/dep/src/irrlicht/jpeglib/makefile.vms | 142 + src/dep/src/irrlicht/jpeglib/makefile.wat | 233 + src/dep/src/irrlicht/jpeglib/makelib.ds | 1046 +++ src/dep/src/irrlicht/jpeglib/makeproj.mac | 213 + src/dep/src/irrlicht/jpeglib/makljpeg.st | 70 + src/dep/src/irrlicht/jpeglib/maktjpeg.st | 32 + src/dep/src/irrlicht/jpeglib/makvms.opt | 4 + src/dep/src/irrlicht/jpeglib/rdbmp.c | 439 + src/dep/src/irrlicht/jpeglib/rdcolmap.c | 253 + src/dep/src/irrlicht/jpeglib/rdgif.c | 38 + src/dep/src/irrlicht/jpeglib/rdjpgcom.1 | 54 + src/dep/src/irrlicht/jpeglib/rdjpgcom.c | 496 ++ src/dep/src/irrlicht/jpeglib/rdppm.c | 458 ++ src/dep/src/irrlicht/jpeglib/rdrle.c | 387 + src/dep/src/irrlicht/jpeglib/rdswitch.c | 332 + src/dep/src/irrlicht/jpeglib/rdtarga.c | 500 ++ src/dep/src/irrlicht/jpeglib/structure.doc | 948 +++ src/dep/src/irrlicht/jpeglib/testimg.bmp | Bin 0 -> 35050 bytes src/dep/src/irrlicht/jpeglib/testimg.jpg | Bin 0 -> 5756 bytes src/dep/src/irrlicht/jpeglib/testimg.ppm | 4 + src/dep/src/irrlicht/jpeglib/testimgp.jpg | Bin 0 -> 5645 bytes src/dep/src/irrlicht/jpeglib/testorig.jpg | Bin 0 -> 5770 bytes src/dep/src/irrlicht/jpeglib/testprog.jpg | Bin 0 -> 5655 bytes src/dep/src/irrlicht/jpeglib/transupp.c | 928 +++ src/dep/src/irrlicht/jpeglib/transupp.h | 135 + src/dep/src/irrlicht/jpeglib/usage.doc | 562 ++ src/dep/src/irrlicht/jpeglib/wizard.doc | 211 + src/dep/src/irrlicht/jpeglib/wrbmp.c | 442 + src/dep/src/irrlicht/jpeglib/wrgif.c | 399 + src/dep/src/irrlicht/jpeglib/wrjpgcom.1 | 103 + src/dep/src/irrlicht/jpeglib/wrjpgcom.c | 583 ++ src/dep/src/irrlicht/jpeglib/wrppm.c | 268 + src/dep/src/irrlicht/jpeglib/wrrle.c | 305 + src/dep/src/irrlicht/jpeglib/wrtarga.c | 253 + src/dep/src/irrlicht/libpng/ANNOUNCE | 49 + src/dep/src/irrlicht/libpng/CHANGES | 1738 ++++ src/dep/src/irrlicht/libpng/INSTALL | 206 + src/dep/src/irrlicht/libpng/KNOWNBUG | 28 + src/dep/src/irrlicht/libpng/LICENSE | 109 + src/dep/src/irrlicht/libpng/README | 263 + src/dep/src/irrlicht/libpng/TODO | 24 + src/dep/src/irrlicht/libpng/Y2KINFO | 55 + src/dep/src/irrlicht/libpng/configure | 13 + .../irrlicht/libpng/contrib/gregbook/LICENSE | 26 + .../libpng/contrib/gregbook/Makefile.sgi | 104 + .../libpng/contrib/gregbook/Makefile.unx | 104 + .../libpng/contrib/gregbook/Makefile.w32 | 112 + .../irrlicht/libpng/contrib/gregbook/README | 185 + .../libpng/contrib/gregbook/makevms.com | 132 + .../libpng/contrib/gregbook/readpng.c | 280 + .../libpng/contrib/gregbook/readpng.h | 64 + .../libpng/contrib/gregbook/readpng2.c | 624 ++ .../libpng/contrib/gregbook/readpng2.h | 91 + .../libpng/contrib/gregbook/rpng-win.c | 642 ++ .../irrlicht/libpng/contrib/gregbook/rpng-x.c | 858 ++ .../libpng/contrib/gregbook/rpng2-win.c | 1166 +++ .../libpng/contrib/gregbook/rpng2-x.c | 1408 ++++ .../libpng/contrib/gregbook/toucan.png | Bin 0 -> 12901 bytes .../irrlicht/libpng/contrib/gregbook/wpng.c | 816 ++ .../libpng/contrib/gregbook/writepng.c | 368 + .../libpng/contrib/gregbook/writepng.h | 109 + .../irrlicht/libpng/contrib/pngminus/README | 153 + .../libpng/contrib/pngminus/makefile.std | 65 + .../libpng/contrib/pngminus/makefile.tc3 | 38 + .../libpng/contrib/pngminus/makevms.com | 92 + .../libpng/contrib/pngminus/png2pnm.bat | 41 + .../libpng/contrib/pngminus/png2pnm.c | 430 + .../libpng/contrib/pngminus/png2pnm.sh | 42 + .../libpng/contrib/pngminus/pngminus.bat | 4 + .../libpng/contrib/pngminus/pngminus.sh | 5 + .../libpng/contrib/pngminus/pnm2png.bat | 41 + .../libpng/contrib/pngminus/pnm2png.c | 533 ++ .../libpng/contrib/pngminus/pnm2png.sh | 42 + .../libpng/contrib/pngsuite/basn0g01.png | Bin 0 -> 164 bytes .../libpng/contrib/pngsuite/basn0g02.png | Bin 0 -> 104 bytes .../libpng/contrib/pngsuite/basn0g04.png | Bin 0 -> 145 bytes .../libpng/contrib/pngsuite/basn0g08.png | Bin 0 -> 138 bytes .../libpng/contrib/pngsuite/basn0g16.png | Bin 0 -> 167 bytes .../libpng/contrib/pngsuite/basn2c08.png | Bin 0 -> 145 bytes .../libpng/contrib/pngsuite/basn2c16.png | Bin 0 -> 302 bytes .../libpng/contrib/pngsuite/basn3p01.png | Bin 0 -> 112 bytes .../libpng/contrib/pngsuite/basn3p02.png | Bin 0 -> 146 bytes .../libpng/contrib/pngsuite/basn3p04.png | Bin 0 -> 216 bytes .../libpng/contrib/pngsuite/basn3p08.png | Bin 0 -> 1286 bytes .../libpng/contrib/pngsuite/basn4a08.png | Bin 0 -> 126 bytes .../libpng/contrib/pngsuite/basn4a16.png | Bin 0 -> 2206 bytes .../libpng/contrib/pngsuite/basn6a08.png | Bin 0 -> 184 bytes .../libpng/contrib/pngsuite/basn6a16.png | Bin 0 -> 3435 bytes .../irrlicht/libpng/contrib/visupng/PngFile.c | 439 + .../irrlicht/libpng/contrib/visupng/PngFile.h | 27 + .../libpng/contrib/visupng/README.txt | 58 + .../libpng/contrib/visupng/VisualPng.c | 961 +++ .../libpng/contrib/visupng/VisualPng.dsp | 147 + .../libpng/contrib/visupng/VisualPng.dsw | 29 + .../libpng/contrib/visupng/VisualPng.ico | Bin 0 -> 766 bytes .../libpng/contrib/visupng/VisualPng.png | Bin 0 -> 208 bytes .../libpng/contrib/visupng/VisualPng.rc | 152 + .../irrlicht/libpng/contrib/visupng/cexcept.h | 243 + .../libpng/contrib/visupng/resource.h | 23 + src/dep/src/irrlicht/libpng/example.c | 814 ++ src/dep/src/irrlicht/libpng/libpng-1.2.18.txt | 2976 +++++++ src/dep/src/irrlicht/libpng/libpng.3 | 3707 +++++++++ src/dep/src/irrlicht/libpng/libpngpf.3 | 274 + src/dep/src/irrlicht/libpng/png.5 | 74 + src/dep/src/irrlicht/libpng/png.c | 861 ++ src/dep/src/irrlicht/libpng/png.h | 3523 ++++++++ src/dep/src/irrlicht/libpng/pngbar.jpg | Bin 0 -> 2498 bytes src/dep/src/irrlicht/libpng/pngbar.png | Bin 0 -> 2399 bytes src/dep/src/irrlicht/libpng/pngconf.h | 1483 ++++ src/dep/src/irrlicht/libpng/pngerror.c | 320 + src/dep/src/irrlicht/libpng/pnggccrd.c | 5420 ++++++++++++ src/dep/src/irrlicht/libpng/pngget.c | 955 +++ src/dep/src/irrlicht/libpng/pngmem.c | 608 ++ src/dep/src/irrlicht/libpng/pngnow.png | Bin 0 -> 2069 bytes src/dep/src/irrlicht/libpng/pngpread.c | 1589 ++++ src/dep/src/irrlicht/libpng/pngread.c | 1473 ++++ src/dep/src/irrlicht/libpng/pngrio.c | 167 + src/dep/src/irrlicht/libpng/pngrtran.c | 4247 ++++++++++ src/dep/src/irrlicht/libpng/pngrutil.c | 3132 +++++++ src/dep/src/irrlicht/libpng/pngset.c | 1271 +++ src/dep/src/irrlicht/libpng/pngtest.c | 1554 ++++ src/dep/src/irrlicht/libpng/pngtest.png | Bin 0 -> 8574 bytes src/dep/src/irrlicht/libpng/pngtrans.c | 662 ++ src/dep/src/irrlicht/libpng/pngvcrd.c | 3904 +++++++++ src/dep/src/irrlicht/libpng/pngwio.c | 234 + src/dep/src/irrlicht/libpng/pngwrite.c | 1518 ++++ src/dep/src/irrlicht/libpng/pngwtran.c | 572 ++ src/dep/src/irrlicht/libpng/pngwutil.c | 2778 +++++++ .../libpng/projects/beos/x86-shared.proj | Bin 0 -> 17031 bytes .../libpng/projects/beos/x86-shared.txt | 22 + .../libpng/projects/beos/x86-static.proj | Bin 0 -> 16706 bytes .../libpng/projects/beos/x86-static.txt | 22 + .../libpng/projects/cbuilder5/libpng.bpf | 22 + .../libpng/projects/cbuilder5/libpng.bpg | 25 + .../libpng/projects/cbuilder5/libpng.bpr | 157 + .../libpng/projects/cbuilder5/libpng.cpp | 29 + .../projects/cbuilder5/libpng.readme.txt | 25 + .../libpng/projects/cbuilder5/libpngstat.bpf | 22 + .../libpng/projects/cbuilder5/libpngstat.bpr | 109 + .../libpng/projects/cbuilder5/zlib.readme.txt | 14 + .../src/irrlicht/libpng/projects/netware.txt | 6 + .../libpng/projects/visualc6/README.txt | 57 + .../libpng/projects/visualc6/libpng.dsp | 507 ++ .../libpng/projects/visualc6/libpng.dsw | 59 + .../libpng/projects/visualc6/pngtest.dsp | 314 + .../libpng/projects/visualc71/PRJ0041.mak | 21 + .../libpng/projects/visualc71/README.txt | 57 + .../libpng/projects/visualc71/README_zlib.txt | 44 + .../libpng/projects/visualc71/libpng.sln | 88 + .../libpng/projects/visualc71/libpng.vcproj | 735 ++ .../libpng/projects/visualc71/pngtest.vcproj | 459 ++ .../libpng/projects/visualc71/zlib.vcproj | 670 ++ .../src/irrlicht/libpng/projects/wince.txt | 6 + .../irrlicht/libpng/scripts/CMakeLists.txt | 213 + .../src/irrlicht/libpng/scripts/SCOPTIONS.ppc | 7 + .../src/irrlicht/libpng/scripts/descrip.mms | 52 + .../libpng/scripts/libpng-config-body.in | 96 + .../libpng/scripts/libpng-config-head.in | 21 + .../irrlicht/libpng/scripts/libpng-config.in | 124 + .../src/irrlicht/libpng/scripts/libpng.icc | 44 + .../libpng/scripts/libpng.pc-configure.in | 10 + .../src/irrlicht/libpng/scripts/libpng.pc.in | 10 + .../irrlicht/libpng/scripts/makefile.32sunu | 250 + .../irrlicht/libpng/scripts/makefile.64sunu | 250 + .../irrlicht/libpng/scripts/makefile.acorn | 51 + .../src/irrlicht/libpng/scripts/makefile.aix | 113 + .../irrlicht/libpng/scripts/makefile.amiga | 48 + .../irrlicht/libpng/scripts/makefile.atari | 51 + .../src/irrlicht/libpng/scripts/makefile.bc32 | 152 + .../src/irrlicht/libpng/scripts/makefile.beos | 222 + .../src/irrlicht/libpng/scripts/makefile.bor | 162 + .../irrlicht/libpng/scripts/makefile.cygwin | 316 + .../irrlicht/libpng/scripts/makefile.darwin | 230 + .../src/irrlicht/libpng/scripts/makefile.dec | 210 + .../src/irrlicht/libpng/scripts/makefile.dj2 | 55 + .../src/irrlicht/libpng/scripts/makefile.elf | 271 + .../irrlicht/libpng/scripts/makefile.freebsd | 48 + .../src/irrlicht/libpng/scripts/makefile.gcc | 79 + .../irrlicht/libpng/scripts/makefile.gcmmx | 275 + .../src/irrlicht/libpng/scripts/makefile.hp64 | 231 + .../irrlicht/libpng/scripts/makefile.hpgcc | 241 + .../src/irrlicht/libpng/scripts/makefile.hpux | 228 + .../src/irrlicht/libpng/scripts/makefile.ibmc | 71 + .../irrlicht/libpng/scripts/makefile.intel | 114 + .../src/irrlicht/libpng/scripts/makefile.knr | 99 + .../irrlicht/libpng/scripts/makefile.linux | 245 + .../irrlicht/libpng/scripts/makefile.mingw | 312 + .../src/irrlicht/libpng/scripts/makefile.mips | 83 + .../src/irrlicht/libpng/scripts/makefile.msc | 86 + .../irrlicht/libpng/scripts/makefile.ne12bsd | 45 + .../irrlicht/libpng/scripts/makefile.netbsd | 45 + .../irrlicht/libpng/scripts/makefile.nommx | 248 + .../irrlicht/libpng/scripts/makefile.openbsd | 73 + .../src/irrlicht/libpng/scripts/makefile.os2 | 69 + .../src/irrlicht/libpng/scripts/makefile.sco | 225 + .../irrlicht/libpng/scripts/makefile.sggcc | 238 + .../src/irrlicht/libpng/scripts/makefile.sgi | 243 + .../src/irrlicht/libpng/scripts/makefile.so9 | 247 + .../irrlicht/libpng/scripts/makefile.solaris | 244 + .../src/irrlicht/libpng/scripts/makefile.std | 92 + .../irrlicht/libpng/scripts/makefile.sunos | 97 + .../src/irrlicht/libpng/scripts/makefile.tc3 | 89 + .../irrlicht/libpng/scripts/makefile.vcawin32 | 103 + .../irrlicht/libpng/scripts/makefile.vcwin32 | 99 + .../irrlicht/libpng/scripts/makefile.watcom | 109 + .../src/irrlicht/libpng/scripts/makevms.com | 144 + .../src/irrlicht/libpng/scripts/pngos2.def | 258 + .../src/irrlicht/libpng/scripts/pngw32.def | 236 + src/dep/src/irrlicht/libpng/scripts/pngw32.rc | 112 + .../src/irrlicht/libpng/scripts/smakefile.ppc | 30 + src/dep/src/irrlicht/os.cpp | 299 + src/dep/src/irrlicht/os.h | 107 + src/dep/src/irrlicht/source.txt | 40 + src/dep/src/irrlicht/zlib/ChangeLog | 855 ++ src/dep/src/irrlicht/zlib/FAQ | 339 + src/dep/src/irrlicht/zlib/INDEX | 51 + src/dep/src/irrlicht/zlib/README | 125 + src/dep/src/irrlicht/zlib/adler32.c | 149 + src/dep/src/irrlicht/zlib/algorithm.txt | 209 + src/dep/src/irrlicht/zlib/compress.c | 79 + src/dep/src/irrlicht/zlib/crc32.c | 423 + src/dep/src/irrlicht/zlib/crc32.h | 441 + src/dep/src/irrlicht/zlib/deflate.c | 1736 ++++ src/dep/src/irrlicht/zlib/deflate.h | 331 + src/dep/src/irrlicht/zlib/gzio.c | 1026 +++ src/dep/src/irrlicht/zlib/infback.c | 623 ++ src/dep/src/irrlicht/zlib/inffast.c | 318 + src/dep/src/irrlicht/zlib/inffast.h | 11 + src/dep/src/irrlicht/zlib/inffixed.h | 94 + src/dep/src/irrlicht/zlib/inflate.c | 1368 ++++ src/dep/src/irrlicht/zlib/inflate.h | 115 + src/dep/src/irrlicht/zlib/inftrees.c | 329 + src/dep/src/irrlicht/zlib/inftrees.h | 55 + src/dep/src/irrlicht/zlib/trees.c | 1219 +++ src/dep/src/irrlicht/zlib/trees.h | 128 + src/dep/src/irrlicht/zlib/uncompr.c | 61 + src/dep/src/irrlicht/zlib/zconf.h | 332 + src/dep/src/irrlicht/zlib/zlib.3 | 159 + src/dep/src/irrlicht/zlib/zlib.h | 1357 +++ src/dep/src/irrlicht/zlib/zutil.c | 318 + src/dep/src/irrlicht/zlib/zutil.h | 269 + 911 files changed, 319052 insertions(+), 27 deletions(-) create mode 100644 src/dep/include/irrlicht/CMeshBuffer.h create mode 100644 src/dep/include/irrlicht/ECullingTypes.h create mode 100644 src/dep/include/irrlicht/EDebugSceneTypes.h create mode 100644 src/dep/include/irrlicht/EDriverFeatures.h create mode 100644 src/dep/include/irrlicht/EDriverTypes.h create mode 100644 src/dep/include/irrlicht/EGUIElementTypes.h create mode 100644 src/dep/include/irrlicht/EMaterialFlags.h create mode 100644 src/dep/include/irrlicht/EMaterialTypes.h create mode 100644 src/dep/include/irrlicht/EMeshWriterEnums.h create mode 100644 src/dep/include/irrlicht/EMessageBoxFlags.h create mode 100644 src/dep/include/irrlicht/ESceneNodeAnimatorTypes.h create mode 100644 src/dep/include/irrlicht/ESceneNodeTypes.h create mode 100644 src/dep/include/irrlicht/ETerrainElements.h create mode 100644 src/dep/include/irrlicht/IAnimatedMesh.h create mode 100644 src/dep/include/irrlicht/IAnimatedMeshMD2.h create mode 100644 src/dep/include/irrlicht/IAnimatedMeshMD3.h create mode 100644 src/dep/include/irrlicht/IAnimatedMeshSceneNode.h create mode 100644 src/dep/include/irrlicht/IAttributeExchangingObject.h create mode 100644 src/dep/include/irrlicht/IAttributes.h create mode 100644 src/dep/include/irrlicht/IBillboardSceneNode.h create mode 100644 src/dep/include/irrlicht/IBoneSceneNode.h create mode 100644 src/dep/include/irrlicht/ICameraSceneNode.h create mode 100644 src/dep/include/irrlicht/ICursorControl.h create mode 100644 src/dep/include/irrlicht/IDummyTransformationSceneNode.h create mode 100644 src/dep/include/irrlicht/IEventReceiver.h create mode 100644 src/dep/include/irrlicht/IFileList.h create mode 100644 src/dep/include/irrlicht/IFileSystem.h create mode 100644 src/dep/include/irrlicht/IGPUProgrammingServices.h create mode 100644 src/dep/include/irrlicht/IGUIButton.h create mode 100644 src/dep/include/irrlicht/IGUICheckBox.h create mode 100644 src/dep/include/irrlicht/IGUIColorSelectDialog.h create mode 100644 src/dep/include/irrlicht/IGUIComboBox.h create mode 100644 src/dep/include/irrlicht/IGUIContextMenu.h create mode 100644 src/dep/include/irrlicht/IGUIEditBox.h create mode 100644 src/dep/include/irrlicht/IGUIElement.h create mode 100644 src/dep/include/irrlicht/IGUIElementFactory.h create mode 100644 src/dep/include/irrlicht/IGUIEnvironment.h create mode 100644 src/dep/include/irrlicht/IGUIFileOpenDialog.h create mode 100644 src/dep/include/irrlicht/IGUIFont.h create mode 100644 src/dep/include/irrlicht/IGUIFontBitmap.h create mode 100644 src/dep/include/irrlicht/IGUIImage.h create mode 100644 src/dep/include/irrlicht/IGUIInOutFader.h create mode 100644 src/dep/include/irrlicht/IGUIListBox.h create mode 100644 src/dep/include/irrlicht/IGUIMeshViewer.h create mode 100644 src/dep/include/irrlicht/IGUIScrollBar.h create mode 100644 src/dep/include/irrlicht/IGUISkin.h create mode 100644 src/dep/include/irrlicht/IGUISpinBox.h create mode 100644 src/dep/include/irrlicht/IGUISpriteBank.h create mode 100644 src/dep/include/irrlicht/IGUIStaticText.h create mode 100644 src/dep/include/irrlicht/IGUITabControl.h create mode 100644 src/dep/include/irrlicht/IGUIToolbar.h create mode 100644 src/dep/include/irrlicht/IGUIWindow.h create mode 100644 src/dep/include/irrlicht/IImage.h create mode 100644 src/dep/include/irrlicht/IImageLoader.h create mode 100644 src/dep/include/irrlicht/IImageWriter.h create mode 100644 src/dep/include/irrlicht/ILightSceneNode.h create mode 100644 src/dep/include/irrlicht/ILogger.h create mode 100644 src/dep/include/irrlicht/IMaterialRenderer.h create mode 100644 src/dep/include/irrlicht/IMaterialRendererServices.h create mode 100644 src/dep/include/irrlicht/IMesh.h create mode 100644 src/dep/include/irrlicht/IMeshBuffer.h create mode 100644 src/dep/include/irrlicht/IMeshCache.h create mode 100644 src/dep/include/irrlicht/IMeshLoader.h create mode 100644 src/dep/include/irrlicht/IMeshManipulator.h create mode 100644 src/dep/include/irrlicht/IMeshSceneNode.h create mode 100644 src/dep/include/irrlicht/IMeshWriter.h create mode 100644 src/dep/include/irrlicht/IMetaTriangleSelector.h create mode 100644 src/dep/include/irrlicht/IOSOperator.h create mode 100644 src/dep/include/irrlicht/IParticleAffector.h create mode 100644 src/dep/include/irrlicht/IParticleAnimatedMeshSceneNodeEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleAttractionAffector.h create mode 100644 src/dep/include/irrlicht/IParticleBoxEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleCylinderEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleFadeOutAffector.h create mode 100644 src/dep/include/irrlicht/IParticleGravityAffector.h create mode 100644 src/dep/include/irrlicht/IParticleMeshEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleRingEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleRotationAffector.h create mode 100644 src/dep/include/irrlicht/IParticleSphereEmitter.h create mode 100644 src/dep/include/irrlicht/IParticleSystemSceneNode.h create mode 100644 src/dep/include/irrlicht/IQ3LevelMesh.h create mode 100644 src/dep/include/irrlicht/IQ3Shader.h create mode 100644 src/dep/include/irrlicht/IReadFile.h create mode 100644 src/dep/include/irrlicht/IReferenceCounted.h create mode 100644 src/dep/include/irrlicht/ISceneCollisionManager.h create mode 100644 src/dep/include/irrlicht/ISceneManager.h create mode 100644 src/dep/include/irrlicht/ISceneNode.h create mode 100644 src/dep/include/irrlicht/ISceneNodeAnimator.h create mode 100644 src/dep/include/irrlicht/ISceneNodeAnimatorCollisionResponse.h create mode 100644 src/dep/include/irrlicht/ISceneNodeAnimatorFactory.h create mode 100644 src/dep/include/irrlicht/ISceneNodeFactory.h create mode 100644 src/dep/include/irrlicht/ISceneUserDataSerializer.h create mode 100644 src/dep/include/irrlicht/IShaderConstantSetCallBack.h create mode 100644 src/dep/include/irrlicht/IShadowVolumeSceneNode.h create mode 100644 src/dep/include/irrlicht/ISkinnedMesh.h create mode 100644 src/dep/include/irrlicht/ITerrainSceneNode.h create mode 100644 src/dep/include/irrlicht/ITextSceneNode.h create mode 100644 src/dep/include/irrlicht/ITexture.h create mode 100644 src/dep/include/irrlicht/ITimer.h create mode 100644 src/dep/include/irrlicht/ITriangleSelector.h create mode 100644 src/dep/include/irrlicht/IVideoDriver.h create mode 100644 src/dep/include/irrlicht/IVideoModeList.h create mode 100644 src/dep/include/irrlicht/IWriteFile.h create mode 100644 src/dep/include/irrlicht/IXMLReader.h create mode 100644 src/dep/include/irrlicht/IXMLWriter.h create mode 100644 src/dep/include/irrlicht/IrrCompileConfig.h create mode 100644 src/dep/include/irrlicht/IrrlichtDevice.h create mode 100644 src/dep/include/irrlicht/Keycodes.h create mode 100644 src/dep/include/irrlicht/S3DVertex.h create mode 100644 src/dep/include/irrlicht/SAnimatedMesh.h create mode 100644 src/dep/include/irrlicht/SColor.h create mode 100644 src/dep/include/irrlicht/SExposedVideoData.h create mode 100644 src/dep/include/irrlicht/SIrrCreationParameters.h create mode 100644 src/dep/include/irrlicht/SKeyMap.h create mode 100644 src/dep/include/irrlicht/SLight.h create mode 100644 src/dep/include/irrlicht/SMaterial.h create mode 100644 src/dep/include/irrlicht/SMaterialLayer.h create mode 100644 src/dep/include/irrlicht/SMesh.h create mode 100644 src/dep/include/irrlicht/SMeshBuffer.h create mode 100644 src/dep/include/irrlicht/SMeshBufferLightMap.h create mode 100644 src/dep/include/irrlicht/SMeshBufferTangents.h create mode 100644 src/dep/include/irrlicht/SParticle.h create mode 100644 src/dep/include/irrlicht/SSharedMeshBuffer.h create mode 100644 src/dep/include/irrlicht/SSkinMeshBuffer.h create mode 100644 src/dep/include/irrlicht/SViewFrustum.h create mode 100644 src/dep/include/irrlicht/SceneParameters.h create mode 100644 src/dep/include/irrlicht/aabbox3d.h create mode 100644 src/dep/include/irrlicht/coreutil.h create mode 100644 src/dep/include/irrlicht/dimension2d.h create mode 100644 src/dep/include/irrlicht/fast_atof.h create mode 100644 src/dep/include/irrlicht/heapsort.h create mode 100644 src/dep/include/irrlicht/irrAllocator.h create mode 100644 src/dep/include/irrlicht/irrArray.h create mode 100644 src/dep/include/irrlicht/irrList.h create mode 100644 src/dep/include/irrlicht/irrMap.h create mode 100644 src/dep/include/irrlicht/irrMath.h create mode 100644 src/dep/include/irrlicht/irrString.h create mode 100644 src/dep/include/irrlicht/irrTypes.h create mode 100644 src/dep/include/irrlicht/irrXML.h create mode 100644 src/dep/include/irrlicht/irrlicht.h create mode 100644 src/dep/include/irrlicht/line2d.h create mode 100644 src/dep/include/irrlicht/line3d.h create mode 100644 src/dep/include/irrlicht/matrix4.h create mode 100644 src/dep/include/irrlicht/plane3d.h create mode 100644 src/dep/include/irrlicht/position2d.h create mode 100644 src/dep/include/irrlicht/quaternion.h create mode 100644 src/dep/include/irrlicht/rect.h create mode 100644 src/dep/include/irrlicht/triangle3d.h create mode 100644 src/dep/include/irrlicht/vector2d.h create mode 100644 src/dep/include/irrlicht/vector3d.h create mode 100644 src/dep/src/irrlicht/BuiltInFont.h create mode 100644 src/dep/src/irrlicht/C3DSMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/C3DSMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CAnimatedMeshMD2.cpp create mode 100644 src/dep/src/irrlicht/CAnimatedMeshMD2.h create mode 100644 src/dep/src/irrlicht/CAnimatedMeshMD3.cpp create mode 100644 src/dep/src/irrlicht/CAnimatedMeshMD3.h create mode 100644 src/dep/src/irrlicht/CAnimatedMeshSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CAnimatedMeshSceneNode.h create mode 100644 src/dep/src/irrlicht/CAttributeImpl.h create mode 100644 src/dep/src/irrlicht/CAttributes.cpp create mode 100644 src/dep/src/irrlicht/CAttributes.h create mode 100644 src/dep/src/irrlicht/CB3DMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CB3DMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CBSPMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CBSPMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CBillboardSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CBillboardSceneNode.h create mode 100644 src/dep/src/irrlicht/CBoneSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CBoneSceneNode.h create mode 100644 src/dep/src/irrlicht/CCSMLoader.cpp create mode 100644 src/dep/src/irrlicht/CCSMLoader.h create mode 100644 src/dep/src/irrlicht/CCameraFPSSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CCameraFPSSceneNode.h create mode 100644 src/dep/src/irrlicht/CCameraMayaSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CCameraMayaSceneNode.h create mode 100644 src/dep/src/irrlicht/CCameraSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CCameraSceneNode.h create mode 100644 src/dep/src/irrlicht/CColladaFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CColladaFileLoader.h create mode 100644 src/dep/src/irrlicht/CColladaMeshWriter.cpp create mode 100644 src/dep/src/irrlicht/CColladaMeshWriter.h create mode 100644 src/dep/src/irrlicht/CColorConverter.cpp create mode 100644 src/dep/src/irrlicht/CColorConverter.h create mode 100644 src/dep/src/irrlicht/CCubeSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CCubeSceneNode.h create mode 100644 src/dep/src/irrlicht/CD3D8Driver.cpp create mode 100644 src/dep/src/irrlicht/CD3D8Driver.h create mode 100644 src/dep/src/irrlicht/CD3D8MaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D8NormalMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D8NormalMapRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D8Texture.cpp create mode 100644 src/dep/src/irrlicht/CD3D8Texture.h create mode 100644 src/dep/src/irrlicht/CD3D9Driver.cpp create mode 100644 src/dep/src/irrlicht/CD3D9Driver.h create mode 100644 src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D9MaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D9NormalMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D9NormalMapRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.cpp create mode 100644 src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CD3D9Texture.cpp create mode 100644 src/dep/src/irrlicht/CD3D9Texture.h create mode 100644 src/dep/src/irrlicht/CDMFLoader.cpp create mode 100644 src/dep/src/irrlicht/CDMFLoader.h create mode 100644 src/dep/src/irrlicht/CDefaultGUIElementFactory.cpp create mode 100644 src/dep/src/irrlicht/CDefaultGUIElementFactory.h create mode 100644 src/dep/src/irrlicht/CDefaultSceneNodeAnimatorFactory.cpp create mode 100644 src/dep/src/irrlicht/CDefaultSceneNodeAnimatorFactory.h create mode 100644 src/dep/src/irrlicht/CDefaultSceneNodeFactory.cpp create mode 100644 src/dep/src/irrlicht/CDefaultSceneNodeFactory.h create mode 100644 src/dep/src/irrlicht/CDepthBuffer.cpp create mode 100644 src/dep/src/irrlicht/CDepthBuffer.h create mode 100644 src/dep/src/irrlicht/CDummyTransformationSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CDummyTransformationSceneNode.h create mode 100644 src/dep/src/irrlicht/CEmptySceneNode.cpp create mode 100644 src/dep/src/irrlicht/CEmptySceneNode.h create mode 100644 src/dep/src/irrlicht/CFPSCounter.cpp create mode 100644 src/dep/src/irrlicht/CFPSCounter.h create mode 100644 src/dep/src/irrlicht/CFileList.cpp create mode 100644 src/dep/src/irrlicht/CFileList.h create mode 100644 src/dep/src/irrlicht/CFileSystem.cpp create mode 100644 src/dep/src/irrlicht/CFileSystem.h create mode 100644 src/dep/src/irrlicht/CGUIButton.cpp create mode 100644 src/dep/src/irrlicht/CGUIButton.h create mode 100644 src/dep/src/irrlicht/CGUICheckBox.cpp create mode 100644 src/dep/src/irrlicht/CGUICheckBox.h create mode 100644 src/dep/src/irrlicht/CGUIColorSelectDialog.cpp create mode 100644 src/dep/src/irrlicht/CGUIColorSelectDialog.h create mode 100644 src/dep/src/irrlicht/CGUIComboBox.cpp create mode 100644 src/dep/src/irrlicht/CGUIComboBox.h create mode 100644 src/dep/src/irrlicht/CGUIContextMenu.cpp create mode 100644 src/dep/src/irrlicht/CGUIContextMenu.h create mode 100644 src/dep/src/irrlicht/CGUIEditBox.cpp create mode 100644 src/dep/src/irrlicht/CGUIEditBox.h create mode 100644 src/dep/src/irrlicht/CGUIEnvironment.cpp create mode 100644 src/dep/src/irrlicht/CGUIEnvironment.h create mode 100644 src/dep/src/irrlicht/CGUIFileOpenDialog.cpp create mode 100644 src/dep/src/irrlicht/CGUIFileOpenDialog.h create mode 100644 src/dep/src/irrlicht/CGUIFont.cpp create mode 100644 src/dep/src/irrlicht/CGUIFont.h create mode 100644 src/dep/src/irrlicht/CGUIImage.cpp create mode 100644 src/dep/src/irrlicht/CGUIImage.h create mode 100644 src/dep/src/irrlicht/CGUIInOutFader.cpp create mode 100644 src/dep/src/irrlicht/CGUIInOutFader.h create mode 100644 src/dep/src/irrlicht/CGUIListBox.cpp create mode 100644 src/dep/src/irrlicht/CGUIListBox.h create mode 100644 src/dep/src/irrlicht/CGUIMenu.cpp create mode 100644 src/dep/src/irrlicht/CGUIMenu.h create mode 100644 src/dep/src/irrlicht/CGUIMeshViewer.cpp create mode 100644 src/dep/src/irrlicht/CGUIMeshViewer.h create mode 100644 src/dep/src/irrlicht/CGUIMessageBox.cpp create mode 100644 src/dep/src/irrlicht/CGUIMessageBox.h create mode 100644 src/dep/src/irrlicht/CGUIModalScreen.cpp create mode 100644 src/dep/src/irrlicht/CGUIModalScreen.h create mode 100644 src/dep/src/irrlicht/CGUIScrollBar.cpp create mode 100644 src/dep/src/irrlicht/CGUIScrollBar.h create mode 100644 src/dep/src/irrlicht/CGUISkin.cpp create mode 100644 src/dep/src/irrlicht/CGUISkin.h create mode 100644 src/dep/src/irrlicht/CGUISpinBox.cpp create mode 100644 src/dep/src/irrlicht/CGUISpinBox.h create mode 100644 src/dep/src/irrlicht/CGUISpriteBank.cpp create mode 100644 src/dep/src/irrlicht/CGUISpriteBank.h create mode 100644 src/dep/src/irrlicht/CGUIStaticText.cpp create mode 100644 src/dep/src/irrlicht/CGUIStaticText.h create mode 100644 src/dep/src/irrlicht/CGUITabControl.cpp create mode 100644 src/dep/src/irrlicht/CGUITabControl.h create mode 100644 src/dep/src/irrlicht/CGUIToolBar.cpp create mode 100644 src/dep/src/irrlicht/CGUIToolBar.h create mode 100644 src/dep/src/irrlicht/CGUIWindow.cpp create mode 100644 src/dep/src/irrlicht/CGUIWindow.h create mode 100644 src/dep/src/irrlicht/CGeometryCreator.cpp create mode 100644 src/dep/src/irrlicht/CGeometryCreator.h create mode 100644 src/dep/src/irrlicht/CImage.cpp create mode 100644 src/dep/src/irrlicht/CImage.h create mode 100644 src/dep/src/irrlicht/CImageLoaderBMP.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderBMP.h create mode 100644 src/dep/src/irrlicht/CImageLoaderJPG.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderJPG.h create mode 100644 src/dep/src/irrlicht/CImageLoaderPCX.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderPCX.h create mode 100644 src/dep/src/irrlicht/CImageLoaderPNG.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderPNG.h create mode 100644 src/dep/src/irrlicht/CImageLoaderPPM.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderPPM.h create mode 100644 src/dep/src/irrlicht/CImageLoaderPSD.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderPSD.h create mode 100644 src/dep/src/irrlicht/CImageLoaderTGA.cpp create mode 100644 src/dep/src/irrlicht/CImageLoaderTGA.h create mode 100644 src/dep/src/irrlicht/CImageWriterBMP.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterBMP.h create mode 100644 src/dep/src/irrlicht/CImageWriterJPG.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterJPG.h create mode 100644 src/dep/src/irrlicht/CImageWriterPCX.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterPCX.h create mode 100644 src/dep/src/irrlicht/CImageWriterPNG.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterPNG.h create mode 100644 src/dep/src/irrlicht/CImageWriterPPM.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterPPM.h create mode 100644 src/dep/src/irrlicht/CImageWriterPSD.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterPSD.h create mode 100644 src/dep/src/irrlicht/CImageWriterTGA.cpp create mode 100644 src/dep/src/irrlicht/CImageWriterTGA.h create mode 100644 src/dep/src/irrlicht/CIrrDeviceLinux.cpp create mode 100644 src/dep/src/irrlicht/CIrrDeviceLinux.h create mode 100644 src/dep/src/irrlicht/CIrrDeviceSDL.cpp create mode 100644 src/dep/src/irrlicht/CIrrDeviceSDL.h create mode 100644 src/dep/src/irrlicht/CIrrDeviceStub.cpp create mode 100644 src/dep/src/irrlicht/CIrrDeviceStub.h create mode 100644 src/dep/src/irrlicht/CIrrDeviceWin32.cpp create mode 100644 src/dep/src/irrlicht/CIrrDeviceWin32.h create mode 100644 src/dep/src/irrlicht/CIrrMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CIrrMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CIrrMeshWriter.cpp create mode 100644 src/dep/src/irrlicht/CIrrMeshWriter.h create mode 100644 src/dep/src/irrlicht/CLMTSMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CLMTSMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CLightSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CLightSceneNode.h create mode 100644 src/dep/src/irrlicht/CLimitReadFile.cpp create mode 100644 src/dep/src/irrlicht/CLimitReadFile.h create mode 100644 src/dep/src/irrlicht/CLogger.cpp create mode 100644 src/dep/src/irrlicht/CLogger.h create mode 100644 src/dep/src/irrlicht/CMD2MeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CMD2MeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CMD3MeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CMD3MeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CMS3DMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CMS3DMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CMY3DHelper.h create mode 100644 src/dep/src/irrlicht/CMY3DMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CMY3DMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CMY3DStuff.h create mode 100644 src/dep/src/irrlicht/CMemoryReadFile.cpp create mode 100644 src/dep/src/irrlicht/CMemoryReadFile.h create mode 100644 src/dep/src/irrlicht/CMeshCache.cpp create mode 100644 src/dep/src/irrlicht/CMeshCache.h create mode 100644 src/dep/src/irrlicht/CMeshManipulator.cpp create mode 100644 src/dep/src/irrlicht/CMeshManipulator.h create mode 100644 src/dep/src/irrlicht/CMeshSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CMeshSceneNode.h create mode 100644 src/dep/src/irrlicht/CMetaTriangleSelector.cpp create mode 100644 src/dep/src/irrlicht/CMetaTriangleSelector.h create mode 100644 src/dep/src/irrlicht/CNullDriver.cpp create mode 100644 src/dep/src/irrlicht/CNullDriver.h create mode 100644 src/dep/src/irrlicht/COBJMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/COBJMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/COCTLoader.cpp create mode 100644 src/dep/src/irrlicht/COCTLoader.h create mode 100644 src/dep/src/irrlicht/COSOperator.cpp create mode 100644 src/dep/src/irrlicht/COSOperator.h create mode 100644 src/dep/src/irrlicht/COctTreeSceneNode.cpp create mode 100644 src/dep/src/irrlicht/COctTreeSceneNode.h create mode 100644 src/dep/src/irrlicht/COctTreeTriangleSelector.cpp create mode 100644 src/dep/src/irrlicht/COctTreeTriangleSelector.h create mode 100644 src/dep/src/irrlicht/COgreMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/COgreMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/COpenGLDriver.cpp create mode 100644 src/dep/src/irrlicht/COpenGLDriver.h create mode 100644 src/dep/src/irrlicht/COpenGLExtensionHandler.cpp create mode 100644 src/dep/src/irrlicht/COpenGLExtensionHandler.h create mode 100644 src/dep/src/irrlicht/COpenGLMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/COpenGLNormalMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/COpenGLNormalMapRenderer.h create mode 100644 src/dep/src/irrlicht/COpenGLParallaxMapRenderer.cpp create mode 100644 src/dep/src/irrlicht/COpenGLParallaxMapRenderer.h create mode 100644 src/dep/src/irrlicht/COpenGLSLMaterialRenderer.cpp create mode 100644 src/dep/src/irrlicht/COpenGLSLMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.cpp create mode 100644 src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.h create mode 100644 src/dep/src/irrlicht/COpenGLTexture.cpp create mode 100644 src/dep/src/irrlicht/COpenGLTexture.h create mode 100644 src/dep/src/irrlicht/CPakReader.cpp create mode 100644 src/dep/src/irrlicht/CPakReader.h create mode 100644 src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleAttractionAffector.cpp create mode 100644 src/dep/src/irrlicht/CParticleAttractionAffector.h create mode 100644 src/dep/src/irrlicht/CParticleBoxEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleBoxEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleCylinderEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleCylinderEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleFadeOutAffector.cpp create mode 100644 src/dep/src/irrlicht/CParticleFadeOutAffector.h create mode 100644 src/dep/src/irrlicht/CParticleGravityAffector.cpp create mode 100644 src/dep/src/irrlicht/CParticleGravityAffector.h create mode 100644 src/dep/src/irrlicht/CParticleMeshEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleMeshEmitter.h create mode 100644 src/dep/src/irrlicht/CParticlePointEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticlePointEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleRingEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleRingEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleRotationAffector.cpp create mode 100644 src/dep/src/irrlicht/CParticleRotationAffector.h create mode 100644 src/dep/src/irrlicht/CParticleSphereEmitter.cpp create mode 100644 src/dep/src/irrlicht/CParticleSphereEmitter.h create mode 100644 src/dep/src/irrlicht/CParticleSystemSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CParticleSystemSceneNode.h create mode 100644 src/dep/src/irrlicht/CQ3LevelMesh.cpp create mode 100644 src/dep/src/irrlicht/CQ3LevelMesh.h create mode 100644 src/dep/src/irrlicht/CQuake3ShaderSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CQuake3ShaderSceneNode.h create mode 100644 src/dep/src/irrlicht/CReadFile.cpp create mode 100644 src/dep/src/irrlicht/CReadFile.h create mode 100644 src/dep/src/irrlicht/CSTLMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CSTLMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CSTLMeshWriter.cpp create mode 100644 src/dep/src/irrlicht/CSTLMeshWriter.h create mode 100644 src/dep/src/irrlicht/CSceneCollisionManager.cpp create mode 100644 src/dep/src/irrlicht/CSceneCollisionManager.h create mode 100644 src/dep/src/irrlicht/CSceneManager.cpp create mode 100644 src/dep/src/irrlicht/CSceneManager.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorDelete.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorDelete.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorRotation.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorRotation.h create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorTexture.cpp create mode 100644 src/dep/src/irrlicht/CSceneNodeAnimatorTexture.h create mode 100644 src/dep/src/irrlicht/CShadowVolumeSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CShadowVolumeSceneNode.h create mode 100644 src/dep/src/irrlicht/CSkinnedMesh.cpp create mode 100644 src/dep/src/irrlicht/CSkinnedMesh.h create mode 100644 src/dep/src/irrlicht/CSkyBoxSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CSkyBoxSceneNode.h create mode 100644 src/dep/src/irrlicht/CSkyDomeSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CSkyDomeSceneNode.h create mode 100644 src/dep/src/irrlicht/CSoftware2MaterialRenderer.h create mode 100644 src/dep/src/irrlicht/CSoftwareDriver.cpp create mode 100644 src/dep/src/irrlicht/CSoftwareDriver.h create mode 100644 src/dep/src/irrlicht/CSoftwareDriver2.cpp create mode 100644 src/dep/src/irrlicht/CSoftwareDriver2.h create mode 100644 src/dep/src/irrlicht/CSoftwareTexture.cpp create mode 100644 src/dep/src/irrlicht/CSoftwareTexture.h create mode 100644 src/dep/src/irrlicht/CSoftwareTexture2.cpp create mode 100644 src/dep/src/irrlicht/CSoftwareTexture2.h create mode 100644 src/dep/src/irrlicht/CSphereSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CSphereSceneNode.h create mode 100644 src/dep/src/irrlicht/CTRFlat.cpp create mode 100644 src/dep/src/irrlicht/CTRFlatWire.cpp create mode 100644 src/dep/src/irrlicht/CTRGouraud.cpp create mode 100644 src/dep/src/irrlicht/CTRGouraud2.cpp create mode 100644 src/dep/src/irrlicht/CTRGouraudAlpha2.cpp create mode 100644 src/dep/src/irrlicht/CTRGouraudAlphaNoZ2.cpp create mode 100644 src/dep/src/irrlicht/CTRGouraudWire.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureBlend.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureDetailMap2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureFlat.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureFlatWire.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraud.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraud.h create mode 100644 src/dep/src/irrlicht/CTRTextureGouraud2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudAdd.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudAdd2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudAddNoZ2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudAlpha.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudAlphaNoZ.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudNoZ.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudNoZ2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudVertexAlpha2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureGouraudWire.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureLightMap2_Add.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureLightMap2_M1.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureLightMap2_M2.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureLightMap2_M4.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureLightMapGouraud2_M4.cpp create mode 100644 src/dep/src/irrlicht/CTRTextureWire2.cpp create mode 100644 src/dep/src/irrlicht/CTerrainSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CTerrainSceneNode.h create mode 100644 src/dep/src/irrlicht/CTerrainTriangleSelector.cpp create mode 100644 src/dep/src/irrlicht/CTerrainTriangleSelector.h create mode 100644 src/dep/src/irrlicht/CTextSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CTextSceneNode.h create mode 100644 src/dep/src/irrlicht/CTimer.h create mode 100644 src/dep/src/irrlicht/CTriangleBBSelector.cpp create mode 100644 src/dep/src/irrlicht/CTriangleBBSelector.h create mode 100644 src/dep/src/irrlicht/CTriangleSelector.cpp create mode 100644 src/dep/src/irrlicht/CTriangleSelector.h create mode 100644 src/dep/src/irrlicht/CVideoModeList.cpp create mode 100644 src/dep/src/irrlicht/CVideoModeList.h create mode 100644 src/dep/src/irrlicht/CWaterSurfaceSceneNode.cpp create mode 100644 src/dep/src/irrlicht/CWaterSurfaceSceneNode.h create mode 100644 src/dep/src/irrlicht/CWriteFile.cpp create mode 100644 src/dep/src/irrlicht/CWriteFile.h create mode 100644 src/dep/src/irrlicht/CXMLReader.cpp create mode 100644 src/dep/src/irrlicht/CXMLReader.h create mode 100644 src/dep/src/irrlicht/CXMLReaderImpl.h create mode 100644 src/dep/src/irrlicht/CXMLWriter.cpp create mode 100644 src/dep/src/irrlicht/CXMLWriter.h create mode 100644 src/dep/src/irrlicht/CXMeshFileLoader.cpp create mode 100644 src/dep/src/irrlicht/CXMeshFileLoader.h create mode 100644 src/dep/src/irrlicht/CZBuffer.cpp create mode 100644 src/dep/src/irrlicht/CZBuffer.h create mode 100644 src/dep/src/irrlicht/CZipReader.cpp create mode 100644 src/dep/src/irrlicht/CZipReader.h create mode 100644 src/dep/src/irrlicht/IBurningShader.cpp create mode 100644 src/dep/src/irrlicht/IBurningShader.h create mode 100644 src/dep/src/irrlicht/IDepthBuffer.h create mode 100644 src/dep/src/irrlicht/IImagePresenter.h create mode 100644 src/dep/src/irrlicht/ITriangleRenderer.h create mode 100644 src/dep/src/irrlicht/IZBuffer.h create mode 100644 src/dep/src/irrlicht/Irrlicht.cpp create mode 100644 src/dep/src/irrlicht/Irrlicht.dev create mode 100644 src/dep/src/irrlicht/Irrlicht.dsp create mode 100644 src/dep/src/irrlicht/Irrlicht.dsw create mode 100644 src/dep/src/irrlicht/Irrlicht.opt create mode 100644 src/dep/src/irrlicht/Irrlicht7.1.sln create mode 100644 src/dep/src/irrlicht/Irrlicht7.1.vcproj create mode 100644 src/dep/src/irrlicht/Irrlicht8.0.sln create mode 100644 src/dep/src/irrlicht/Irrlicht8.0.vcproj create mode 100644 src/dep/src/irrlicht/Irrlicht_Win32-gcc.cbp create mode 100644 src/dep/src/irrlicht/MacOSX/._MainMenu.nib create mode 100644 src/dep/src/irrlicht/MacOSX/AppDelegate.h create mode 100644 src/dep/src/irrlicht/MacOSX/AppDelegate.mm create mode 100644 src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.h create mode 100644 src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.mm create mode 100644 src/dep/src/irrlicht/MacOSX/DemoApp-Info.plist create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.mode1 create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.pbxuser create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.mode1 create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.pbxuser create mode 100644 src/dep/src/irrlicht/MacOSX/MacOSX_Prefix.pch create mode 100644 src/dep/src/irrlicht/MacOSX/MainMenu.nib/classes.nib create mode 100644 src/dep/src/irrlicht/MacOSX/MainMenu.nib/info.nib create mode 100644 src/dep/src/irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib create mode 100644 src/dep/src/irrlicht/MacOSX/OSXClipboard.h create mode 100644 src/dep/src/irrlicht/MacOSX/OSXClipboard.mm create mode 100644 src/dep/src/irrlicht/Makefile create mode 100644 src/dep/src/irrlicht/OctTree.h create mode 100644 src/dep/src/irrlicht/S2DVertex.h create mode 100644 src/dep/src/irrlicht/S4DVertex.h create mode 100644 src/dep/src/irrlicht/SoftwareDriver2_compile_config.h create mode 100644 src/dep/src/irrlicht/SoftwareDriver2_helper.h create mode 100644 src/dep/src/irrlicht/builtInFont.bmp create mode 100644 src/dep/src/irrlicht/dmfsupport.h create mode 100644 src/dep/src/irrlicht/glext.h create mode 100644 src/dep/src/irrlicht/glxext.h create mode 100644 src/dep/src/irrlicht/irrXML.cpp create mode 100644 src/dep/src/irrlicht/jpeglib/README create mode 100644 src/dep/src/irrlicht/jpeglib/Tcdjpeg.c create mode 100644 src/dep/src/irrlicht/jpeglib/ansi2knr create mode 100644 src/dep/src/irrlicht/jpeglib/ansi2knr.1 create mode 100644 src/dep/src/irrlicht/jpeglib/ansi2knr.c create mode 100644 src/dep/src/irrlicht/jpeglib/cderror.h create mode 100644 src/dep/src/irrlicht/jpeglib/cdjpeg.c create mode 100644 src/dep/src/irrlicht/jpeglib/cdjpeg.h create mode 100644 src/dep/src/irrlicht/jpeglib/change.log create mode 100644 src/dep/src/irrlicht/jpeglib/cjpeg.1 create mode 100644 src/dep/src/irrlicht/jpeglib/cjpeg.c create mode 100644 src/dep/src/irrlicht/jpeglib/ckconfig.c create mode 100644 src/dep/src/irrlicht/jpeglib/coderules.doc create mode 100644 src/dep/src/irrlicht/jpeglib/config.guess create mode 100644 src/dep/src/irrlicht/jpeglib/config.sub create mode 100644 src/dep/src/irrlicht/jpeglib/configure create mode 100644 src/dep/src/irrlicht/jpeglib/djpeg.1 create mode 100644 src/dep/src/irrlicht/jpeglib/djpeg.c create mode 100644 src/dep/src/irrlicht/jpeglib/example.c create mode 100644 src/dep/src/irrlicht/jpeglib/filelist.doc create mode 100644 src/dep/src/irrlicht/jpeglib/install-sh create mode 100644 src/dep/src/irrlicht/jpeglib/install.doc create mode 100644 src/dep/src/irrlicht/jpeglib/jcapimin.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcapistd.c create mode 100644 src/dep/src/irrlicht/jpeglib/jccoefct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jccolor.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcdctmgr.c create mode 100644 src/dep/src/irrlicht/jpeglib/jchuff.c create mode 100644 src/dep/src/irrlicht/jpeglib/jchuff.h create mode 100644 src/dep/src/irrlicht/jpeglib/jcinit.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcmainct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcmarker.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcmaster.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcomapi.c create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.bcc create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.cfg create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.dj create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.doc create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.h create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.mac create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.manx create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.mc6 create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.sas create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.st create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.vc create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.vms create mode 100644 src/dep/src/irrlicht/jpeglib/jconfig.wat create mode 100644 src/dep/src/irrlicht/jpeglib/jcparam.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcphuff.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcprepct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jcsample.c create mode 100644 src/dep/src/irrlicht/jpeglib/jctrans.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdapimin.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdapistd.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdatadst.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdatasrc.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdcoefct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdcolor.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdct.h create mode 100644 src/dep/src/irrlicht/jpeglib/jddctmgr.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdhuff.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdhuff.h create mode 100644 src/dep/src/irrlicht/jpeglib/jdinput.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdmainct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdmarker.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdmaster.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdmerge.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdphuff.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdpostct.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdsample.c create mode 100644 src/dep/src/irrlicht/jpeglib/jdtrans.c create mode 100644 src/dep/src/irrlicht/jpeglib/jerror.c create mode 100644 src/dep/src/irrlicht/jpeglib/jerror.h create mode 100644 src/dep/src/irrlicht/jpeglib/jfdctflt.c create mode 100644 src/dep/src/irrlicht/jpeglib/jfdctfst.c create mode 100644 src/dep/src/irrlicht/jpeglib/jfdctint.c create mode 100644 src/dep/src/irrlicht/jpeglib/jidctflt.c create mode 100644 src/dep/src/irrlicht/jpeglib/jidctfst.c create mode 100644 src/dep/src/irrlicht/jpeglib/jidctint.c create mode 100644 src/dep/src/irrlicht/jpeglib/jidctred.c create mode 100644 src/dep/src/irrlicht/jpeglib/jinclude.h create mode 100644 src/dep/src/irrlicht/jpeglib/jmemansi.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemdos.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemdosa.asm create mode 100644 src/dep/src/irrlicht/jpeglib/jmemmac.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemmgr.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemname.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemnobs.c create mode 100644 src/dep/src/irrlicht/jpeglib/jmemsys.h create mode 100644 src/dep/src/irrlicht/jpeglib/jmorecfg.h create mode 100644 src/dep/src/irrlicht/jpeglib/jpegint.h create mode 100644 src/dep/src/irrlicht/jpeglib/jpeglib.h create mode 100644 src/dep/src/irrlicht/jpeglib/jpegtran.1 create mode 100644 src/dep/src/irrlicht/jpeglib/jpegtran.c create mode 100644 src/dep/src/irrlicht/jpeglib/jquant1.c create mode 100644 src/dep/src/irrlicht/jpeglib/jquant2.c create mode 100644 src/dep/src/irrlicht/jpeglib/jutils.c create mode 100644 src/dep/src/irrlicht/jpeglib/jversion.h create mode 100644 src/dep/src/irrlicht/jpeglib/libjpeg.doc create mode 100644 src/dep/src/irrlicht/jpeglib/ltconfig create mode 100644 src/dep/src/irrlicht/jpeglib/ltmain.sh create mode 100644 src/dep/src/irrlicht/jpeglib/makcjpeg.st create mode 100644 src/dep/src/irrlicht/jpeglib/makdjpeg.st create mode 100644 src/dep/src/irrlicht/jpeglib/makeapps.ds create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.ansi create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.bcc create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.cfg create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.dj create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.manx create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.mc6 create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.mms create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.sas create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.unix create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.vc create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.vms create mode 100644 src/dep/src/irrlicht/jpeglib/makefile.wat create mode 100644 src/dep/src/irrlicht/jpeglib/makelib.ds create mode 100644 src/dep/src/irrlicht/jpeglib/makeproj.mac create mode 100644 src/dep/src/irrlicht/jpeglib/makljpeg.st create mode 100644 src/dep/src/irrlicht/jpeglib/maktjpeg.st create mode 100644 src/dep/src/irrlicht/jpeglib/makvms.opt create mode 100644 src/dep/src/irrlicht/jpeglib/rdbmp.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdcolmap.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdgif.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdjpgcom.1 create mode 100644 src/dep/src/irrlicht/jpeglib/rdjpgcom.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdppm.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdrle.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdswitch.c create mode 100644 src/dep/src/irrlicht/jpeglib/rdtarga.c create mode 100644 src/dep/src/irrlicht/jpeglib/structure.doc create mode 100644 src/dep/src/irrlicht/jpeglib/testimg.bmp create mode 100644 src/dep/src/irrlicht/jpeglib/testimg.jpg create mode 100644 src/dep/src/irrlicht/jpeglib/testimg.ppm create mode 100644 src/dep/src/irrlicht/jpeglib/testimgp.jpg create mode 100644 src/dep/src/irrlicht/jpeglib/testorig.jpg create mode 100644 src/dep/src/irrlicht/jpeglib/testprog.jpg create mode 100644 src/dep/src/irrlicht/jpeglib/transupp.c create mode 100644 src/dep/src/irrlicht/jpeglib/transupp.h create mode 100644 src/dep/src/irrlicht/jpeglib/usage.doc create mode 100644 src/dep/src/irrlicht/jpeglib/wizard.doc create mode 100644 src/dep/src/irrlicht/jpeglib/wrbmp.c create mode 100644 src/dep/src/irrlicht/jpeglib/wrgif.c create mode 100644 src/dep/src/irrlicht/jpeglib/wrjpgcom.1 create mode 100644 src/dep/src/irrlicht/jpeglib/wrjpgcom.c create mode 100644 src/dep/src/irrlicht/jpeglib/wrppm.c create mode 100644 src/dep/src/irrlicht/jpeglib/wrrle.c create mode 100644 src/dep/src/irrlicht/jpeglib/wrtarga.c create mode 100644 src/dep/src/irrlicht/libpng/ANNOUNCE create mode 100644 src/dep/src/irrlicht/libpng/CHANGES create mode 100644 src/dep/src/irrlicht/libpng/INSTALL create mode 100644 src/dep/src/irrlicht/libpng/KNOWNBUG create mode 100644 src/dep/src/irrlicht/libpng/LICENSE create mode 100644 src/dep/src/irrlicht/libpng/README create mode 100644 src/dep/src/irrlicht/libpng/TODO create mode 100644 src/dep/src/irrlicht/libpng/Y2KINFO create mode 100644 src/dep/src/irrlicht/libpng/configure create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/LICENSE create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.sgi create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.unx create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.w32 create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/README create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/makevms.com create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.h create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.h create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-win.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-x.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-win.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-x.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/toucan.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/wpng.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.h create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/README create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.std create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.tc3 create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/makevms.com create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.bat create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.sh create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.bat create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.sh create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.bat create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.sh create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g01.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g02.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g04.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g08.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g16.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn2c08.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn2c16.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p01.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p02.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p04.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p08.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn4a08.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn4a16.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn6a08.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/pngsuite/basn6a16.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/PngFile.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/PngFile.h create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/README.txt create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.c create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsp create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsw create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.ico create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.png create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.rc create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/cexcept.h create mode 100644 src/dep/src/irrlicht/libpng/contrib/visupng/resource.h create mode 100644 src/dep/src/irrlicht/libpng/example.c create mode 100644 src/dep/src/irrlicht/libpng/libpng-1.2.18.txt create mode 100644 src/dep/src/irrlicht/libpng/libpng.3 create mode 100644 src/dep/src/irrlicht/libpng/libpngpf.3 create mode 100644 src/dep/src/irrlicht/libpng/png.5 create mode 100644 src/dep/src/irrlicht/libpng/png.c create mode 100644 src/dep/src/irrlicht/libpng/png.h create mode 100644 src/dep/src/irrlicht/libpng/pngbar.jpg create mode 100644 src/dep/src/irrlicht/libpng/pngbar.png create mode 100644 src/dep/src/irrlicht/libpng/pngconf.h create mode 100644 src/dep/src/irrlicht/libpng/pngerror.c create mode 100644 src/dep/src/irrlicht/libpng/pnggccrd.c create mode 100644 src/dep/src/irrlicht/libpng/pngget.c create mode 100644 src/dep/src/irrlicht/libpng/pngmem.c create mode 100644 src/dep/src/irrlicht/libpng/pngnow.png create mode 100644 src/dep/src/irrlicht/libpng/pngpread.c create mode 100644 src/dep/src/irrlicht/libpng/pngread.c create mode 100644 src/dep/src/irrlicht/libpng/pngrio.c create mode 100644 src/dep/src/irrlicht/libpng/pngrtran.c create mode 100644 src/dep/src/irrlicht/libpng/pngrutil.c create mode 100644 src/dep/src/irrlicht/libpng/pngset.c create mode 100644 src/dep/src/irrlicht/libpng/pngtest.c create mode 100644 src/dep/src/irrlicht/libpng/pngtest.png create mode 100644 src/dep/src/irrlicht/libpng/pngtrans.c create mode 100644 src/dep/src/irrlicht/libpng/pngvcrd.c create mode 100644 src/dep/src/irrlicht/libpng/pngwio.c create mode 100644 src/dep/src/irrlicht/libpng/pngwrite.c create mode 100644 src/dep/src/irrlicht/libpng/pngwtran.c create mode 100644 src/dep/src/irrlicht/libpng/pngwutil.c create mode 100644 src/dep/src/irrlicht/libpng/projects/beos/x86-shared.proj create mode 100644 src/dep/src/irrlicht/libpng/projects/beos/x86-shared.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/beos/x86-static.proj create mode 100644 src/dep/src/irrlicht/libpng/projects/beos/x86-static.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.bpf create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.bpg create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.bpr create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.cpp create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.readme.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpf create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpr create mode 100644 src/dep/src/irrlicht/libpng/projects/cbuilder5/zlib.readme.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/netware.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc6/README.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsp create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsw create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc6/pngtest.dsp create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/PRJ0041.mak create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/README.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/README_zlib.txt create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/libpng.sln create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/libpng.vcproj create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/pngtest.vcproj create mode 100644 src/dep/src/irrlicht/libpng/projects/visualc71/zlib.vcproj create mode 100644 src/dep/src/irrlicht/libpng/projects/wince.txt create mode 100644 src/dep/src/irrlicht/libpng/scripts/CMakeLists.txt create mode 100644 src/dep/src/irrlicht/libpng/scripts/SCOPTIONS.ppc create mode 100644 src/dep/src/irrlicht/libpng/scripts/descrip.mms create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng-config-body.in create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng-config-head.in create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng-config.in create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng.icc create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng.pc-configure.in create mode 100644 src/dep/src/irrlicht/libpng/scripts/libpng.pc.in create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.32sunu create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.64sunu create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.acorn create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.aix create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.amiga create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.atari create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.bc32 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.beos create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.bor create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.cygwin create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.darwin create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.dec create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.dj2 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.elf create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.freebsd create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.gcc create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.gcmmx create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.hp64 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.hpgcc create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.hpux create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.ibmc create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.intel create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.knr create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.linux create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.mingw create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.mips create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.msc create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.ne12bsd create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.netbsd create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.nommx create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.openbsd create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.os2 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.sco create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.sggcc create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.sgi create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.so9 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.solaris create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.std create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.sunos create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.tc3 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.vcawin32 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.vcwin32 create mode 100644 src/dep/src/irrlicht/libpng/scripts/makefile.watcom create mode 100644 src/dep/src/irrlicht/libpng/scripts/makevms.com create mode 100644 src/dep/src/irrlicht/libpng/scripts/pngos2.def create mode 100644 src/dep/src/irrlicht/libpng/scripts/pngw32.def create mode 100644 src/dep/src/irrlicht/libpng/scripts/pngw32.rc create mode 100644 src/dep/src/irrlicht/libpng/scripts/smakefile.ppc create mode 100644 src/dep/src/irrlicht/os.cpp create mode 100644 src/dep/src/irrlicht/os.h create mode 100644 src/dep/src/irrlicht/source.txt create mode 100644 src/dep/src/irrlicht/zlib/ChangeLog create mode 100644 src/dep/src/irrlicht/zlib/FAQ create mode 100644 src/dep/src/irrlicht/zlib/INDEX create mode 100644 src/dep/src/irrlicht/zlib/README create mode 100644 src/dep/src/irrlicht/zlib/adler32.c create mode 100644 src/dep/src/irrlicht/zlib/algorithm.txt create mode 100644 src/dep/src/irrlicht/zlib/compress.c create mode 100644 src/dep/src/irrlicht/zlib/crc32.c create mode 100644 src/dep/src/irrlicht/zlib/crc32.h create mode 100644 src/dep/src/irrlicht/zlib/deflate.c create mode 100644 src/dep/src/irrlicht/zlib/deflate.h create mode 100644 src/dep/src/irrlicht/zlib/gzio.c create mode 100644 src/dep/src/irrlicht/zlib/infback.c create mode 100644 src/dep/src/irrlicht/zlib/inffast.c create mode 100644 src/dep/src/irrlicht/zlib/inffast.h create mode 100644 src/dep/src/irrlicht/zlib/inffixed.h create mode 100644 src/dep/src/irrlicht/zlib/inflate.c create mode 100644 src/dep/src/irrlicht/zlib/inflate.h create mode 100644 src/dep/src/irrlicht/zlib/inftrees.c create mode 100644 src/dep/src/irrlicht/zlib/inftrees.h create mode 100644 src/dep/src/irrlicht/zlib/trees.c create mode 100644 src/dep/src/irrlicht/zlib/trees.h create mode 100644 src/dep/src/irrlicht/zlib/uncompr.c create mode 100644 src/dep/src/irrlicht/zlib/zconf.h create mode 100644 src/dep/src/irrlicht/zlib/zlib.3 create mode 100644 src/dep/src/irrlicht/zlib/zlib.h create mode 100644 src/dep/src/irrlicht/zlib/zutil.c create mode 100644 src/dep/src/irrlicht/zlib/zutil.h diff --git a/PseuWoW.sln b/PseuWoW.sln index 37666df..08a7754 100644 --- a/PseuWoW.sln +++ b/PseuWoW.sln @@ -21,22 +21,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "src\shared.vcproj {262199E8-EEDF-4700-A1D1-E9CC901CF480} = {262199E8-EEDF-4700-A1D1-E9CC901CF480} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "src\dep\src\irrlicht\Irrlicht7.1.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" - ProjectSection(ProjectDependencies) = postProject - {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StuffExtract", "src\tools\stuffextract.vcproj", "{EFFE60F4-DA39-41E8-9E53-E462000A2D91}" ProjectSection(ProjectDependencies) = postProject {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} {F548FC51-24A4-45FF-A381-BEBC39F18270} = {F548FC51-24A4-45FF-A381-BEBC39F18270} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "src\dep\src\irrlicht\Irrlicht7.1.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Relase - Fast FPU = Relase - Fast FPU Release = Release + Release - Fast FPU = Release - Fast FPU Release - Fast FPU DebugInfo = Release - Fast FPU DebugInfo EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution @@ -46,6 +46,8 @@ Global {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Relase - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release.Build.0 = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Debug.ActiveCfg = Debug|Win32 @@ -54,6 +56,8 @@ Global {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Relase - Fast FPU.Build.0 = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release.ActiveCfg = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release.Build.0 = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - Fast FPU.ActiveCfg = Release|Win32 + {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - Fast FPU.Build.0 = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Debug.ActiveCfg = Debug|Win32 @@ -62,6 +66,8 @@ Global {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Relase - Fast FPU.Build.0 = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release.ActiveCfg = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release.Build.0 = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - Fast FPU.ActiveCfg = Release|Win32 + {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - Fast FPU.Build.0 = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {262199E8-EEDF-4700-A1D1-E9CC901CF480}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Debug.ActiveCfg = Debug|Win32 @@ -70,24 +76,30 @@ Global {F548FC51-24A4-45FF-A381-BEBC39F18270}.Relase - Fast FPU.Build.0 = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release.ActiveCfg = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release.Build.0 = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - Fast FPU.ActiveCfg = Release|Win32 + {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - Fast FPU.Build.0 = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {F548FC51-24A4-45FF-A381-BEBC39F18270}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.ActiveCfg = Debug|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.Build.0 = Debug|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Relase - Fast FPU.ActiveCfg = Relase - Fast FPU|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Relase - Fast FPU.Build.0 = Relase - Fast FPU|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release.ActiveCfg = Release|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release.Build.0 = Release|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.ActiveCfg = Release - Fast FPU DebugInfo|Win32 - {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.Build.0 = Release - Fast FPU DebugInfo|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Debug.ActiveCfg = Debug|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Debug.Build.0 = Debug|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Relase - Fast FPU.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Relase - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release.Build.0 = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU.ActiveCfg = Release|Win32 + {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU.Build.0 = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.ActiveCfg = Release|Win32 {EFFE60F4-DA39-41E8-9E53-E462000A2D91}.Release - Fast FPU DebugInfo.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Relase - Fast FPU.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Relase - Fast FPU.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU DebugInfo.Build.0 = Release - Fast FPU|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index b41526c..2ca2ff9 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -29,7 +29,7 @@ ImproveFloatingPointConsistency="FALSE" FavorSizeOrSpeed="1" AdditionalIncludeDirectories="shared;Client;Client/World;Client/Realm;dep/include" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_IRR_STATIC_LIB_" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="FALSE" @@ -98,7 +98,7 @@ ImproveFloatingPointConsistency="FALSE" OptimizeForProcessor="0" AdditionalIncludeDirectories="shared;Client;Client/World;Client/Realm;dep/include" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_IRR_STATIC_LIB_" BasicRuntimeChecks="3" RuntimeLibrary="1" PrecompiledHeaderFile="" @@ -489,18 +489,42 @@ + + + + + + + + + + + + + + + + @@ -519,24 +543,15 @@ - - - - - - @@ -546,6 +561,9 @@ + + @@ -621,6 +639,9 @@ + + @@ -675,6 +696,9 @@ + + @@ -684,9 +708,39 @@ + + + + + + + + + + + + + + + + + + + + @@ -699,6 +753,9 @@ + + @@ -762,6 +819,9 @@ + + @@ -777,9 +837,6 @@ - - @@ -846,6 +903,9 @@ + + @@ -861,6 +921,12 @@ + + + + diff --git a/src/dep/include/irrlicht/CMeshBuffer.h b/src/dep/include/irrlicht/CMeshBuffer.h new file mode 100644 index 0000000..34386b9 --- /dev/null +++ b/src/dep/include/irrlicht/CMeshBuffer.h @@ -0,0 +1,166 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __T_MESH_BUFFER_H_INCLUDED__ +#define __T_MESH_BUFFER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + //! Template implementation of the IMeshBuffer interface + template + class CMeshBuffer : public IMeshBuffer + { + public: + //! constructor + CMeshBuffer() // everything's default constructed + { + #ifdef _DEBUG + setDebugName("SMeshBuffer"); + #endif + } + + //! returns the material of this meshbuffer + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + //! returns the material of this meshbuffer + virtual video::SMaterial& getMaterial() + { + return Material; + } + + //! returns pointer to vertices + virtual const void* getVertices() const + { + return Vertices.const_pointer(); + } + + //! returns pointer to vertices + virtual void* getVertices() + { + return Vertices.pointer(); + } + + //! returns amount of vertices + virtual u32 getVertexCount() const + { + return Vertices.size(); + } + + //! returns pointer to Indices + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + //! returns pointer to Indices + virtual u16* getIndices() + { + return Indices.pointer(); + } + + //! returns amount of indices + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const + { + return BoundingBox; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox(const core::aabbox3df& box) + { + BoundingBox = box; + } + + + //! recalculates the bounding box. should be called if the mesh changed. + virtual void recalculateBoundingBox() + { + if (Vertices.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices[0].Pos); + for (u32 i=1; i(vertices)[i]); + BoundingBox.addInternalPoint(reinterpret_cast(vertices)[i].Pos); + } + + Indices.reallocate(getIndexCount()+numIndices); + for (i=0; igetVertexCount()); + for (i=0; igetVertexCount(); ++i) + { + Vertices.push_back(reinterpret_cast(other->getVertices())[i]); + } + + Indices.reallocate(getIndexCount()+other->getIndexCount()); + for (i=0; igetIndexCount(); ++i) + { + Indices.push_back(other->getIndices()[i]+vertexCount); + } + BoundingBox.addInternalBox(other->getBoundingBox()); + } + + //! Material for this meshbuffer. + video::SMaterial Material; + //! Vertices of this buffer + core::array Vertices; + //! Indices into the vertices of this buffer. + core::array Indices; + //! Bounding box of this meshbuffer. + core::aabbox3d BoundingBox; + }; + + typedef CMeshBuffer SMeshBuffer; + typedef CMeshBuffer SMeshBufferLightMap; + typedef CMeshBuffer SMeshBufferTangents; +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ECullingTypes.h b/src/dep/include/irrlicht/ECullingTypes.h new file mode 100644 index 0000000..31d74ac --- /dev/null +++ b/src/dep/include/irrlicht/ECullingTypes.h @@ -0,0 +1,39 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_CULLING_TYPES_H_INCLUDED__ +#define __E_CULLING_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of automatic culling for built-in scene nodes + enum E_CULLING_TYPE + { + EAC_OFF = 0, + EAC_BOX = 1, + EAC_FRUSTUM_BOX = 2, + EAC_FRUSTUM_SPHERE = 4 + }; + + //! Names for culling type + const c8* const AutomaticCullingNames[] = + { + "false", + "box", // camera box against node box + "frustum_box", // camera frustum against node box + "frustum_sphere", // camera frustum against node sphere + 0 + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __E_CULLING_TYPES_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/EDebugSceneTypes.h b/src/dep/include/irrlicht/EDebugSceneTypes.h new file mode 100644 index 0000000..4d00a5b --- /dev/null +++ b/src/dep/include/irrlicht/EDebugSceneTypes.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DEBUG_SCENE_TYPES_H_INCLUDED__ +#define __E_DEBUG_SCENE_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of debug data for built-in scene nodes (flags) + enum E_DEBUG_SCENE_TYPE + { + //! No Debug Data ( Default ) + EDS_OFF = 0, + + //! Show Bounding Boxes of SceneNode + EDS_BBOX = 1, + + //! Show Vertex Normals + EDS_NORMALS = 2, + + //! Shows Skeleton/Tags + EDS_SKELETON = 4, + + //! Overlays Mesh Wireframe + EDS_MESH_WIRE_OVERLAY = 8, + + //! Temporary use transparency Material Type + EDS_HALF_TRANSPARENCY = 16, + + //! Show Bounding Boxes of all MeshBuffers + EDS_BBOX_BUFFERS = 32, + + //! Show all debug infos + EDS_FULL = 0xffffffff + }; + + +} // end namespace scene +} // end namespace irr + + +#endif // __E_DEBUG_SCENE_TYPES_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/EDriverFeatures.h b/src/dep/include/irrlicht/EDriverFeatures.h new file mode 100644 index 0000000..dd5b8c8 --- /dev/null +++ b/src/dep/include/irrlicht/EDriverFeatures.h @@ -0,0 +1,88 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DRIVER_FEATURES_H_INCLUDED__ +#define __E_DRIVER_FEATURES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! enumeration for querying features of the video driver. + enum E_VIDEO_DRIVER_FEATURE + { + //! Is driver able to render to a surface? + EVDF_RENDER_TO_TARGET = 0, + + //! Is hardeware transform and lighting supported? + EVDF_HARDWARE_TL, + + //! Are multiple textures per material possible? + EVDF_MULTITEXTURE, + + //! Is driver able to render with a bilinear filter applied? + EVDF_BILINEAR_FILTER, + + //! Can the driver handle mip maps? + EVDF_MIP_MAP, + + //! Can the driver update mip maps automatically? + EVDF_MIP_MAP_AUTO_UPDATE, + + //! Are stencilbuffers switched on and does the device support stencil buffers? + EVDF_STENCIL_BUFFER, + + //! Is Vertex Shader 1.1 supported? + EVDF_VERTEX_SHADER_1_1, + + //! Is Vertex Shader 2.0 supported? + EVDF_VERTEX_SHADER_2_0, + + //! Is Vertex Shader 3.0 supported? + EVDF_VERTEX_SHADER_3_0, + + //! Is Pixel Shader 1.1 supported? + EVDF_PIXEL_SHADER_1_1, + + //! Is Pixel Shader 1.2 supported? + EVDF_PIXEL_SHADER_1_2, + + //! Is Pixel Shader 1.3 supported? + EVDF_PIXEL_SHADER_1_3, + + //! Is Pixel Shader 1.4 supported? + EVDF_PIXEL_SHADER_1_4, + + //! Is Pixel Shader 2.0 supported? + EVDF_PIXEL_SHADER_2_0, + + //! Is Pixel Shader 3.0 supported? + EVDF_PIXEL_SHADER_3_0, + + //! Are ARB vertex programs v1.0 supported? + EVDF_ARB_VERTEX_PROGRAM_1, + + //! Are ARB fragment programs v1.0 supported? + EVDF_ARB_FRAGMENT_PROGRAM_1, + + //! Is GLSL supported? + EVDF_ARB_GLSL, + + //! Is HLSL supported? + EVDF_HLSL, + + //! Are non-power-of-two textures supported? + EVDF_TEXTURE_NPOT, + + //! Are framebuffer objects supported? + EVDF_FRAMEBUFFER_OBJECT + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/EDriverTypes.h b/src/dep/include/irrlicht/EDriverTypes.h new file mode 100644 index 0000000..2993de9 --- /dev/null +++ b/src/dep/include/irrlicht/EDriverTypes.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_DRIVER_TYPES_H_INCLUDED__ +#define __E_DRIVER_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! An enum for all types of drivers the Irrlicht Engine supports. + enum E_DRIVER_TYPE + { + //! Null device, useful for applications to run the engine without visualisation. + //! The null device is able to load textures, but does not render and display + //! any graphics. + EDT_NULL, + + //! The Irrlicht Engine Software renderer, runs on all platforms, + //! with every hardware. It should only be used for 2d graphics, + //! but it can also perform some primitive 3d functions. These 3d drawing + //! functions are quite fast, but very inaccurate, and don't even support + //! clipping in 3D mode. + EDT_SOFTWARE, + + //! The Burning's Software Renderer, an alternative software renderer for Irrlicht. + //! Basically it can be described as the Irrlicht Software renderer on steroids. It rasterizes + //! 3D geometry perfectly: It is able to perform correct 3d clipping, perspective + //! correct texture mapping, perspective correct color mapping, and renders + //! sub pixel correct, sub texel correct primitives. In addition, it does + //! bilinear texel filtering and supports more materials than the EDT_SOFTWARE driver. + //! This renderer has been written entirely by Thomas Alten, thanks a lot for this huge + //! contribution. + EDT_BURNINGSVIDEO, + + //! Direct3D 8 device, only available on Win32 platforms. + //! Performs hardware accelerated rendering of 3D and 2D primitives. + EDT_DIRECT3D8, + + //! Direct3D 9 device, only available on Win32 platforms. + //! Performs hardware accelerated rendering of 3D and 2D primitives. + EDT_DIRECT3D9, + + //! OpenGL device, available on most platforms. + //! Performs hardware accelerated rendering of 3D and 2D primitives. + EDT_OPENGL + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/EGUIElementTypes.h b/src/dep/include/irrlicht/EGUIElementTypes.h new file mode 100644 index 0000000..53faa15 --- /dev/null +++ b/src/dep/include/irrlicht/EGUIElementTypes.h @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_GUI_ELEMENT_TYPES_H_INCLUDED__ +#define __E_GUI_ELEMENT_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace gui +{ + +//! List of all basic Irrlicht GUI elements. +/** An IGUIElement returns this when calling IGUIElement::getType(); */ +enum EGUI_ELEMENT_TYPE +{ + //! A button (IGUIButton) + EGUIET_BUTTON = 0, + + //! A check box (IGUICheckBox) + EGUIET_CHECK_BOX, + + //! A combo box (IGUIComboBox) + EGUIET_COMBO_BOX, + + //! A context menu (IGUIContextMenu) + EGUIET_CONTEXT_MENU, + + //! A menu (IGUIMenu) + EGUIET_MENU, + + //! An edit box (IGUIEditBox) + EGUIET_EDIT_BOX, + + //! A file open dialog (IGUIFileOpenDialog) + EGUIET_FILE_OPEN_DIALOG, + + //! A color select open dialog (IGUIColorSelectDialog) + EGUIET_COLOR_SELECT_DIALOG, + + //! A in/out fader (IGUIInOutFader) + EGUIET_IN_OUT_FADER, + + //! An image (IGUIImage) + EGUIET_IMAGE, + + //! A list box (IGUIListBox) + EGUIET_LIST_BOX, + + //! A mesh viewer (IGUIMeshViewer) + EGUIET_MESH_VIEWER, + + //! A message box (IGUIWindow) + EGUIET_MESSAGE_BOX, + + //! A modal screen + EGUIET_MODAL_SCREEN, + + //! A scroll bar (IGUIScrollBar) + EGUIET_SCROLL_BAR, + + //! A static text (IGUIStaticText) + EGUIET_STATIC_TEXT, + + //! A tab (IGUITab) + EGUIET_TAB, + + //! A tab control + EGUIET_TAB_CONTROL, + + //! A tool bar (IGUIToolBar) + EGUIET_TOOL_BAR, + + //! A window + EGUIET_WINDOW, + + //! A spin box (IGUISpinBox) + EGUIET_SPIN_BOX, + + //! Not an element, amount of elements in there + EGUIET_COUNT, + + //! Unknown type. + EGUIET_ELEMENT, + + //! This enum is never used, it only forces the compiler to + //! compile these enumeration values to 32 bit. + EGUIET_FORCE_32_BIT = 0x7fffffff + +}; + +//! Names for built-in element types +const c8* const GUIElementTypeNames[] = +{ + "button", + "checkBox", + "comboBox", + "contextMenu", + "menu", + "editBox", + "fileOpenDialog", + "colorSelectDialog", + "inOutFader", + "image", + "listBox", + "meshViewer", + "messageBox", + "modalScreen", + "scrollBar", + "staticText", + "tab", + "tabControl", + "toolBar", + "window", + "spinBox", + 0 +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/EMaterialFlags.h b/src/dep/include/irrlicht/EMaterialFlags.h new file mode 100644 index 0000000..4cb0767 --- /dev/null +++ b/src/dep/include/irrlicht/EMaterialFlags.h @@ -0,0 +1,74 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MATERIAL_FLAGS_H_INCLUDED__ +#define __E_MATERIAL_FLAGS_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! Material flags + enum E_MATERIAL_FLAG + { + //! Draw as wireframe or filled triangles? Default: false + EMF_WIREFRAME = 0, + + //! Draw as point cloud or filled triangles? Default: false + EMF_POINTCLOUD, + + //! Flat or Gouraud shading? Default: true + EMF_GOURAUD_SHADING, + + //! Will this material be lighted? Default: true + EMF_LIGHTING, + + //! Is the ZBuffer enabled? Default: true + EMF_ZBUFFER, + + //! May be written to the zbuffer or is it readonly. Default: true + //! This flag is ignored, if the material type is a transparent type. + EMF_ZWRITE_ENABLE, + + //! Is backfaceculling enabled? Default: true + EMF_BACK_FACE_CULLING, + + //! Is bilinear filtering enabled? Default: true + EMF_BILINEAR_FILTER, + + //! Is trilinear filtering enabled? Default: false + //! If the trilinear filter flag is enabled, + //! the bilinear filtering flag is ignored. + EMF_TRILINEAR_FILTER, + + //! Is anisotropic filtering? Default: false + //! In Irrlicht you can use anisotropic texture filtering in + //! conjunction with bilinear or trilinear texture filtering + //! to improve rendering results. Primitives will look less + //! blurry with this flag switched on. + EMF_ANISOTROPIC_FILTER, + + //! Is fog enabled? Default: false + EMF_FOG_ENABLE, + + //! Normalizes normals.You can enable this if you need + //! to scale a dynamic lighted model. Usually, its normals will get scaled + //! too then and it will get darker. If you enable the EMF_NORMALIZE_NORMALS flag, + //! the normals will be normalized again, and the model will look as bright as it should. + EMF_NORMALIZE_NORMALS, + + //! Access to all layers texture wrap settings. Overwrites separate layer settings. + EMF_TEXTURE_WRAP, + + //! This is not a flag, but a value indicating how much flags there are. + EMF_MATERIAL_FLAG_COUNT + }; + +} // end namespace video +} // end namespace irr + + +#endif // __E_MATERIAL_FLAGS_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/EMaterialTypes.h b/src/dep/include/irrlicht/EMaterialTypes.h new file mode 100644 index 0000000..087c338 --- /dev/null +++ b/src/dep/include/irrlicht/EMaterialTypes.h @@ -0,0 +1,223 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MATERIAL_TYPES_H_INCLUDED__ +#define __E_MATERIAL_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace video +{ + + //! Abstracted and easy to use fixed function/programmable pipeline material modes. + enum E_MATERIAL_TYPE + { + //! Standard solid material. Only first texture is used, which is + //! supposed to be the diffuse material. + EMT_SOLID = 0, + + //! Solid material with 2 texture layers. The second is blended onto the + //! first using the alpha value of the vertex colors. + //! This material is currently not implemented in OpenGL, but it + //! works with DirectX. + EMT_SOLID_2_LAYER, + + //! Material type with standard lightmap technique: + //! There should be 2 textures: The first texture layer is a diffuse map, + //! the second is a light map. Vertex light is ignored. + EMT_LIGHTMAP, + + //! Material type with lightmap technique like EMT_LIGHTMAP, but + //! lightmap and diffuse texture are not modulated, but added instead. + EMT_LIGHTMAP_ADD, + + //! Material type with standard lightmap technique: + //! There should be 2 textures: The first texture layer is a diffuse map, + //! the second is a light map. Vertex light is ignored. + //! The texture colors are effectively multiplyied by 2 for brightening. + //! like known in DirectX as D3DTOP_MODULATE2X. + EMT_LIGHTMAP_M2, + + //! Material type with standard lightmap technique: + //! There should be 2 textures: The first texture layer is a diffuse map, + //! the second is a light map. Vertex light is ignored. + //! The texture colors are effectively multiplyied by 4 for brightening. + //! like known in DirectX as D3DTOP_MODULATE4X. + EMT_LIGHTMAP_M4, + + //! Like EMT_LIGHTMAP, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING, + + //! Like EMT_LIGHTMAP_M2, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING_M2, + + //! Like EMT_LIGHTMAP_4, but also supports dynamic lighting. + EMT_LIGHTMAP_LIGHTING_M4, + + //! Detail mapped material. The first texture is diffuse color map, the + //! second is added to this and usually displayed with a bigger scale value + //! so that it adds more detail. The detail map is added to the diffuse map using + //! ADD_SIGNED, so that it is possible to add and substract color from the diffuse + //! map. For example a value of (127,127,127) will not change the appearance of + //! the diffuse map at all. + //! Often used for terrain rendering. + EMT_DETAIL_MAP, + + //! Makes the material look like it was reflection the environment + //! around it. To make this possible, a texture called 'sphere map' + //! is used, which must be set as Textures[0]. + EMT_SPHERE_MAP, + + //! A reflecting material with an + //! optional additional non reflecting texture layer. The reflection + //! map should be set as Texture 1. + EMT_REFLECTION_2_LAYER, + + //! A transparent material. Only the first texture is used. + //! The new color is calculated by simply adding the source color and + //! the dest color. This means if for example a billboard using a texture with + //! black background and a red circle on it is drawn with this material, the + //! result is that only the red circle will be drawn a little bit transparent, + //! and everything which was black is 100% transparent and not visible. + //! This material type is useful for e.g. particle effects. + EMT_TRANSPARENT_ADD_COLOR, + + //! Makes the material transparent based on the texture alpha channel. + //! The final color is blended together from the destination color and the + //! texture color, using the alpha channel value as blend factor. + //! Only first texture is used. If you are using this material with small + //! textures, it is a good idea to load the texture in 32 bit + //! mode (video::IVideoDriver::setTextureCreationFlag()). + //! Also, an alpha ref is used, which can be manipulated using SMaterial::MaterialTypeParam. + //! If set to 0, the alpha ref gets its default value which is 0.5f and which means + //! that pixels with an alpha value >127 will be written, others not. In other, simple + //! words: this value controls how sharp the edges become when going from a + //! transparent to a solid spot on the texture. + EMT_TRANSPARENT_ALPHA_CHANNEL, + + //! Makes the material transparent based on the texture alpha channel. + //! If the alpha channel value is greater than 127, a pixel is written to the + //! target, otherwise not. This material does not use alpha blending + //! and is a lot faster than EMT_TRANSPARENT_ALPHA_CHANNEL. It + //! is ideal for drawing stuff like leafes of plants, because the borders + //! are not blurry but sharp. + //! Only first texture is used. If you are using this material with small + //! textures and 3d object, it is a good idea to load the texture in 32 bit + //! mode (video::IVideoDriver::setTextureCreationFlag()). + EMT_TRANSPARENT_ALPHA_CHANNEL_REF, + + //! Makes the material transparent based on the vertex alpha value. + EMT_TRANSPARENT_VERTEX_ALPHA, + + //! A transparent reflecting material with an + //! optional additional non reflecting texture layer. The reflection + //! map should be set as Texture 1. The transparency depends on the + //! alpha value in the vertex colors. A texture which will not reflect + //! can be set als Texture 2. + //! Please note that this material type is currently not 100% implemented + //! in OpenGL. It works in Direct3D. + EMT_TRANSPARENT_REFLECTION_2_LAYER, + + //! A solid normal map renderer. First texture is the color map, the + //! second should be the normal map. Note that you should use this material + //! only when drawing geometry consisting of vertices of type S3DVertexTangents + //! (EVT_TANGENTS). You can convert any mesh into this format using + //! IMeshManipulator::createMeshWithTangents() (See SpecialFX2 Tutorial). + //! This shader runs on vertex shader 1.1 and pixel shader 1.1 capable hardware and + //! falls back on a fixed function lighted material if this hardware is not available. + //! Only two lights are supported by this shader, if there are more, the nearest two + //! are chosen. Currently, this shader is only implemented for the D3D8 and D3D9 renderers. + EMT_NORMAL_MAP_SOLID, + + //! A transparent normal map renderer. First texture is the color map, the + //! second should be the normal map. Note that you should use this material + //! only when drawing geometry consisting of vertices of type S3DVertexTangents + //! (EVT_TANGENTS). You can convert any mesh into this format using + //! IMeshManipulator::createMeshWithTangents() (See SpecialFX2 Tutorial). + //! This shader runs on vertex shader 1.1 and pixel shader 1.1 capable hardware and + //! falls back on a fixed function lighted material if this hardware is not available. + //! Only two lights are supported by this shader, if there are more, the nearest two + //! are chosen. Currently, this shader is only implemented for the D3D8 and D3D9 renderers. + EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, + + //! A transparent (based on the vertex alpha value) normal map renderer. + //! First texture is the color map, the + //! second should be the normal map. Note that you should use this material + //! only when drawing geometry consisting of vertices of type S3DVertexTangents + //! (EVT_TANGENTS). You can convert any mesh into this format using + //! IMeshManipulator::createMeshWithTangents() (See SpecialFX2 Tutorial). + //! This shader runs on vertex shader 1.1 and pixel shader 1.1 capable hardware and + //! falls back on a fixed function lighted material if this hardware is not available. + //! Only two lights are supported by this shader, if there are more, the nearest two + //! are chosen. Currently, this shader is only implemented for the D3D8 and D3D9 renderers. + EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, + + //! Just like EMT_NORMAL_MAP_SOLID, but uses parallax mapping too, which + //! looks a lot more realistic. This only works when the hardware supports at + //! least vertex shader 1.1 and pixel shader 1.4. + //! First texture is the color map, the second should be the normal map. + //! The normal map texture should contain the height value in the + //! alpha component. The IVideoDriver::makeNormalMapTexture() method writes + //! this value automaticly when creating normal maps from a heightmap when using a 32 bit + //! texture. + //! The height scale of the material (affecting the bumpiness) is being controlled + //! by the SMaterial::MaterialTypeParam member. + //! If set to zero, the default value (0.02f) will be applied. Otherwise + //! the value set in SMaterial::MaterialTypeParam is taken. This value depends on with which + //! scale the texture is mapped on the material. Too high or low values of MaterialTypeParam + //! can result in strange artifacts. + EMT_PARALLAX_MAP_SOLID, + + //! A material just like EMT_PARALLAX_MAP_SOLID, but it is transparent, using + //! EMT_TRANSPARENT_ADD_COLOR as base material. + EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, + + //! A material just like EMT_PARALLAX_MAP_SOLID, but it is transparent, using + //! EMT_TRANSPARENT_VERTEX_ALPHA as base material. + EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, + + //! BlendFunc = source * sourceFactor + dest * destFactor ( E_BLEND_FUNC ) + //! Using only Textures[0]. generic Blender + EMT_ONETEXTURE_BLEND, + + //! This value is not used. It only forces this enumeration to compile in 32 bit. + EMT_FORCE_32BIT = 0x7fffffff + }; + + //! Array holding the built in material type names + const char* const sBuiltInMaterialTypeNames[] = + { + "solid", + "solid_2layer", + "lightmap", + "lightmap_add", + "lightmap_m2", + "lightmap_m4", + "lightmap_light", + "lightmap_light_m2", + "lightmap_light_m4", + "detail_map", + "sphere_map", + "reflection_2layer", + "trans_add", + "trans_alphach", + "trans_alphach_ref", + "trans_vertex_alpha", + "trans_reflection_2layer", + "normalmap_solid", + "normalmap_trans_add", + "normalmap_trans_vertexalpha", + "parallaxmap_solid", + "parallaxmap_trans_add", + "parallaxmap_trans_vertexalpha", + "onetexture_blend", + 0 + }; + +} // end namespace video +} // end namespace irr + + +#endif // __E_MATERIAL_TYPES_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/EMeshWriterEnums.h b/src/dep/include/irrlicht/EMeshWriterEnums.h new file mode 100644 index 0000000..8028ff4 --- /dev/null +++ b/src/dep/include/irrlicht/EMeshWriterEnums.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MESH_WRITER_ENUMS_H_INCLUDED__ +#define __E_MESH_WRITER_ENUMS_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all supported types of built-in mesh writers + /** A scene mesh writers is represented by a four character code + such as 'irrm' or 'coll' instead of simple numbers, to avoid + name clashes with external mesh writers.*/ + enum EMESH_WRITER_TYPE + { + //! Irrlicht Native mesh writer, for static .irrmesh files. + EMWT_IRR_MESH = MAKE_IRR_ID('i','r','r','m'), + + //! COLLADA mesh writer for .dae and .xml files + EMWT_COLLADA = MAKE_IRR_ID('c','o','l','l'), + + //! STL mesh writer for .stl files + EMWT_STL = MAKE_IRR_ID('s','t','l',0) + }; + + + //! flags configuring mesh writing + enum E_MESH_WRITER_FLAGS + { + //! no writer flags + EMWF_NONE = 0, + + //! write lightmap textures out if possible + EMWF_WRITE_LIGHTMAPS = 0x1, + + //! write in a way that does consume less disk space + EMWF_WRITE_COMPRESSED = 0x2 + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __E_MESH_WRITER_ENUMS_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/EMessageBoxFlags.h b/src/dep/include/irrlicht/EMessageBoxFlags.h new file mode 100644 index 0000000..636a135 --- /dev/null +++ b/src/dep/include/irrlicht/EMessageBoxFlags.h @@ -0,0 +1,35 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_MESSAGE_BOX_FLAGS_H_INCLUDED__ +#define __E_MESSAGE_BOX_FLAGS_H_INCLUDED__ + +namespace irr +{ +namespace gui +{ + +//! enumeration for message box layout flags +enum EMESSAGE_BOX_FLAG +{ + //! Flag for the ok button + EMBF_OK = 0x1, + + //! Flag for the cancel button + EMBF_CANCEL = 0x2, + + //! Flag for the yes button + EMBF_YES = 0x4, + + //! Flag for the no button + EMBF_NO = 0x8, + + //! This value is not used. It only forces this enumeration to compile in 32 bit. + EMBF_FORCE_32BIT = 0x7fffffff +}; + +} // namespace gui +} // namespace irr + +#endif diff --git a/src/dep/include/irrlicht/ESceneNodeAnimatorTypes.h b/src/dep/include/irrlicht/ESceneNodeAnimatorTypes.h new file mode 100644 index 0000000..4b9cbae --- /dev/null +++ b/src/dep/include/irrlicht/ESceneNodeAnimatorTypes.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_SCENE_NODE_ANIMATOR_TYPES_H_INCLUDED__ +#define __E_SCENE_NODE_ANIMATOR_TYPES_H_INCLUDED__ + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of built-in scene node animators + enum ESCENE_NODE_ANIMATOR_TYPE + { + //! Fly circle scene node animator + ESNAT_FLY_CIRCLE = 0, + + //! Fly straight scene node animator + ESNAT_FLY_STRAIGHT, + + //! Follow spline scene node animator + ESNAT_FOLLOW_SPLINE, + + //! Rotation scene node animator + ESNAT_ROTATION, + + //! Texture scene node animator + ESNAT_TEXTURE, + + //! Deletion scene node animator + ESNAT_DELETION, + + //! Collision respose scene node animator + ESNAT_COLLISION_RESPONSE, + + //! Amount of built-in scene node animators + ESNAT_COUNT, + + //! Unknown scene node animator + ESNAT_UNKNOWN, + + //! This enum is never used, it only forces the compiler to + //! compile these enumeration values to 32 bit. + ESNAT_FORCE_32_BIT = 0x7fffffff + }; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/ESceneNodeTypes.h b/src/dep/include/irrlicht/ESceneNodeTypes.h new file mode 100644 index 0000000..1e74161 --- /dev/null +++ b/src/dep/include/irrlicht/ESceneNodeTypes.h @@ -0,0 +1,89 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_SCENE_NODE_TYPES_H_INCLUDED__ +#define __E_SCENE_NODE_TYPES_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace scene +{ + + //! An enumeration for all types of built-in scene nodes + /** A scene node type is represented by a four character code + such as 'cube' or 'mesh' instead of simple numbers, to avoid + name clashes with external scene nodes.*/ + enum ESCENE_NODE_TYPE + { + //! simple cube scene node + ESNT_CUBE = MAKE_IRR_ID('c','u','b','e'), + + //! Sphere scene node + ESNT_SPHERE = MAKE_IRR_ID('s','p','h','r'), + + //! Text Scene Node + ESNT_TEXT = MAKE_IRR_ID('t','e','x','t'), + + //! Water Surface Scene Node + ESNT_WATER_SURFACE = MAKE_IRR_ID('w','a','t','r'), + + //! Terrain Scene Node + ESNT_TERRAIN = MAKE_IRR_ID('t','e','r','r'), + + //! Sky Box Scene Node + ESNT_SKY_BOX = MAKE_IRR_ID('s','k','y','_'), + + //! Shadow Volume Scene Node + ESNT_SHADOW_VOLUME = MAKE_IRR_ID('s','h','d','w'), + + //! OctTree Scene Node + ESNT_OCT_TREE = MAKE_IRR_ID('o','c','t','t'), + + //! Mesh Scene Node + ESNT_MESH = MAKE_IRR_ID('m','e','s','h'), + + //! Light Scene Node + ESNT_LIGHT = MAKE_IRR_ID('l','g','h','t'), + + //! Empty Scene Node + ESNT_EMPTY = MAKE_IRR_ID('e','m','t','y'), + + //! Dummy Transformation Scene Node + ESNT_DUMMY_TRANSFORMATION = MAKE_IRR_ID('d','m','m','y'), + + //! Camera Scene Node + ESNT_CAMERA = MAKE_IRR_ID('c','a','m','_'), + + //! Maya Camera Scene Node + ESNT_CAMERA_MAYA = MAKE_IRR_ID('c','a','m','M'), + + //! First Person Shooter style Camera + ESNT_CAMERA_FPS = MAKE_IRR_ID('c','a','m','F'), + + //! Billboard Scene Node + ESNT_BILLBOARD = MAKE_IRR_ID('b','i','l','l'), + + //! Animated Mesh Scene Node + ESNT_ANIMATED_MESH = MAKE_IRR_ID('a','m','s','h'), + + //! Particle System Scene Node + ESNT_PARTICLE_SYSTEM = MAKE_IRR_ID('p','t','c','l'), + + //! Quake3 Model Scene Node ( has tag to link to ) + ESNT_MD3_SCENE_NODE = MAKE_IRR_ID('m','d','3','_'), + + //! Unknown scene node + ESNT_UNKNOWN = MAKE_IRR_ID('u','n','k','n') + }; + + + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/ETerrainElements.h b/src/dep/include/irrlicht/ETerrainElements.h new file mode 100644 index 0000000..9644d78 --- /dev/null +++ b/src/dep/include/irrlicht/ETerrainElements.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __E_TERRAIN_ELEMENTS_H__ +#define __E_TERRAIN_ELEMENTS_H__ + +namespace irr +{ +namespace scene +{ + + //! enumeration for patch sizes specifying the size of patches in the TerrainSceneNode + enum E_TERRAIN_PATCH_SIZE + { + //! patch size of 9, at most, use 4 levels of detail with this patch size. + ETPS_9 = 9, + + //! patch size of 17, at most, use 5 levels of detail with this patch size. + ETPS_17 = 17, + + //! patch size of 33, at most, use 6 levels of detail with this patch size. + ETPS_33 = 33, + + //! patch size of 65, at most, use 7 levels of detail with this patch size. + ETPS_65 = 65, + + //! patch size of 129, at most, use 8 levels of detail with this patch size. + ETPS_129 = 129 + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAnimatedMesh.h b/src/dep/include/irrlicht/IAnimatedMesh.h new file mode 100644 index 0000000..6d11e5f --- /dev/null +++ b/src/dep/include/irrlicht/IAnimatedMesh.h @@ -0,0 +1,103 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_H_INCLUDED__ +#define __I_ANIMATED_MESH_H_INCLUDED__ + +#include "aabbox3d.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + + enum E_ANIMATED_MESH_TYPE + { + //! Unknown animated mesh type. + EAMT_UNKNOWN = 0, + + //! Quake 2 MD2 model file + EAMT_MD2, + + //! Quake 3 MD3 model file + EAMT_MD3, + + //! Maya .obj static model + EAMT_OBJ, + + //! Quake 3 .bsp static Map + EAMT_BSP, + + //! 3D Studio .3ds file + EAMT_3DS, + + //! My3D Mesh, the file format by Zhuck Dimitry + EAMT_MY3D, + + //! Pulsar LMTools .lmts file. This Irrlicht loader was + //! written by Jonas Petersen + EAMT_LMTS, + + //! Cartography Shop .csm file. This loader was created by Saurav Mohapatra. + EAMT_CSM, + + //! .oct file for Paul Nette's FSRad or from Murphy McCauley's + //! Blender .oct exporter. The oct file format contains 3D + //! geometry and lightmaps and can be loaded directly by Irrlicht + EAMT_OCT, + + //! generic skinned mesh + EAMT_SKINNED + }; + + //! Interface for an animated mesh. + /** There are already simple implementations of this interface available so + you don't have to implement this interface on your own if you need to: + You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh, + irr::scene::SMeshBuffer etc. */ + class IAnimatedMesh : public IMesh + { + public: + + //! destructor + virtual ~IAnimatedMesh() { } + + //! Gets the frame count of the animated mesh. + /** \return Returns the amount of frames. If the amount is 1, + it is a static, non animated mesh. */ + virtual u32 getFrameCount() const = 0; + + //! Returns the IMesh interface for a frame. + /** \param frame: Frame number as zero based index. The maximum + frame number is getFrameCount() - 1; + \param detailLevel: Level of detail. 0 is the lowest, 255 the + highest level of detail. Most meshes will ignore the detail level. + \param startFrameLoop: Because some animated meshes (.MD2) are + blended between 2 static frames, and maybe animated in a loop, + the startFrameLoop and the endFrameLoop have to be defined, to + prevent the animation to be blended between frames which are + outside of this loop. + If startFrameLoop and endFrameLoop are both -1, they are ignored. + \param endFrameLoop: see startFrameLoop. + \return Returns the animated mesh based on a detail level. */ + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1) = 0; + + //! Returns the type of the animated mesh. + /** In most cases it is not neccessary to use this method. + This is useful for making a safe downcast. For example, + if getMeshType() returns EAMT_MD2 it's safe to cast the + IAnimatedMesh to IAnimatedMeshMD2. + \returns Type of the mesh. */ + virtual E_ANIMATED_MESH_TYPE getMeshType() const + { + return EAMT_UNKNOWN; + } + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAnimatedMeshMD2.h b/src/dep/include/irrlicht/IAnimatedMeshMD2.h new file mode 100644 index 0000000..f61848b --- /dev/null +++ b/src/dep/include/irrlicht/IAnimatedMeshMD2.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_MD2_H_INCLUDED__ +#define __I_ANIMATED_MESH_MD2_H_INCLUDED__ + +#include "IAnimatedMesh.h" + +namespace irr +{ +namespace scene +{ + + //! Types of standard md2 animations + enum EMD2_ANIMATION_TYPE + { + EMAT_STAND = 0, + EMAT_RUN, + EMAT_ATTACK, + EMAT_PAIN_A, + EMAT_PAIN_B, + EMAT_PAIN_C, + EMAT_JUMP, + EMAT_FLIP, + EMAT_SALUTE, + EMAT_FALLBACK, + EMAT_WAVE, + EMAT_POINT, + EMAT_CROUCH_STAND, + EMAT_CROUCH_WALK, + EMAT_CROUCH_ATTACK, + EMAT_CROUCH_PAIN, + EMAT_CROUCH_DEATH, + EMAT_DEATH_FALLBACK, + EMAT_DEATH_FALLFORWARD, + EMAT_DEATH_FALLBACKSLOW, + EMAT_BOOM, + + //! Not an animation, but amount of animation types. + EMAT_COUNT + }; + + //! Interface for using some special functions of MD2 meshes + class IAnimatedMeshMD2 : public IAnimatedMesh + { + public: + + // Get frame loop data for a default MD2 animation type. + //! \param l: The EMD2_ANIMATION_TYPE to get the frames for. + //! \param outBegin: The returned beginning frame for animation type specified. + //! \param outEnd: The returned ending frame for the animation type specified. + //! \param outFPS: The number of frames per second, this animation should be played at. + //! \return Returns the beginframe, endframe and frames per second for a default MD2 animation type. + virtual void getFrameLoop(EMD2_ANIMATION_TYPE l, s32& outBegin, + s32& outEnd, s32& outFPS) const = 0; + + // Get frame loop data for a special MD2 animation type, identified by name. + //! \param name: Name of the animation. + //! \param outBegin: The returned beginning frame for animation type specified. + //! \param outEnd: The returned ending frame for the animation type specified. + //! \param outFPS: The number of frames per second, this animation should be played at. + //! \return Returns the beginframe, endframe and frames per second for a special MD2 animation type. + virtual bool getFrameLoop(const c8* name, + s32& outBegin, s32& outEnd, s32& outFPS) const = 0; + + //! Returns amount of md2 animations in this file. + virtual s32 getAnimationCount() const = 0; + + //! Returns name of md2 animation. + //! \param nr: Zero based index of animation. + virtual const c8* getAnimationName(s32 nr) const = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAnimatedMeshMD3.h b/src/dep/include/irrlicht/IAnimatedMeshMD3.h new file mode 100644 index 0000000..8250f93 --- /dev/null +++ b/src/dep/include/irrlicht/IAnimatedMeshMD3.h @@ -0,0 +1,258 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_MD3_H_INCLUDED__ +#define __I_ANIMATED_MESH_MD3_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IQ3Shader.h" +#include "quaternion.h" + +namespace irr +{ +namespace scene +{ + + enum eMD3Models + { + EMD3_HEAD = 0, + EMD3_UPPER, + EMD3_LOWER, + EMD3_WEAPON, + EMD3_NUMMODELS + }; + + + // Animation list + enum EMD3_ANIMATION_TYPE + { + // Animations for both lower and upper parts of the player + EMD3_BOTH_DEATH_1 = 0, + EMD3_BOTH_DEAD_1, + EMD3_BOTH_DEATH_2, + EMD3_BOTH_DEAD_2, + EMD3_BOTH_DEATH_3, + EMD3_BOTH_DEAD_3, + + // Animations for the upper part + EMD3_TORSO_GESTURE, + EMD3_TORSO_ATTACK_1, + EMD3_TORSO_ATTACK_2, + EMD3_TORSO_DROP, + EMD3_TORSO_RAISE, + EMD3_TORSO_STAND_1, + EMD3_TORSO_STAND_2, + + // Animations for the lower part + EMD3_LEGS_WALK_CROUCH, + EMD3_LEGS_WALK, + EMD3_LEGS_RUN, + EMD3_LEGS_BACK, + EMD3_LEGS_SWIM, + EMD3_LEGS_JUMP_1, + EMD3_LEGS_LAND_1, + EMD3_LEGS_JUMP_2, + EMD3_LEGS_LAND_2, + EMD3_LEGS_IDLE, + EMD3_LEGS_IDLE_CROUCH, + EMD3_LEGS_TURN, + + //! Not an animation, but amount of animation types. + EMD3_ANIMATION_COUNT + }; + + struct SMD3AnimationInfo + { + s32 first; // First frame + s32 num; // Last frame + s32 looping; // Looping frames + s32 fps; // Frames per second + }; + + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + // this holds the header info of the MD3 file + struct SMD3Header + { + c8 headerID[4]; //id of file, always "IDP3" + s32 Version; //this is a version number, always 15 + s8 fileName[68]; //sometimes left Blank... 65 chars, 32bit aligned == 68 chars + s32 numFrames; //number of KeyFrames + s32 numTags; //number of 'tags' per frame + s32 numMeshes; //number of meshes/skins + s32 numMaxSkins; //maximum number of unique skins used in md3 file + s32 headerSize; //always equal to the length of this header + s32 tagStart; //starting position of tag-structures + s32 tagEnd; //ending position of tag-structures/starting position of mesh-structures + s32 fileSize; + }; + + struct SMD3MeshHeader + { + c8 meshID[4]; //id, must be IDP3 + c8 meshName[68]; //name of mesh 65 chars, 32 bit aligned == 68 chars + + s32 numFrames; //number of meshframes in mesh + s32 numShader; //number of skins in mesh + s32 numVertices; //number of vertices + s32 numTriangles; //number of Triangles + + s32 offset_triangles; //starting position of Triangle data, relative to start of Mesh_Header + s32 offset_shaders; //size of header + s32 offset_st; //starting position of texvector data, relative to start of Mesh_Header + s32 vertexStart; //starting position of vertex data,relative to start of Mesh_Header + s32 offset_end; + }; + + + //! Compressed Vertex Data + struct SMD3Vertex + { + s16 position[3]; + u8 normal[2]; + }; + + //! Texure Coordinate + struct SMD3TexCoord + { + f32 u; + f32 v; + }; + + //! Triangle Index + struct SMD3Face + { + s32 Index[3]; + }; + + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + //! Holding Frame Data for a Mesh + struct SMD3MeshBuffer : public IReferenceCounted + { + SMD3MeshHeader MeshHeader; + + core::array < core::stringc > Shader; + core::array < s32 > Indices; + core::array < SMD3Vertex > Vertices; + core::array < SMD3TexCoord > Tex; + }; + + //! hold a tag info for connecting meshes + //! basically its an alternate way to describe a transformation + struct SMD3QuaterionTag + { + SMD3QuaterionTag() {} + + SMD3QuaterionTag( const core::stringc& name ) + : Name ( name ) {} + + // construct from a matrix + SMD3QuaterionTag ( const core::stringc& name, const core::matrix4 &m ) + { + Name = name; + position = m.getTranslation (); + rotation = m; + } + + // set to matrix + void setto ( core::matrix4 &m ) + { + rotation.getMatrix ( m ); + m.setTranslation ( position ); + } + + // construct from a position and euler angles in degrees + SMD3QuaterionTag ( const core::vector3df &pos, const core::vector3df &angle ) + { + position = pos; + rotation.set ( angle * core::DEGTORAD ); + } + + bool operator == ( const SMD3QuaterionTag &other ) const + { + return Name == other.Name; + } + + core::stringc Name; + core::vector3df position; + core::quaternion rotation; + }; + + // holds a assoziative list of named quaternions + struct SMD3QuaterionTagList : public virtual IReferenceCounted + { + SMD3QuaterionTag* get ( const core::stringc& name ) + { + SMD3QuaterionTag search ( name ); + s32 index = Container.linear_search ( search ); + if ( index >= 0 ) + return &Container[index]; + return 0; + } + + u32 size () const + { + return Container.size(); + } + + SMD3QuaterionTag& operator[] (u32 index ) + { + return Container[index]; + } + + core::array < SMD3QuaterionTag > Container; + }; + + + //! Holding Frames Buffers and Tag Infos + struct SMD3Mesh: public IReferenceCounted + { + ~SMD3Mesh() + { + for (u32 i=0; idrop(); + }; + + SMD3Header MD3Header; + core::stringc Name; + core::array < SMD3MeshBuffer * > Buffer; + SMD3QuaterionTagList TagList; + }; + + + //! Interface for using some special functions of MD3 meshes + class IAnimatedMeshMD3 : public IAnimatedMesh + { + public: + + //! tune how many frames you want to render inbetween + virtual void setInterpolationShift ( u32 shift, u32 loopMode ) = 0; + + virtual SMD3QuaterionTagList *getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) = 0; + + virtual SMD3Mesh * getOriginalMesh () = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAnimatedMeshSceneNode.h b/src/dep/include/irrlicht/IAnimatedMeshSceneNode.h new file mode 100644 index 0000000..8b855d4 --- /dev/null +++ b/src/dep/include/irrlicht/IAnimatedMeshSceneNode.h @@ -0,0 +1,213 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ +#define __I_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IBoneSceneNode.h" +#include "IAnimatedMeshMD2.h" +#include "IAnimatedMeshMD3.h" +#include "IShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + + + enum E_JOINT_UPDATE_ON_RENDER + { + // do nothing + EJUOR_NONE = 0, + + // get joints positions from the mesh (for attached nodes, etc) + EJUOR_READ, + + // control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() ) + EJUOR_CONTROL, + + //! count of all available interpolation modes + EJUOR_COUNT + }; + + + + class IAnimatedMeshSceneNode; + + //! Callback interface for catching events of ended animations. + /** Implement this interface and use + IAnimatedMeshSceneNode::setAnimationEndCallback to be able to + be notified if an animation playback has ended. + **/ + class IAnimationEndCallBack : public virtual IReferenceCounted + { + public: + + //! Will be called when the animation playback has ended. + //! See IAnimatedMeshSceneNode::setAnimationEndCallback for + //! more informations. + //! \param node: Node of which the animation has ended. + virtual void OnAnimationEnd(IAnimatedMeshSceneNode* node) = 0; + }; + + //! Scene node capable of displaying an animated mesh and its shadow. + /** The shadow is optional: If a shadow should be displayed too, just invoke + the IAnimatedMeshSceneNode::createShadowVolumeSceneNode().*/ + class IAnimatedMeshSceneNode : public ISceneNode + { + public: + + //! Constructor + IAnimatedMeshSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Destructor + virtual ~IAnimatedMeshSceneNode() {} + + //! Sets the current frame number. + //! From now on the animation is played from this frame. + //! \param frame: Number of the frame to let the animation be started from. + //! The frame number must be a valid frame number of the IMesh used by this + //! scene node. Set IAnimatedMesh::getMesh() for details. + virtual void setCurrentFrame(f32 frame) = 0; + + //! Sets the frame numbers between the animation is looped. + //! The default is 0 - MaximalFrameCount of the mesh. + //! \param begin: Start frame number of the loop. + //! \param end: End frame number of the loop. + //! \return Returns true if successful, false if not. + virtual bool setFrameLoop(s32 begin, s32 end) = 0; + + //! Sets the speed with witch the animation is played. + //! \param framesPerSecond: Frames per second played. + virtual void setAnimationSpeed(f32 framesPerSecond) = 0; + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. The shadow can be rendered using the ZPass + //! or the zfail method. ZPass is a little bit faster because the shadow volume + //! creation is easier, but with this method there occur ugly looking artifacs + //! when the camera is inside the shadow volume. These error do not occur + //! with the ZFail method. + //! \param id: Id of the shadow scene node. This id can be used to identify + //! the node later. + //! \param zfailmethod: If set to true, the shadow will use the zfail method, + //! if not, zpass is used. + //! \param infinity: Value used by the shadow volume algorithm to scale the + //! shadow volume. + //! \return Returns pointer to the created shadow scene node. + //! This pointer should not be dropped. See IReferenceCounted::drop() for more information. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id=-1, + bool zfailmethod=true, f32 infinity=10000.0f) = 0; + + + //! Returns a pointer to a joint in the mesh (if the mesh is a bone based mesh) + //! With this method it is possible to attach scene nodes to joints + //! for example possible to attach a weapon to the left hand of an + //! animated model. This example shows how: + //! \code + //! ISceneNode* hand = + //! yourAnimatedMeshSceneNode->getJointNode("LeftHand"); + //! hand->addChild(weaponSceneNode); + //! \endcode + //! Please note that the joint returned by this method may not exist + //! before this call and the joints in the node were created by it. + //! \param jointName: Name of the joint. + //! \return Returns a pointer to the scene node which represents the joint + //! with the specified name. Returns 0 if the contained mesh is not an + //! skinned mesh or the name of the joint could not be found. + virtual IBoneSceneNode* getJointNode(const c8* jointName)=0; + + //! same as getJointNode(const c8* jointName), but based on id + virtual IBoneSceneNode* getJointNode(u32 jointID) = 0; + + //! Redundant command, please use getJointNode (only for backwards compatibility) + virtual ISceneNode* getMS3DJointNode(const c8* jointName) = 0; + + //! Redundant command, please use getJointNode (only for backwards compatibility) + virtual ISceneNode* getXJointNode(const c8* jointName) = 0; + + //! Starts a default MD2 animation. + //! With this method it is easily possible to start a Run, Attack, + //! Die or whatever animation, if the mesh contained in this scene + //! node is an md2 mesh. Otherwise, nothing happens. + //! \param anim: An MD2 animation type, which should be played, for + //! example EMAT_STAND for the standing animation. + //! \return Returns true if successful, and false if not, for example + //! if the mesh in the scene node is not a md2 mesh. + virtual bool setMD2Animation(EMD2_ANIMATION_TYPE anim) = 0; + + //! Starts a special MD2 animation. + //! With this method it is easily possible to start a Run, Attack, + //! Die or whatever animation, if the mesh contained in this scene + //! node is an md2 mesh. Otherwise, nothing happens. This method uses + //! a character string to identify the animation. If the animation is a + //! standard md2 animation, you might want to start this animation + //! with the EMD2_ANIMATION_TYPE enumeration instead. + //! \param animationName: Name of the animation which should be played. + //! \return Returns true if successful, and false if not, for example + //! if the mesh in the scene node is not an md2 mesh, or no animation + //! with this name could be found. + virtual bool setMD2Animation(const c8* animationName) = 0; + + //! Returns the current displayed frame number. + virtual f32 getFrameNr() const = 0; + //! Returns the current start frame number. + virtual s32 getStartFrame() const = 0; + //! Returns the current end frame number. + virtual s32 getEndFrame() const = 0; + + //! Sets looping mode which is on by default. If set to false, + //! animations will not be played looped. + virtual void setLoopMode(bool playAnimationLooped) = 0; + + //! Sets a callback interface which will be called if an animation + //! playback has ended. Set this to 0 to disable the callback again. + //! Please note that this will only be called when in non looped mode, + //! see IAnimatedMeshSceneNode::setLoopMode(). + virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0) = 0; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly) = 0; + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const = 0; + + //! Sets a new mesh + virtual void setMesh(IAnimatedMesh* mesh) = 0; + + //! Returns the current mesh + virtual IAnimatedMesh* getMesh(void) = 0; + + //! returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, + //! or the absolutetransformation if it's a normal scenenode + virtual const SMD3QuaterionTag& getMD3TagTransformation( const core::stringc & tagname) = 0; + + //! Set how the joints should be updated on render + //! 0-do nothing + //! 1-get joints positions from the mesh (for attached nodes, etc) + //! 2-control joint positions in the mesh (eg. ragdolls, or set the animation from animateJoints() ) + virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode)=0; + + //! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) + //! you must call animateJoints(), or the mesh will not ani\mate + virtual void setTransitionTime(f32 Time) =0; + + //! animates the joints in the mesh based on the current frame (also takes in to account transitions) + virtual void animateJoints(bool CalculateAbsolutePositions=true) = 0; + + //! render mesh ignoring it's transformation. Used with ragdolls. (culling is unaffected) + virtual void setRenderFromIdentity( bool On )=0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAttributeExchangingObject.h b/src/dep/include/irrlicht/IAttributeExchangingObject.h new file mode 100644 index 0000000..534cc74 --- /dev/null +++ b/src/dep/include/irrlicht/IAttributeExchangingObject.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ATTRIBUTE_EXCHANGING_OBJECT_H_INCLUDED__ +#define __I_ATTRIBUTE_EXCHANGING_OBJECT_H_INCLUDED__ + +#include "IReferenceCounted.h" + + +namespace irr +{ + +namespace io +{ + +class IAttributes; + +//! Enumation flags passed through SAttributeReadWriteOptions to the IAttributeExchangingObject object +enum E_ATTRIBUTE_READ_WRITE_FLAGS +{ + //! Serialization/Deserializion is done for an xml file + EARWF_FOR_FILE = 0x00000001, + + //! Serialization/Deserializion is done for an editor property box + EARWF_FOR_EDITOR = 0x00000002, + + //! When writing filenames, relative paths should be used + EARWF_USE_RELATIVE_PATHS = 0x00000004 +}; + + +//! struct holding data describing options +struct SAttributeReadWriteOptions +{ + //! constructor + SAttributeReadWriteOptions() + : Flags(0), Filename(0) + { + } + + //! Combination of E_ATTRIBUTE_READ_WRITE_FLAGS or other, custom ones + s32 Flags; + + //! optional filename + const c8* Filename; +}; + + +//! An object which is able to serialize and deserialize its attributes into an attributes object +class IAttributeExchangingObject : public virtual IReferenceCounted +{ +public: + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {} + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) {} + +}; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IAttributes.h b/src/dep/include/irrlicht/IAttributes.h new file mode 100644 index 0000000..96baf28 --- /dev/null +++ b/src/dep/include/irrlicht/IAttributes.h @@ -0,0 +1,753 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ATTRIBUTES_H_INCLUDED__ +#define __I_ATTRIBUTES_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SColor.h" +#include "vector3d.h" +#include "vector2d.h" +#include "line2d.h" +#include "line3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "rect.h" +#include "matrix4.h" +#include "quaternion.h" +#include "plane3d.h" +#include "triangle3d.h" +#include "line2d.h" +#include "line3d.h" +#include "irrString.h" +#include "irrArray.h" +#include "IXMLReader.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} // end namespace video +namespace io +{ + class IXMLWriter; + +//! Types of attributes available for IAttributes +enum E_ATTRIBUTE_TYPE +{ + // integer attribute + EAT_INT = 0, + + // float attribute + EAT_FLOAT, + + // string attribute + EAT_STRING, + + // boolean attribute + EAT_BOOL, + + // enumeration attribute + EAT_ENUM, + + // color attribute + EAT_COLOR, + + // floating point color attribute + EAT_COLORF, + + // 3d vector attribute + EAT_VECTOR3D, + + // 2d position attribute + EAT_POSITION2D, + + // vector 2d + EAT_VECTOR2D, + + // rectangle attribute + EAT_RECT, + + // matrix attribute + EAT_MATRIX, + + // quaternion attribute + EAT_QUATERNION, + + // 3d bounding box + EAT_BBOX, + + // plane + EAT_PLANE, + + // 3d triangle + EAT_TRIANGLE3D, + + // line 2d + EAT_LINE2D, + + // line 3d + EAT_LINE3D, + + // array of stringws attribute + EAT_STRINGWARRAY, + + // array of float + EAT_FLOATARRAY, + + // array of int + EAT_INTARRAY, + + // binary data attribute + EAT_BINARY, + + // texture reference attribute + EAT_TEXTURE, + + // user pointer void* + EAT_USER_POINTER, + + // known attribute type count + EAT_COUNT, + + // unknown attribute + EAT_UNKNOWN +}; + +//! Provides a generic interface for attributes and their values and the possiblity to serialize them +class IAttributes : public virtual IReferenceCounted +{ +public: + + //! Returns amount of attributes in this collection of attributes. + virtual u32 getAttributeCount() const = 0; + + //! Returns attribute name by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeName(s32 index) = 0; + + //! Returns the type of an attribute + //! \param attributeName: Name for the attribute + virtual E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName) = 0; + + //! Returns attribute type by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual E_ATTRIBUTE_TYPE getAttributeType(s32 index) = 0; + + //! Returns the type string of the attribute + //! \param attributeName: String for the attribute type + virtual const wchar_t* getAttributeTypeString(const c8* attributeName) = 0; + + //! Returns the type string of the attribute by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const wchar_t* getAttributeTypeString(s32 index) = 0; + + //! Returns if an attribute with a name exists + virtual bool existsAttribute(const c8* attributeName) = 0; + + //! Returns attribute index from name, -1 if not found + virtual s32 findAttribute(const c8* attributeName) = 0; + + //! Removes all attributes + virtual void clear() = 0; + + //! Reads attributes from a xml file. + //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes' or + //! the name specified using elementName. + //! \param elementName: The surrounding element name. If it is null, the default one, "attributes" will be taken. + //! If set to false, the first appearing list of attributes are read. + virtual bool read(io::IXMLReader* reader, bool readCurrentElementOnly=false, const wchar_t* elementName=0) = 0; + + //! Write these attributes into a xml file + //! \param writer: The XML writer to write to + //! \param writeXMLHeader: Writes a header to the XML file, required if at the beginning of the file + //! \param elementName: The surrounding element name. If it is null, the default one, "attributes" will be taken. + virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* elementName=0) = 0; + + + /* + + Integer Attribute + + */ + + //! Adds an attribute as integer + virtual void addInt(const c8* attributeName, s32 value) = 0; + + //! Sets an attribute as integer value + virtual void setAttribute(const c8* attributeName, s32 value) = 0; + + //! Gets an attribute as integer value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsInt(const c8* attributeName) = 0; + + //! Gets an attribute as integer value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsInt(s32 index) = 0; + + //! Sets an attribute as integer value + virtual void setAttribute(s32 index, s32 value) = 0; + + /* + + Float Attribute + + */ + + //! Adds an attribute as float + virtual void addFloat(const c8* attributeName, f32 value) = 0; + + //! Sets a attribute as float value + virtual void setAttribute(const c8* attributeName, f32 value) = 0; + + //! Gets an attribute as float value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual f32 getAttributeAsFloat(const c8* attributeName) = 0; + + //! Gets an attribute as float value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual f32 getAttributeAsFloat(s32 index) = 0; + + //! Sets an attribute as float value + virtual void setAttribute(s32 index, f32 value) = 0; + + /* + + String Attribute + + */ + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const c8* value) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const c8* value) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringc getAttributeAsString(const c8* attributeName) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsString(const c8* attributeName, c8* target) = 0; + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringc getAttributeAsString(s32 index) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const c8* value) = 0; + + // wide strings + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const wchar_t* value) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const wchar_t* value) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringw getAttributeAsStringW(const c8* attributeName) = 0; + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsStringW(const c8* attributeName, wchar_t* target) = 0; + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringw getAttributeAsStringW(s32 index) = 0; + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const wchar_t* value) = 0; + + /* + + Binary Data Attribute + + */ + + //! Adds an attribute as binary data + virtual void addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes) = 0; + + //! Sets an attribute as binary data + virtual void setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes ) = 0; + + //! Gets an attribute as binary data + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes) = 0; + + //! Gets an attribute as binary data + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes) = 0; + + //! Sets an attribute as binary data + virtual void setAttribute(s32 index, void* data, s32 dataSizeInBytes ) = 0; + + + /* + + Array Attribute + + */ + + //! Adds an attribute as wide string array + virtual void addArray(const c8* attributeName, core::array value) = 0; + + //! Sets an attribute value as a wide string array. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const core::array value) = 0; + + //! Gets an attribute as an array of wide strings. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::array getAttributeAsArray(const c8* attributeName) = 0; + + //! Returns attribute value as an array of wide strings by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::array getAttributeAsArray(s32 index) = 0; + + //! Sets an attribute as an array of wide strings + virtual void setAttribute(s32 index, core::array value) = 0; + + + /* + + Bool Attribute + + */ + + //! Adds an attribute as bool + virtual void addBool(const c8* attributeName, bool value) = 0; + + //! Sets an attribute as boolean value + virtual void setAttribute(const c8* attributeName, bool value) = 0; + + //! Gets an attribute as boolean value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual bool getAttributeAsBool(const c8* attributeName) = 0; + + //! Gets an attribute as boolean value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual bool getAttributeAsBool(s32 index) = 0; + + //! Sets an attribute as boolean value + virtual void setAttribute(s32 index, bool value) = 0; + + /* + + Enumeration Attribute + + */ + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, s32 enumValue, const c8* const* enumerationLiterals) = 0; + + //! Sets an attribute as enumeration + virtual void setAttribute(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual const c8* getAttributeAsEnumeration(const c8* attributeName) = 0; + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \param enumerationLiteralsToUse: Use these enumeration literals to get the index value instead of the set ones. + //! This is useful when the attribute list maybe was read from an xml file, and only contains the enumeration string, but + //! no information about its index. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsEnumeration(const c8* attributeName, const c8* const* enumerationLiteralsToUse) = 0; + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsEnumeration(s32 index, const c8* const* enumerationLiteralsToUse) = 0; + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeAsEnumeration(s32 index) = 0; + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array& outLiterals) = 0; + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array& outLiterals) = 0; + + //! Sets an attribute as enumeration + virtual void setAttribute(s32 index, const c8* enumValue, const c8* const* enumerationLiterals) = 0; + + + /* + + SColor Attribute + + */ + + //! Adds an attribute as color + virtual void addColor(const c8* attributeName, video::SColor value) = 0; + + + //! Sets a attribute as color + virtual void setAttribute(const c8* attributeName, video::SColor color) = 0; + + //! Gets an attribute as color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColor getAttributeAsColor(const c8* attributeName) = 0; + + //! Gets an attribute as color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColor getAttributeAsColor(s32 index) = 0; + + //! Sets an attribute as color + virtual void setAttribute(s32 index, video::SColor color) = 0; + + /* + + SColorf Attribute + + */ + + //! Adds an attribute as floating point color + virtual void addColorf(const c8* attributeName, video::SColorf value) = 0; + + //! Sets a attribute as floating point color + virtual void setAttribute(const c8* attributeName, video::SColorf color) = 0; + + //! Gets an attribute as floating point color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColorf getAttributeAsColorf(const c8* attributeName) = 0; + + //! Gets an attribute as floating point color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColorf getAttributeAsColorf(s32 index) = 0; + + //! Sets an attribute as floating point color + virtual void setAttribute(s32 index, video::SColorf color) = 0; + + + /* + + Vector3d Attribute + + */ + + //! Adds an attribute as 3d vector + virtual void addVector3d(const c8* attributeName, core::vector3df value) = 0; + + //! Sets a attribute as 3d vector + virtual void setAttribute(const c8* attributeName, core::vector3df v) = 0; + + //! Gets an attribute as 3d vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector3df getAttributeAsVector3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d vector + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector3df getAttributeAsVector3d(s32 index) = 0; + + //! Sets an attribute as vector + virtual void setAttribute(s32 index, core::vector3df v) = 0; + + /* + + Position2d Attribute + + */ + + //! Adds an attribute as 2d position + virtual void addPosition2d(const c8* attributeName, core::position2di value) = 0; + + //! Sets a attribute as 2d position + virtual void setAttribute(const c8* attributeName, core::position2di v) = 0; + + //! Gets an attribute as position + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::position2di getAttributeAsPosition2d(const c8* attributeName) = 0; + + //! Gets an attribute as position + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::position2di getAttributeAsPosition2d(s32 index) = 0; + + //! Sets an attribute as 2d position + virtual void setAttribute(s32 index, core::position2di v) = 0; + + /* + + Rectangle Attribute + + */ + + //! Adds an attribute as rectangle + virtual void addRect(const c8* attributeName, core::rect value) = 0; + + //! Sets an attribute as rectangle + virtual void setAttribute(const c8* attributeName, core::rect v) = 0; + + //! Gets an attribute as rectangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::rect getAttributeAsRect(const c8* attributeName) = 0; + + //! Gets an attribute as rectangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::rect getAttributeAsRect(s32 index) = 0; + + //! Sets an attribute as rectangle + virtual void setAttribute(s32 index, core::rect v) = 0; + + + /* + + matrix attribute + + */ + + //! Adds an attribute as matrix + virtual void addMatrix(const c8* attributeName, const core::matrix4& v) = 0; + + //! Sets an attribute as matrix + virtual void setAttribute(const c8* attributeName, const core::matrix4& v) = 0; + + //! Gets an attribute as a matrix4 + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::matrix4 getAttributeAsMatrix(const c8* attributeName) = 0; + + //! Gets an attribute as matrix + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::matrix4 getAttributeAsMatrix(s32 index) = 0; + + //! Sets an attribute as matrix + virtual void setAttribute(s32 index, const core::matrix4& v) = 0; + + /* + quaternion attribute + + */ + + //! Adds an attribute as quaternion + virtual void addQuaternion(const c8* attributeName, core::quaternion v) = 0; + + //! Sets an attribute as quaternion + virtual void setAttribute(const c8* attributeName, core::quaternion v) = 0; + + //! Gets an attribute as a quaternion + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::quaternion getAttributeAsQuaternion(const c8* attributeName) = 0; + + //! Gets an attribute as quaternion + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::quaternion getAttributeAsQuaternion(s32 index) = 0; + + //! Sets an attribute as quaternion + virtual void setAttribute(s32 index, core::quaternion v) = 0; + + /* + + 3d bounding box + + */ + + //! Adds an attribute as axis aligned bounding box + virtual void addBox3d(const c8* attributeName, core::aabbox3df v) = 0; + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(const c8* attributeName, core::aabbox3df v) = 0; + + //! Gets an attribute as a axis aligned bounding box + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::aabbox3df getAttributeAsBox3d(const c8* attributeName) = 0; + + //! Gets an attribute as axis aligned bounding box + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::aabbox3df getAttributeAsBox3d(s32 index) = 0; + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(s32 index, core::aabbox3df v) = 0; + + /* + + plane + + */ + + //! Adds an attribute as 3d plane + virtual void addPlane3d(const c8* attributeName, core::plane3df v) = 0; + + //! Sets an attribute as 3d plane + virtual void setAttribute(const c8* attributeName, core::plane3df v) = 0; + + //! Gets an attribute as a 3d plane + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::plane3df getAttributeAsPlane3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d plane + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::plane3df getAttributeAsPlane3d(s32 index) = 0; + + //! Sets an attribute as 3d plane + virtual void setAttribute(s32 index, core::plane3df v) = 0; + + + /* + + 3d triangle + + */ + + //! Adds an attribute as 3d triangle + virtual void addTriangle3d(const c8* attributeName, core::triangle3df v) = 0; + + //! Sets an attribute as 3d trianle + virtual void setAttribute(const c8* attributeName, core::triangle3df v) = 0; + + //! Gets an attribute as a 3d triangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::triangle3df getAttributeAsTriangle3d(const c8* attributeName) = 0; + + //! Gets an attribute as 3d triangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::triangle3df getAttributeAsTriangle3d(s32 index) = 0; + + //! Sets an attribute as 3d triangle + virtual void setAttribute(s32 index, core::triangle3df v) = 0; + + + /* + + line 2d + + */ + + //! Adds an attribute as a 2d line + virtual void addLine2d(const c8* attributeName, core::line2df v) = 0; + + //! Sets an attribute as a 2d line + virtual void setAttribute(const c8* attributeName, core::line2df v) = 0; + + //! Gets an attribute as a 2d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line2df getAttributeAsLine2d(const c8* attributeName) = 0; + + //! Gets an attribute as a 2d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line2df getAttributeAsLine2d(s32 index) = 0; + + //! Sets an attribute as a 2d line + virtual void setAttribute(s32 index, core::line2df v) = 0; + + + /* + + line 3d + + */ + + //! Adds an attribute as a 3d line + virtual void addLine3d(const c8* attributeName, core::line3df v) = 0; + + //! Sets an attribute as a 3d line + virtual void setAttribute(const c8* attributeName, core::line3df v) = 0; + + //! Gets an attribute as a 3d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line3df getAttributeAsLine3d(const c8* attributeName) = 0; + + //! Gets an attribute as a 3d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line3df getAttributeAsLine3d(s32 index) = 0; + + //! Sets an attribute as a 3d line + virtual void setAttribute(s32 index, core::line3df v) = 0; + + + /* + + Texture Attribute + + */ + + //! Adds an attribute as texture reference + virtual void addTexture(const c8* attributeName, video::ITexture* texture) = 0; + + //! Sets an attribute as texture reference + virtual void setAttribute(const c8* attributeName, video::ITexture* texture ) = 0; + + //! Gets an attribute as texture reference + //! \param attributeName: Name of the attribute to get. + virtual video::ITexture* getAttributeAsTexture(const c8* attributeName) = 0; + + //! Gets an attribute as texture reference + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::ITexture* getAttributeAsTexture(s32 index) = 0; + + //! Sets an attribute as texture reference + virtual void setAttribute(s32 index, video::ITexture* texture) = 0; + + + /* + + User Pointer Attribute + + */ + + //! Adds an attribute as user pointner + virtual void addUserPointer(const c8* attributeName, void* userPointer) = 0; + + //! Sets an attribute as user pointer + virtual void setAttribute(const c8* attributeName, void* userPointer) = 0; + + //! Gets an attribute as user pointer + //! \param attributeName: Name of the attribute to get. + virtual void* getAttributeAsUserPointer(const c8* attributeName) = 0; + + //! Gets an attribute as user pointer + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void* getAttributeAsUserPointer(s32 index) = 0; + + //! Sets an attribute as user pointer + virtual void setAttribute(s32 index, void* userPointer) = 0; + +}; + +} // end namespace io +} // end namespace irr + +#endif + + + diff --git a/src/dep/include/irrlicht/IBillboardSceneNode.h b/src/dep/include/irrlicht/IBillboardSceneNode.h new file mode 100644 index 0000000..80cd37a --- /dev/null +++ b/src/dep/include/irrlicht/IBillboardSceneNode.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BILLBOARD_SCENE_NODE_H_INCLUDED__ +#define __I_BILLBOARD_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A billboard scene node. +/** A billboard is like a 3d sprite: A 2d element, +which always looks to the camera. It is usually used for explosions, fire, +lensflares, particles and things like that. +*/ +class IBillboardSceneNode : public ISceneNode +{ +public: + + //! constructor + IBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! Sets the size of the billboard. + virtual void setSize(const core::dimension2d& size) = 0; + + //! Returns the size of the billboard. + virtual const core::dimension2d& getSize() const = 0; + + //! Set the color of all vertices of the billboard + //! \param overallColor: the color to set + virtual void setColor(const video::SColor & overallColor) = 0; + + //! Set the color of the top and bottom vertices of the billboard + //! \param topColor: the color to set the top vertices + //! \param bottomColor: the color to set the bottom vertices + virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor) = 0; + + //! Gets the color of the top and bottom vertices of the billboard + //! \param topColor: stores the color of the top vertices + //! \param bottomColor: stores the color of the bottom vertices + virtual void getColor(video::SColor & topColor, video::SColor & bottomColor) const = 0; + +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IBoneSceneNode.h b/src/dep/include/irrlicht/IBoneSceneNode.h new file mode 100644 index 0000000..f840e1c --- /dev/null +++ b/src/dep/include/irrlicht/IBoneSceneNode.h @@ -0,0 +1,103 @@ +#ifndef __I_BONE_SCENE_NODE_H_INCLUDED__ +#define __I_BONE_SCENE_NODE_H_INCLUDED__ + +// Used with ISkinnedMesh and IAnimatedMeshSceneNode, for boned meshes + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + //! Enumeration for different bone animation modes + enum E_BONE_ANIMATION_MODE + { + //! The bone is usually animated, unless it's parent is not animated + EBAM_AUTOMATIC=0, + + //! The bone is animated by the skin, if it's parent is not animated + //! then animation will resume from this bone onward + EBAM_ANIMATED, + + //! The bone is not animated by the skin + EBAM_UNANIMATED, + + //! Not an animation mode, just here to count the available modes + EBAM_COUNT + + }; + + enum E_BONE_SKINNING_SPACE + { + //! local skinning, standard + EBSS_LOCAL=0, + + //! global skinning + EBSS_GLOBAL, + + EBSS_COUNT + }; + + //! Names for bone animation modes + const c8* const BoneAnimationModeNames[] = + { + "automatic", + "animated", + "unanimated", + 0, + }; + + + class IBoneSceneNode : public ISceneNode + { + public: + + IBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1) : + ISceneNode(parent, mgr, id),positionHint(-1),scaleHint(-1),rotationHint(-1) { } + + //! Returns the name of the bone + virtual const c8* getBoneName() const = 0; + + //! Returns the index of the bone + virtual u32 getBoneIndex() const = 0; + + //! Sets the animation mode of the bone. Returns true if successful. (Unused) + virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode) = 0; + + //! Gets the current animation mode of the bone + virtual E_BONE_ANIMATION_MODE getAnimationMode() const = 0; + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const = 0; + + //! Returns the relative transformation of the scene node. + //virtual core::matrix4 getRelativeTransformation() const = 0; + + virtual void OnAnimate(u32 timeMs) =0; + + //! Does nothing as bones are not visible + virtual void render() { } + + //! How the relative transformation of the bone is used + virtual void setSkinningSpace( E_BONE_SKINNING_SPACE space ) =0; + + //! How the relative transformation of the bone is used + virtual E_BONE_SKINNING_SPACE getSkinningSpace() =0; + + //! updates the absolute position based on the relative and the parents position + virtual void updateAbsolutePositionOfAllChildren()=0; + + + + s32 positionHint; + s32 scaleHint; + s32 rotationHint; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ICameraSceneNode.h b/src/dep/include/irrlicht/ICameraSceneNode.h new file mode 100644 index 0000000..8db1418 --- /dev/null +++ b/src/dep/include/irrlicht/ICameraSceneNode.h @@ -0,0 +1,148 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_CAMERA_SCENE_NODE_H_INCLUDED__ +#define __I_CAMERA_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IEventReceiver.h" + +namespace irr +{ +namespace scene +{ + struct SViewFrustum; + + //! Scene Node which is a (controlable) camera. + /** The whole scene will be + rendered from the cameras point of view. Because the ICameraScenNode + is a SceneNode, it can be attached to any other scene node, and will + follow its parents movement, rotation and so on. + */ + class ICameraSceneNode : public ISceneNode, public IEventReceiver + { + public: + + //! Constructor + ICameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale), IsOrthogonal(false) {} + + //! Destructor + virtual ~ICameraSceneNode() {} + + //! Sets the projection matrix of the camera. + /** The core::matrix4 class has some methods + to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH. + Note that the matrix will only stay as set by this method until one of + the following Methods are called: setNearValue, setFarValue, setAspectRatio, setFOV. + \param projection: The new projection matrix of the camera. */ + virtual void setProjectionMatrix(const core::matrix4& projection) = 0; + + //! Gets the current projection matrix of the camera. + /** \return Returns the current projection matrix of the camera. */ + virtual const core::matrix4& getProjectionMatrix() const = 0; + + //! Gets the current view matrix of the camera. + /** \return Returns the current view matrix of the camera. */ + virtual const core::matrix4& getViewMatrix() const = 0; + + //! It is possible to send mouse and key events to the camera. + /** Most cameras + may ignore this input, but camera scene nodes which are created for + example with ISceneManager::addMayaCameraSceneNode or + ISceneManager::addMeshViewerCameraSceneNode, may want to get this input + for changing their position, look at target or whatever. */ + virtual bool OnEvent(const SEvent& event) = 0; + + //! Sets the look at target of the camera + /** \param pos: Look at target of the camera. */ + virtual void setTarget(const core::vector3df& pos) = 0; + + //! Gets the current look at target of the camera + /** \return Returns the current look at target of the camera */ + virtual core::vector3df getTarget() const = 0; + + //! Sets the up vector of the camera. + /** \param pos: New upvector of the camera. */ + virtual void setUpVector(const core::vector3df& pos) = 0; + + //! Gets the up vector of the camera. + /** \return Returns the up vector of the camera. */ + virtual core::vector3df getUpVector() const = 0; + + //! Gets the value of the near plane of the camera. + /** \return Returns the value of the near plane of the camera. */ + virtual f32 getNearValue() const = 0; + + //! Gets the value of the far plane of the camera. + /** \return Returns the value of the far plane of the camera. */ + virtual f32 getFarValue() const = 0; + + //! Gets the aspect ratio of the camera. + /** \return Returns the aspect ratio of the camera. */ + virtual f32 getAspectRatio() const = 0; + + //! Gets the field of view of the camera. + /** \return Returns the field of view of the camera in radiants. */ + virtual f32 getFOV() const = 0; + + //! Sets the value of the near clipping plane. (default: 1.0f) + /** \param zn: New z near value. */ + virtual void setNearValue(f32 zn) = 0; + + //! Sets the value of the far clipping plane (default: 2000.0f) + /** \param zf: New z far value. */ + virtual void setFarValue(f32 zf) = 0; + + //! Sets the aspect ratio (default: 4.0f / 3.0f) + /** \param aspect: New aspect ratio. */ + virtual void setAspectRatio(f32 aspect) = 0; + + //! Sets the field of view (Default: PI / 2.5f) + /** \param fovy: New field of view in radiants. */ + virtual void setFOV(f32 fovy) = 0; + + //! Returns the view frustum. + /** Needed sometimes by bspTree or LOD render nodes. + \return Returns the current view frustum. */ + virtual const SViewFrustum* getViewFrustum() const = 0; + + //! Disables or enables the camera to get key or mouse inputs. + /** If this is set to true, the camera will respond to key inputs + otherwise not. */ + virtual void setInputReceiverEnabled(bool enabled) = 0; + + //! Returns if the input receiver of the camera is currently enabled. + virtual bool isInputReceiverEnabled() const = 0; + + //! Returns if a camera is orthogonal. + /** This setting does not change anything of the view or projection matrix. However + it influences how collision detection and picking is done with this camera. */ + virtual bool isOrthogonal() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsOrthogonal; + } + + //! Sets if this camera should return if it is orthogonal. + /** This setting does not change anything of the view or projection matrix. However + it influences how collision detection and picking is done with this camera. */ + void setIsOrthogonal( bool orthogonal ) + { + IsOrthogonal = orthogonal; + } + + private: + + bool IsOrthogonal; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ICursorControl.h b/src/dep/include/irrlicht/ICursorControl.h new file mode 100644 index 0000000..f3dab3f --- /dev/null +++ b/src/dep/include/irrlicht/ICursorControl.h @@ -0,0 +1,81 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_CURSOR_CONTROL_H_INCLUDED__ +#define __I_CURSOR_CONTROL_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "position2d.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + + //! Interface to manipulate the mouse cursor. + class ICursorControl : public virtual IReferenceCounted + { + public: + + //! Changes the visible state of the mouse cursor. + /** \param visible: The new visible state. If true, the cursor will be visible, + if false, it will be invisible. */ + virtual void setVisible(bool visible) = 0; + + //! Returns if the cursor is currently visible. + /** \return Returns true if the cursor is visible, false if not. */ + virtual bool isVisible() const = 0; + + /** Sets the new position of the cursor. The position must be + between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. */ + //! \param pos: New position of the cursor. + virtual void setPosition(const core::position2d &pos) = 0; + + /** Sets the new position of the cursor. The position must be + between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. */ + //! \param x: New x-coord of the cursor. + //! \param y: New x-coord of the cursor. + virtual void setPosition(f32 x, f32 y) = 0; + + //! Sets the new position of the cursor. + /** \param pos: New position of the cursor. The coordinates are pixel units. */ + virtual void setPosition(const core::position2d &pos) = 0; + + //! Sets the new position of the cursor. + /** \param x: New x-coord of the cursor. The coordinates are pixel units. */ + /** \param y: New y-coord of the cursor. The coordinates are pixel units. */ + virtual void setPosition(s32 x, s32 y) = 0; + + //! Returns the current position of the mouse cursor. + /** \return Returns the current position of the cursor. The returned position + is the position of the mouse cursor in pixel units. */ + virtual core::position2d getPosition() = 0; + + //! Returns the current position of the mouse cursor. + /** \return Returns the current position of the cursor. The returned position + is a value between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is + the top left corner and (1.0f, 1.0f) is the bottom right corner of the + render window. */ + virtual core::position2d getRelativePosition() = 0; + + //! Sets an absolute reference rect for setting and retrieving the cursor position. + /** If this rect is set, the cursor position is not being calculated relative to + the rendering window but to this rect. You can set the rect pointer to 0 to disable + this feature again. This feature is useful when rendering into parts of foreign windows + for example in an editor. + \param rect: A pointer to an reference rectangle or 0 to disable the reference rectangle.*/ + virtual void setReferenceRect(core::rect* rect=0) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IDummyTransformationSceneNode.h b/src/dep/include/irrlicht/IDummyTransformationSceneNode.h new file mode 100644 index 0000000..e5846a8 --- /dev/null +++ b/src/dep/include/irrlicht/IDummyTransformationSceneNode.h @@ -0,0 +1,42 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ +#define __I_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! Dummy scene node for adding additional transformations to the scene graph. +/** This scene node does not render itself, and does not respond to set/getPosition, +set/getRotation and set/getScale. Its just a simple scene node that takes a +matrix as relative transformation, making it possible to insert any transformation +anywhere into the scene graph. +This scene node is for example used by the IAnimatedMeshSceneNode for emulating +joint scene nodes when playing skeletal animations. +*/ +class IDummyTransformationSceneNode : public ISceneNode +{ +public: + + //! constructor + IDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id) {} + + //! Returns a reference to the current relative transformation matrix. + //! This is the matrix, this scene node uses instead of scale, translation + //! and rotation. + virtual core::matrix4& getRelativeTransformationMatrix() = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IEventReceiver.h b/src/dep/include/irrlicht/IEventReceiver.h new file mode 100644 index 0000000..fce37f9 --- /dev/null +++ b/src/dep/include/irrlicht/IEventReceiver.h @@ -0,0 +1,263 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_EVENT_RECEIVER_H_INCLUDED__ +#define __I_EVENT_RECEIVER_H_INCLUDED__ + +#include "ILogger.h" +#include "position2d.h" +#include "Keycodes.h" + +namespace irr +{ + //! Enumeration for all event types there are. + enum EEVENT_TYPE + { + //! An event of the graphical user interface. + /** GUI events are created by the GUI environment or the GUI elements in response + to mouse or keyboard events. When a GUI element receives an event it will either + process it and return true, or pass the event to its parent. If an event is not absorbed + before it reaches the root element then it will then be passed to the user receiver. */ + EET_GUI_EVENT = 0, + + //! A mouse input event. + /** Mouse events are created by the device and passed to IrrlichtDevice::postEventFromUser + in response to mouse input received from the operating system. + Mouse events are first passed to the user receiver, then to the GUI environment (and possibly + many GUI elements), then finally the input receiving scene manager (and possibly the active + camera) */ + EET_MOUSE_INPUT_EVENT, + + //! A key input evant. + /** Keyboard events are also created by the device and passed to IrrlichtDevice::postEventFromUser. + They take the same path as mouse events. */ + EET_KEY_INPUT_EVENT, + + //! A log event + /** Log events are only passed to the user receiver if there is one. If they are absorbed by the + user receiver then no text will be sent to the console. */ + EET_LOG_TEXT_EVENT, + + //! A user event with user data. This is not used by Irrlicht and can be used + //! to send user specific data though the system. + EET_USER_EVENT + }; + + //! Enumeration for all mouse input events + enum EMOUSE_INPUT_EVENT + { + //! Left mouse button was pressed down. + EMIE_LMOUSE_PRESSED_DOWN = 0, + + //! Right mouse button was pressed down. + EMIE_RMOUSE_PRESSED_DOWN, + + //! Middle mouse button was pressed down. + EMIE_MMOUSE_PRESSED_DOWN, + + //! Left mouse button was left up. + EMIE_LMOUSE_LEFT_UP, + + //! Right mouse button was left up. + EMIE_RMOUSE_LEFT_UP, + + //! Middle mouse button was left up. + EMIE_MMOUSE_LEFT_UP, + + //! The mouse cursor changed its position. + EMIE_MOUSE_MOVED, + + //! The mouse wheel was moved. Use Wheel value in event data to find out + //! in what direction and how fast. + EMIE_MOUSE_WHEEL, + + //! No real event. Just for convenience to get number of events + EMIE_COUNT + }; + + namespace gui + { + + class IGUIElement; + + //! Enumeration for all events which are sendable by the gui system + enum EGUI_EVENT_TYPE + { + //! A gui element has lost its focus. + //! GUIEvent.Caller is losing the focus to GUIEvent.Element. + //! If the event is absorbed then the focus will not be changed. + EGET_ELEMENT_FOCUS_LOST = 0, + + //! A gui element has got the focus. + //! If the event is absorbed then the focus will not be changed. + EGET_ELEMENT_FOCUSED, + + //! The mouse cursor hovered over a gui element. + EGET_ELEMENT_HOVERED, + + //! The mouse cursor left the hovered element. + EGET_ELEMENT_LEFT, + + //! An element would like to close. + //! Windows and context menus use this event when they would like to close, + //! this can be cancelled by absorbing the event. + EGET_ELEMENT_CLOSED, + + //! A button was clicked. + EGET_BUTTON_CLICKED, + + //! A scrollbar has changed its position. + EGET_SCROLL_BAR_CHANGED, + + //! A checkbox has changed its check state. + EGET_CHECKBOX_CHANGED, + + //! A new item in a listbox was seleted. + EGET_LISTBOX_CHANGED, + + //! An item in the listbox was selected, which was already selected. + EGET_LISTBOX_SELECTED_AGAIN, + + //! A file has been selected in the file dialog + EGET_FILE_SELECTED, + + //! A file open dialog has been closed without choosing a file + EGET_FILE_CHOOSE_DIALOG_CANCELLED, + + //! 'Yes' was clicked on a messagebox + EGET_MESSAGEBOX_YES, + + //! 'No' was clicked on a messagebox + EGET_MESSAGEBOX_NO, + + //! 'OK' was clicked on a messagebox + EGET_MESSAGEBOX_OK, + + //! 'Cancel' was clicked on a messagebox + EGET_MESSAGEBOX_CANCEL, + + //! In an editbox was pressed 'ENTER' + EGET_EDITBOX_ENTER, + + //! The tab was changed in an tab control + EGET_TAB_CHANGED, + + //! A menu item was selected in a (context) menu + EGET_MENU_ITEM_SELECTED, + + //! The selection in a combo box has been changed + EGET_COMBO_BOX_CHANGED, + + //! The value of a spin box has changed + EGET_SPINBOX_CHANGED + + }; + } // end namespace gui + + +//! SEvents hold information about an event. See irr::IEventReceiver for details on event handling. +struct SEvent +{ + struct SGUIEvent + { + //! IGUIElement who called the event + gui::IGUIElement* Caller; + + //! If the event has something to do with another element, it will be held here. + gui::IGUIElement* Element; + + //! Type of GUI Event + gui::EGUI_EVENT_TYPE EventType; + + }; + + struct SMouseInput + { + //! X position of mouse cursor + s32 X; + + //! Y position of mouse cursor + s32 Y; + + //! mouse wheel delta, usually 1.0 or -1.0. + /** Only valid if event was EMIE_MOUSE_WHEEL */ + f32 Wheel; + + //! type of mouse event + EMOUSE_INPUT_EVENT Event; + }; + + struct SKeyInput + { + //! Character corresponding to the key (0, if not a character) + wchar_t Char; + + //! Key which has been pressed or released + EKEY_CODE Key; + + //! if not pressed, then the key was left up + bool PressedDown; + + //! true if shift was also pressed + bool Shift; + + //! true if ctrl was also pressed + bool Control; + }; + + struct SLogEvent + { + //! pointer to text which has been logged + const c8* Text; + + //! log level in which the text has been logged + ELOG_LEVEL Level; + }; + + struct SUserEvent + { + //! Some user specified data as int + s32 UserData1; + + //! Another user specified data as int + s32 UserData2; + + //! Some user specified data as float + f32 UserData3; + }; + + EEVENT_TYPE EventType; + union + { + struct SGUIEvent GUIEvent; + struct SMouseInput MouseInput; + struct SKeyInput KeyInput; + struct SLogEvent LogEvent; + struct SUserEvent UserEvent; + }; + +}; + +//! Interface of an object which can receive events. +/** Many of the engine's classes inherit IEventReceiver so they are able to process events. +Events usually start at a postEventFromUser function and are passed down through a chain of +event receivers until OnEvent returns true. +See irr::EEVENT_TYPE for a description of where each type of event starts, and the path it takes +through the system. */ +class IEventReceiver +{ +public: + + virtual ~IEventReceiver() {} + + //! called if an event happened. + //! \return Returns true if the event was processed + virtual bool OnEvent(const SEvent& event) = 0; +}; + + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IFileList.h b/src/dep/include/irrlicht/IFileList.h new file mode 100644 index 0000000..049ce1d --- /dev/null +++ b/src/dep/include/irrlicht/IFileList.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_FILE_LIST_H_INCLUDED__ +#define __I_FILE_LIST_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + +//! The Filelist lists all files in a directory. +class IFileList : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IFileList() {} + + //! Returns the amount of files in the filelist. + //! \return + //! Returns the amount of files and directories in the file list. + virtual u32 getFileCount() const = 0; + + //! Gets the name of a file in the list, based on an index. + //! The path is not included in this name. Use getFullFileName for this. + //! \param index is the zero based index of the file which name should + //! be returned. The index has to be smaller than the amount getFileCount() returns. + //! \return + //! Returns the file name of the file. Returns 0, if an error occured. + virtual const c8* getFileName(u32 index) const = 0; + + //! Gets the full name of a file in the list, path included, based on an index. + //! \param index is the zero based index of the file which name should + //! be returned. The index has to be smaller than the amount getFileCount() returns. + //! \return + //! Returns the file name of the file. Returns 0, if an error occured. + virtual const c8* getFullFileName(u32 index) = 0; + + //! Returns of the file is a directory + //! \param + //! index is the zero based index of the file which name should + //! be returned. The index has to be smaller than the amount getFileCount() returns. + //! \return + //! Returns true, if the file is a directory, and false, if it is not. + //! If an error occurs, the result is undefined. + virtual bool isDirectory(u32 index) const = 0; +}; + +} // end namespace irr +} // end namespace io + + +#endif + diff --git a/src/dep/include/irrlicht/IFileSystem.h b/src/dep/include/irrlicht/IFileSystem.h new file mode 100644 index 0000000..a4ba2f3 --- /dev/null +++ b/src/dep/include/irrlicht/IFileSystem.h @@ -0,0 +1,197 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_FILE_SYSTEM_H_INCLUDED__ +#define __I_FILE_SYSTEM_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IXMLReader.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; +} // end namespace video +namespace io +{ + +class IReadFile; +class IWriteFile; +class IFileList; +class IXMLWriter; +class IAttributes; + +//! The FileSystem manages files and archives and provides access to them. +/** + It manages where files are, so that modules which + use the the IO do not need to know where every file is located. A file + could be in a .zip-Archive or as file on disk, using the IFileSystem + makes no difference to this. +*/ +class IFileSystem : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IFileSystem() {} + + //! Opens a file for read access. + /** \param filename: Name of file to open. + \return Returns a pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. */ + virtual IReadFile* createAndOpenFile(const c8* filename) = 0; + + //! Creates an IReadFile interface for accessing memory like a file. + /** This allows you to use a pointer to memory where an IReadFile is requested. + \param memory: A pointer to the start of the file in memory + \param len: The length of the memory in bytes + \param fileName: The name given to this file + \param deleteMemoryWhenDropped: True if the memory should be deleted + along with the IReadFile when it is dropped. + \return Returns a pointer to the created file interface. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. + */ + virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped=false) = 0; + + //! Opens a file for write access. + /** \param filename: Name of file to open. + \param append: If the file already exist, all write operations are + appended to the file. + \return Returns a pointer to the created file interface. 0 is returned, if the + file could not created or opened for writing. + The returned pointer should be dropped when no longer needed. + See IReferenceCounted::drop() for more information. */ + virtual IWriteFile* createAndWriteFile(const c8* filename, bool append=false) = 0; + + //! Adds an zip archive to the file system. + /** After calling this, the Irrlicht Engine will search and open files directly from this archive too. + This is useful for hiding data from the end user, speeding up file access and making it possible to + access for example Quake3 .pk3 files, which are nothing different than .zip files. + \param filename: Filename of the zip archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \return Returns true if the archive was added successful, false if not. */ + virtual bool addZipFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true) = 0; + + //! Adds an unzipped archive ( or basedirectory with subdirectories..) to the file system. + /** Useful for handling data which will be in a zip file + \param filename: Filename of the unzipped zip archive base directory to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path. + \return Returns true if the archive was added successful, false if not. */ + virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true) = 0; + + //! Adds an pak archive to the file system. + /** After calling this, the Irrlicht Engine will search and open files directly from this archive too. + This is useful for hiding data from the end user, speeding up file access and making it possible to + access for example Quake2/KingPin/Hexen2 .pak files + \param filename: Filename of the pak archive to add to the file system. + \param ignoreCase: If set to true, files in the archive can be accessed without + writing all letters in the right case. + \param ignorePaths: If set to true, files in the added archive can be accessed + without its complete path.(should not use with Quake2 paks + \return Returns true if the archive was added successful, false if not. */ + virtual bool addPakFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true) = 0; + + //! Returns the string of the current working directory. + virtual const c8* getWorkingDirectory() = 0; + + //! Changes the current Working Directory. + /** \param newDirectory: A string specifying the new working directory. + The string is operating system dependent. Under Windows it has + the form ":\\\<..>". An example would be: "C:\Windows\" + \return Returns true if successful, otherwise false. */ + virtual bool changeWorkingDirectoryTo(const c8* newDirectory) = 0; + + //! Converts a relative path to an absolute (unique) path, resolving symbolic links if required + virtual core::stringc getAbsolutePath(const core::stringc& filename) const = 0; + + //! Returns the directory a file is located in. + /** \param filename: The file to get the directory from */ + virtual core::stringc getFileDir(const core::stringc& filename) const = 0; + + //! Creates a list of files and directories in the current working directory and returns it. + /** \return a Pointer to the created IFileList is returned. After the list has been used + it has to be deleted using its IFileList::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IFileList* createFileList() const = 0; + + //! Determines if a file exists and could be opened. + /** \param filename is the string identifying the file which should be tested for existence. + \return Returns true if file exists, and false if it does not exist or an error occured. */ + virtual bool existFile(const c8* filename) const = 0; + + //! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*). + /** Use createXMLReaderUTF8() if you prefer char* instead of wchar_t*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReader::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReader* createXMLReader(const c8* filename) = 0; + + //! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*). + /** Use createXMLReaderUTF8() if you prefer char* instead of wchar_t*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReader::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReader* createXMLReader(IReadFile* file) = 0; + + //! Creates a XML Reader from a file which returns all parsed strings as ASCII/UTF-8 characters (char*). + /** Use createXMLReader() if you prefer wchar_t* instead of char*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReaderUTF8::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReaderUTF8* createXMLReaderUTF8(const c8* filename) = 0; + + //! Creates a XML Reader from a file which returns all parsed strings as ASCII/UTF-8 characters (char*). + /** Use createXMLReader() if you prefer wchar_t* instead of char*. See IIrrXMLReader for + more information on how to use the parser. + \return 0, if file could not be opened, otherwise a pointer to the created + IXMLReader is returned. After use, the reader + has to be deleted using its IXMLReaderUTF8::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLReaderUTF8* createXMLReaderUTF8(IReadFile* file) = 0; + + //! Creates a XML Writer from a file. + /** \return 0, if file could not be opened, otherwise a pointer to the created + IXMLWriter is returned. After use, the reader + has to be deleted using its IXMLWriter::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLWriter* createXMLWriter(const c8* filename) = 0; + + //! Creates a XML Writer from a file. + /** \return 0, if file could not be opened, otherwise a pointer to the created + IXMLWriter is returned. After use, the reader + has to be deleted using its IXMLWriter::drop() method. + See IReferenceCounted::drop() for more information. */ + virtual IXMLWriter* createXMLWriter(IWriteFile* file) = 0; + + //! Creates a new empty collection of attributes, usable for serialization and more. + /** \param driver: Video driver to be used to load textures when specified as attribute values. + Can be null to prevent automatic texture loading by attributes. + \return Returns a pointer to the created object. + If you no longer need the object, you should call IAttributes::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IAttributes* createEmptyAttributes(video::IVideoDriver* driver=0) = 0; +}; + +} // end namespace io +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IGPUProgrammingServices.h b/src/dep/include/irrlicht/IGPUProgrammingServices.h new file mode 100644 index 0000000..0f86324 --- /dev/null +++ b/src/dep/include/irrlicht/IGPUProgrammingServices.h @@ -0,0 +1,274 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GPU_PROGRAMMING_SERVICES_H_INCLUDED__ +#define __I_GPU_PROGRAMMING_SERVICES_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" + +namespace irr +{ + +namespace io +{ + class IReadFile; +} // end namespace io + +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; + +//! Compile target enumeration for the addHighLevelShaderMaterial() method. +enum E_VERTEX_SHADER_TYPE +{ + EVST_VS_1_1 = 0, + EVST_VS_2_0, + EVST_VS_2_a, + EVST_VS_3_0, + + //! This is not a type, but a value indicating how much types there are. + EVST_COUNT +}; + +//! Names for all vertex shader types, each entry corresponds to a E_VERTEX_SHADER_TYPE entry. +const c8* const VERTEX_SHADER_TYPE_NAMES[] = { + "vs_1_1", + "vs_2_0", + "vs_2_a", + "vs_3_0", + 0 }; + +//! Compile target enumeration for the addHighLevelShaderMaterial() method. +enum E_PIXEL_SHADER_TYPE +{ + EPST_PS_1_1 = 0, + EPST_PS_1_2, + EPST_PS_1_3, + EPST_PS_1_4, + EPST_PS_2_0, + EPST_PS_2_a, + EPST_PS_2_b, + EPST_PS_3_0, + + //! This is not a type, but a value indicating how much types there are. + EPST_COUNT +}; + +//! Names for all pixel shader types, each entry corresponds to a E_PIXEL_SHADER_TYPE entry. +const c8* const PIXEL_SHADER_TYPE_NAMES[] = { + "ps_1_1", + "ps_1_2", + "ps_1_3", + "ps_1_4", + "ps_2_0", + "ps_2_a", + "ps_2_b", + "ps_3_0", + 0 }; + +//! Interface making it possible to create and use programs running on the GPU. +class IGPUProgrammingServices +{ +public: + + //! destructor + virtual ~IGPUProgrammingServices() {} + + //! Adds a new material renderer to the VideoDriver, based on a high level shading + //! language. Currently only HLSL/D3D9 and GLSL/OpenGL is supported. + //! \param vertexShaderProgram: String containing the source of the vertex shader program. + //! This can be 0 if no vertex program shall be used. + //! \param vertexShaderEntryPointName: Name of the entry function of the vertexShaderProgram + //! \param vsCompileTarget: Vertex shader version where the high level shader shall be compiled to. + //! \param pixelShaderProgram: String containing the source of the pixel shader program. + //! This can be 0 if no pixel shader shall be used. + //! \param pixelShaderEntryPointName: Entry name of the function of the pixelShaderEntryPointName + //! \param psCompileTarget: Pixel shader version where the high level shader shall be compiled to. + //! \param callback: Pointer to an implementation of IShaderConstantSetCallBack in which you + //! can set the needed vertex and pixel shader program constants. Set this to 0 if you don't need this. + //! \param baseMaterial: Base material which renderstates will be used to shade the + //! material. + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured, e.g. if a vertex or pixel shader + //! program could not be compiled or a compile target is not reachable. + //! The error strings are then printed to the error log and + //! can be catched with a custom event receiver. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0 ) = 0; + + //! Like IGPUProgrammingServices::addShaderMaterial(), + //! but tries to load the programs from files. + //! \param vertexShaderProgram: Text file containing the source of the vertex shader program. + //! Set to 0 if no shader shall be created. + //! \param vertexShaderEntryPointName: Name of the entry function of the vertexShaderProgram + //! \param vsCompileTarget: Vertex shader version where the high level shader shall be compiled to. + //! \param pixelShaderProgram: Text file containing the source of the pixel shader program. Set to + //! 0 if no shader shall be created. + //! \param vertexShaderEntryPointName: Name of the entry function of the vertexShaderProgram + //! \param vsCompileTarget: Vertex shader version where the high level shader shall be compiled to. + //! \param pixelShaderProgram: String containing the source of the pixel shader program. + //! This can be 0 if no pixel shader shall be used. + //! \param pixelShaderEntryPointName: Entry name of the function of the pixelShaderEntryPointName + //! \param psCompileTarget: Pixel shader version where the high level shader shall be compiled to. + //! \param callback: Pointer to an implementation of IShaderConstantSetCallBack in which you + //! can set the needed vertex and pixel shader program constants. Set this to 0 if you don't need this. + //! \param baseMaterial: Base material which renderstates will be used to shade the + //! material. + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured, e.g. if a vertex or pixel shader + //! program could not be compiled or a compile target is not reachable. + //! The error strings are then printed to the error log and + //! can be catched with a custom event receiver. + virtual s32 addHighLevelShaderMaterialFromFiles( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + + //! Like IGPUProgrammingServices::addShaderMaterial(), + //! but tries to load the programs from files. + //! \param vertexShaderProgram: Text file handle containing the source of the vertex shader program. + //! Set to 0 if no shader shall be created. + //! \param vertexShaderEntryPointName: Name of the entry function of the vertexShaderProgram + //! \param vsCompileTarget: Vertex shader version where the high level shader shall be compiled to. + //! \param pixelShaderProgram: Text file containing the source of the pixel shader program. Set to + //! \param pixelShaderProgram: Text file handle containing the source of the pixel shader program. Set to + //! 0 if no shader shall be created. + //! \param pixelShaderEntryPointName: Entry name of the function of the pixelShaderEntryPointName + //! \param psCompileTarget: Pixel shader version where the high level shader shall be compiled to. + //! \param callback: Pointer to an implementation of IShaderConstantSetCallBack in which you + //! can set the needed vertex and pixel shader program constants. Set this to 0 if you don't need this. + //! \param baseMaterial: Base material which renderstates will be used to shade the + //! material. + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured, e.g. if a vertex or pixel shader + //! program could not be compiled or a compile target is not reachable. + //! The error strings are then printed to the error log and + //! can be catched with a custom event receiver. + virtual s32 addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + io::IReadFile* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + //! Note that it is a good idea to call IVideoDriver::queryFeature() before to check + //! if the IVideoDriver supports the vertex and/or pixel shader version your are using. + //! The material is added to the VideoDriver like with IVideoDriver::addMaterialRenderer() + //! and can be used like it had been added with that method. + //! \param vertexShaderProgram: String containing the source of the vertex shader program. This can be + //! 0 if no vertex program shall be used. + //! For DX8 programs, the will always input registers look like this: + //! v0: position, v1: normal, + //! v2: color, v3: texture cooridnates, v4: texture coordinates 2 if available. + //! For DX9 programs, you can manually set the registers using the dcl_ statements. + //! \param pixelShaderProgram: String containing the source of the pixel shader program. + //! This can be 0 if you don't want to use a pixel shader. + //! \param callback: Pointer to an implementation of IShaderConstantSetCallBack in which you + //! can set the needed vertex and pixel shader program constants. Set this to 0 if you don't need this. + //! \param baseMaterial: Base material which renderstates will be used to shade the + //! material. + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured. -1 is returned for example if a vertex or pixel shader + //! program could not be compiled, the error strings are then printed out into the error log, and + //! can be catched with a custom event receiver. + virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0, + const c8* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + //! \param vertexShaderProgram: Text file containing the source of the vertex shader program. + //! Set to 0 if no shader shall be created. + //! \param pixelShaderProgram: Text file containing the source of the pixel shader program. Set to + //! 0 if no shader shall be created. + //! \param callback: Pointer to an IShaderConstantSetCallback object to which the + //! OnSetConstants function is called. + //! \param baseMaterial: baseMaterial + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured. -1 is returned for example if a vertex or pixel shader + //! program could not be compiled, the error strings are then printed out into the error log, and + //! can be catched with a custom event receiver. + virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, + io::IReadFile* pixelShaderProgram, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + //! \param vertexShaderProgramFileName: Text file name containing the source of the + //! vertex shader program. + //! Set to 0 if no shader shall be created. + //! \param pixelShaderProgramFileName: Text file name containing the source of the + //! pixel shader program. Set to 0 if no shader shall be created. + //! \param callback: Pointer to an IShaderConstantSetCallback object on which the + //! OnSetConstants function is called. + //! \param baseMaterial: baseMaterial + //! \param userData: a user data int. This int can be set to any value and will be set as parameter + //! in the callback method when calling OnSetConstants(). In this way it is easily possible to + //! use the same callback method for multiple materials and distinguish between them during the call. + //! \return Returns the number of the + //! material type which can be set in SMaterial::MaterialType to use the renderer. + //! -1 is returned if an error occured. -1 is returned for example if a vertex or pixel shader + //! program could not be compiled, the error strings are then printed out into the error log, and + //! can be catched with a custom event receiver. + virtual s32 addShaderMaterialFromFiles(const c8* vertexShaderProgramFileName, + const c8* pixelShaderProgramFileName, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0) = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIButton.h b/src/dep/include/irrlicht/IGUIButton.h new file mode 100644 index 0000000..aeeb5c1 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIButton.h @@ -0,0 +1,136 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_BUTTON_H_INCLUDED__ +#define __I_GUI_BUTTON_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ + +namespace video +{ + class ITexture; +} // end namespace video + +namespace gui +{ + class IGUIFont; + class IGUISpriteBank; + + enum EGUI_BUTTON_STATE + { + //! The button is not pressed + EGBS_BUTTON_UP=0, + //! The button is currently pressed down + EGBS_BUTTON_DOWN, + //! The mouse cursor is over the button + EGBS_BUTTON_MOUSE_OVER, + //! The mouse cursor is not over the button + EGBS_BUTTON_MOUSE_OFF, + //! The button has the focus + EGBS_BUTTON_FOCUSED, + //! The button doesn't have the focus + EGBS_BUTTON_NOT_FOCUSED, + //! not used, counts the number of enumerated items + EGBS_COUNT + }; + + //! Names for gui button state icons + const c8* const GUIButtonStateNames[] = + { + "buttonUp", + "buttonDown", + "buttonMouseOver", + "buttonMouseOff", + "buttonFocused", + "buttonNotFocused", + 0, + 0, + }; + + //! GUI Button interface. + class IGUIButton : public IGUIElement + { + public: + + //! constructor + IGUIButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_BUTTON, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIButton() {} + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Sets an image which should be displayed on the button when it is in normal state. + /** \param image: Image to be displayed */ + virtual void setImage(video::ITexture* image) = 0; + + //! Sets a background image for the button when it is in normal state. + /** \param image: Texture containing the image to be displayed + \param pos: Position in the texture, where the image is located */ + virtual void setImage(video::ITexture* image, const core::rect& pos) = 0; + + //! Sets a background image for the button when it is in pressed state. + /** If no images is specified for the pressed state via + setPressedImage(), this image is also drawn in pressed state. + \param image: Image to be displayed */ + virtual void setPressedImage(video::ITexture* image) = 0; + + //! Sets an image which should be displayed on the button when it is in pressed state. + /** \param image: Texture containing the image to be displayed + \param pos: Position in the texture, where the image is located */ + virtual void setPressedImage(video::ITexture* image, const core::rect& pos) = 0; + + //! Sets the sprite bank used by the button + virtual void setSpriteBank(IGUISpriteBank* bank) = 0; + + //! Sets the animated sprite for a specific button state + /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite + \param state: State of the button to set the sprite for + \param index: The sprite number from the current sprite bank + \param color: The color of the sprite + \param loop: True if the animation should loop, false if not + */ + virtual void setSprite(EGUI_BUTTON_STATE state, s32 index, + video::SColor color=video::SColor(255,255,255,255), bool loop=false) = 0; + + //! Sets if the button should behave like a push button. + /** Which means it can be in two states: Normal or Pressed. With a click on the button, + the user can change the state of the button. */ + virtual void setIsPushButton(bool isPushButton) = 0; + + //! Sets the pressed state of the button if this is a pushbutton + virtual void setPressed(bool pressed) = 0; + + //! Returns if the button is currently pressed + virtual bool isPressed() const = 0; + + //! Sets if the alpha channel should be used for drawing background images on the button (default is false) + virtual void setUseAlphaChannel(bool useAlphaChannel) = 0; + + //! Returns if the alpha channel should be used for drawing background images on the button + virtual bool isAlphaChannelUsed() const = 0; + + //! Returns whether the button is a push button + virtual bool isPushButton() const = 0; + + //! Sets if the button should use the skin to draw its border and button face (default is true) + virtual void setDrawBorder(bool border) = 0; + + //! Returns if the border and button face are being drawn using the skin + virtual bool isDrawingBorder() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUICheckBox.h b/src/dep/include/irrlicht/IGUICheckBox.h new file mode 100644 index 0000000..f231004 --- /dev/null +++ b/src/dep/include/irrlicht/IGUICheckBox.h @@ -0,0 +1,38 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_CHECKBOX_H_INCLUDED__ +#define __I_GUI_CHECKBOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! GUI Check box interface. + class IGUICheckBox : public IGUIElement + { + public: + + //! constructor + IGUICheckBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_CHECK_BOX, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUICheckBox() {} + + //! Set if box is checked. + virtual void setChecked(bool checked) = 0; + + //! Returns true if box is checked. + virtual bool isChecked() const = 0; + }; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIColorSelectDialog.h b/src/dep/include/irrlicht/IGUIColorSelectDialog.h new file mode 100644 index 0000000..ed71881 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIColorSelectDialog.h @@ -0,0 +1,33 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ +#define __I_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Standard file chooser dialog. + class IGUIColorSelectDialog : public IGUIElement + { + public: + + //! constructor + IGUIColorSelectDialog(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_COLOR_SELECT_DIALOG, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIColorSelectDialog() {} + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIComboBox.h b/src/dep/include/irrlicht/IGUIComboBox.h new file mode 100644 index 0000000..f60f9cf --- /dev/null +++ b/src/dep/include/irrlicht/IGUIComboBox.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_COMBO_BOX_H_INCLUDED__ +#define __I_GUI_COMBO_BOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + //! Combobox widget + class IGUIComboBox : public IGUIElement + { + public: + + //! constructor + IGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_COMBO_BOX, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIComboBox() {} + + //! Returns amount of items in box + virtual u32 getItemCount() const = 0; + + //! Returns string of an item. the idx may be a value from 0 to itemCount-1 + virtual const wchar_t* getItem(u32 idx) const = 0; + + //! Adds an item and returns the index of it + virtual u32 addItem(const wchar_t* text) = 0; + + //! Removes an item from the combo box. + /** Warning. This will change the IDs of all following items */ + virtual void removeItem(u32 id) = 0; + + //! Deletes all items in the combo box + virtual void clear() = 0; + + //! Returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const = 0; + + //! Sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 id) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIContextMenu.h b/src/dep/include/irrlicht/IGUIContextMenu.h new file mode 100644 index 0000000..573c8e8 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIContextMenu.h @@ -0,0 +1,108 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_CONTEXT_MENU_H_INCLUDED__ +#define __I_GUI_CONTEXT_MENU_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! GUI Context menu interface. + class IGUIContextMenu : public IGUIElement + { + public: + + //! constructor + IGUIContextMenu(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_CONTEXT_MENU, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIContextMenu() {}; + + //! Get amount of menu items + virtual u32 getItemCount() const = 0; + + //! Adds a menu item. + /** \param text: Text of menu item. Set this to 0 to create + an separator instead of a real item, which is the same like + calling addSeparator(); + \param commandId: Command id of menu item, a simple id you may + set to whatever you want. + \param enabled: Specifies if the menu item should be enabled. + \param hasSubMenu: Set this to true if there should be a submenu + at this item. You can acess this submenu via getSubMenu(). + \param checked: Specifies if the menu item should be initially checked. + \return Returns the index of the new item */ + virtual u32 addItem(const wchar_t* text, s32 commandId=-1, bool enabled=true, + bool hasSubMenu=false, + bool checked=false + ) = 0; + + //! Adds a separator item to the menu + virtual void addSeparator() = 0; + + //! Get text of the menu item. + /** \param idx: Zero based index of the menu item */ + virtual const wchar_t* getItemText(u32 idx) const = 0; + + //! Sets text of the menu item. + /** \param idx: Zero based index of the menu item + \param text: New text of the item. */ + virtual void setItemText(u32 idx, const wchar_t* text) = 0; + + //! Check if a menu item is enabled + /** \param idx: Zero based index of the menu item */ + virtual bool isItemEnabled(u32 idx) const = 0; + + //! Sets if the menu item should be enabled. + /** \param idx: Zero based index of the menu item + \param enabled: True if it is enabled, otherwise false. */ + virtual void setItemEnabled(u32 idx, bool enabled) = 0; + + //! Sets if the menu item should be checked. + /** \param idx: Zero based index of the menu item + \param enabled: True if it is enabled, otherwise false. */ + virtual void setItemChecked(u32 idx, bool enabled) = 0; + + //! Check if a menu item is checked + /** \param idx: Zero based index of the menu item */ + virtual bool isItemChecked(u32 idx) const = 0; + + //! Removes a menu item + /** \param idx: Zero based index of the menu item */ + virtual void removeItem(u32 idx) = 0; + + //! Removes all menu items + virtual void removeAllItems() = 0; + + //! Get the selected item in the menu + /** \return Index of the selected item, -1 if none selected. */ + virtual s32 getSelectedItem() const = 0; + + //! Get the command id of a menu item + /** \param idx: Zero based index of the menu item */ + virtual s32 getItemCommandId(u32 idx) const = 0; + + //! Sets the command id of a menu item + /** \param idx: Zero based index of the menu item + \param id: Command id of menu item, a simple id you may + set to whatever you want. */ + virtual void setItemCommandId(u32 idx, s32 id) = 0; + + //! Get a pointer to the submenu of an item. + /** 0 is returned if there is no submenu + \param idx: Zero based index of the menu item + \return Returns a pointer to the submenu of an item. */ + virtual IGUIContextMenu* getSubMenu(u32 idx) const = 0; + }; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIEditBox.h b/src/dep/include/irrlicht/IGUIEditBox.h new file mode 100644 index 0000000..65d6c3e --- /dev/null +++ b/src/dep/include/irrlicht/IGUIEditBox.h @@ -0,0 +1,114 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_EDIT_BOX_H_INCLUDED__ +#define __I_GUI_EDIT_BOX_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + + //! Single line edit box for editing simple text. + class IGUIEditBox : public IGUIElement + { + public: + + //! constructor + IGUIEditBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_EDIT_BOX, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIEditBox() {}; + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Sets another color for the text. + /** If set, the edit box does not use the EGDC_BUTTON_TEXT color defined + in the skin, but the set color instead. You don't need to call + IGUIEditBox::enableOverrrideColor(true) after this, this is done + by this function. + If you set a color, and you want the text displayed with the color + of the skin again, call IGUIEditBox::enableOverrideColor(false); + \param color: New color of the text. */ + virtual void setOverrideColor(video::SColor color) = 0; + + //! Sets if the text should use the overide color or the color in the gui skin. + /** \param enable: If set to true, the override color, which can be set + with IGUIEditBox::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual void enableOverrideColor(bool enable) = 0; + + //! Turns the border on or off + /** \param border: true if you want the border to be drawn, false if not */ + virtual void setDrawBorder(bool border) = 0; + + //! Sets text justification mode + /** \param horizontal: EGUIA_UPPERLEFT for left justified (default), + EGUIA_LOWEERRIGHT for right justified, or EGUIA_CENTER for centered text. + \param vertical: EGUIA_UPPERLEFT to align with top edge, + EGUIA_LOWEERRIGHT for bottom edge, or EGUIA_CENTER for centered text (default). */ + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) = 0; + + //! Enables or disables word wrap. + /** \param enable: If set to true, words going over one line are + broken to the next line. */ + virtual void setWordWrap(bool enable) = 0; + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled() const = 0; + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable) = 0; + + //! Checks if multi line editing is enabled + //! \return true if mult-line is enabled, false otherwise + virtual bool isMultiLineEnabled() const = 0; + + //! Enables or disables automatic scrolling with cursor position + //! \param enable: If set to true, the text will move around with the cursor position + virtual void setAutoScroll(bool enable) = 0; + + //! Checks to see if automatic scrolling is enabled + //! \return true if automatic scrolling is enabled, false if not + virtual bool isAutoScrollEnabled() const = 0; + + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*') = 0; + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() const = 0; + + //! Gets the size area of the text in the edit box + //! \return Returns the size in pixels of the text + virtual core::dimension2di getTextDimension() = 0; + + //! Sets the maximum amount of characters which may be entered in the box. + /** \param max: Maximum amount of characters. If 0, the character amount is + infinity. */ + virtual void setMax(u32 max) = 0; + + //! Returns maximum amount of characters, previously set by setMax(); + virtual u32 getMax() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIElement.h b/src/dep/include/irrlicht/IGUIElement.h new file mode 100644 index 0000000..548c70d --- /dev/null +++ b/src/dep/include/irrlicht/IGUIElement.h @@ -0,0 +1,943 @@ + // Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ELEMENT_H_INCLUDED__ +#define __I_GUI_ELEMENT_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "irrList.h" +#include "rect.h" +#include "irrString.h" +#include "IEventReceiver.h" +#include "EGUIElementTypes.h" +#include "IAttributes.h" + +namespace irr +{ +namespace gui +{ + +class IGUIEnvironment; + +enum EGUI_ALIGNMENT +{ + //! Aligned to parent's top or left side (default) + EGUIA_UPPERLEFT=0, + //! Aligned to parent's bottom or right side + EGUIA_LOWERRIGHT, + //! Aligned to the center of parent + EGUIA_CENTER, + //! Scaled within its parent + EGUIA_SCALE +}; + +//! Names for alignments +const c8* const GUIAlignmentNames[] = +{ + "upperLeft", + "lowerRight", + "center", + "scale", + 0 +}; + +//! Base class of all GUI elements. +class IGUIElement : public virtual io::IAttributeExchangingObject, public IEventReceiver +{ +public: + + //! Constructor + IGUIElement(EGUI_ELEMENT_TYPE type, IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : Parent(0), RelativeRect(rectangle), AbsoluteRect(rectangle), + AbsoluteClippingRect(rectangle), DesiredRect(rectangle), + MaxSize(0,0), MinSize(1,1), IsVisible(true), IsEnabled(true), + IsSubElement(false), NoClip(false), ID(id), IsTabStop(false), TabOrder(-1), IsTabGroup(false), + AlignLeft(EGUIA_UPPERLEFT), AlignRight(EGUIA_UPPERLEFT), AlignTop(EGUIA_UPPERLEFT), AlignBottom(EGUIA_UPPERLEFT), + Environment(environment), Type(type) + { + #ifdef _DEBUG + setDebugName("IGUIElement"); + #endif + + // if we were given a parent to attach to + if (parent) + parent->addChild(this); + + // if we succeeded in becoming a child + if (Parent) + { + LastParentRect = Parent->getAbsolutePosition(); + AbsoluteRect += LastParentRect.UpperLeftCorner; + AbsoluteClippingRect = AbsoluteRect; + AbsoluteClippingRect.clipAgainst(Parent->AbsoluteClippingRect); + } + } + + + //! Destructor + virtual ~IGUIElement() + { + // delete all children + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->Parent = 0; + (*it)->drop(); + } + } + + + //! Returns parent of this element. + IGUIElement* getParent() const + { + return Parent; + } + + + //! Returns the relative rectangle of this element. + core::rect getRelativePosition() const + { + return RelativeRect; + } + + + //! Sets the relative rectangle of this element. + void setRelativePosition(const core::rect& r) + { + if (Parent) + { + const core::rect& r2 = Parent->getAbsolutePosition(); + + core::dimension2df d((f32)(r2.getSize().Width), (f32)(r2.getSize().Height)); + + if (AlignLeft == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.X = (f32)r.UpperLeftCorner.X / d.Width; + if (AlignRight == EGUIA_SCALE) + ScaleRect.LowerRightCorner.X = (f32)r.LowerRightCorner.X / d.Width; + if (AlignTop == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.Y = (f32)r.UpperLeftCorner.Y / d.Height; + if (AlignBottom == EGUIA_SCALE) + ScaleRect.LowerRightCorner.Y = (f32)r.LowerRightCorner.Y / d.Height; + } + + DesiredRect = r; + updateAbsolutePosition(); + } + + + //! Sets the relative rectangle of this element. + void setRelativePosition(const core::rect& r) + { + if (!Parent) + return; + + const core::dimension2di& d = Parent->getAbsolutePosition().getSize(); + + DesiredRect = core::rect( + core::floor32((f32)d.Width * r.UpperLeftCorner.X), + core::floor32((f32)d.Height * r.UpperLeftCorner.Y), + core::floor32((f32)d.Width * r.LowerRightCorner.X), + core::floor32((f32)d.Height * r.LowerRightCorner.Y)); + + ScaleRect = r; + + updateAbsolutePosition(); + } + + + //! Returns the absolute rectangle of element. + core::rect getAbsolutePosition() const + { + return AbsoluteRect; + } + + + //! Returns the visible area of the element. + core::rect getAbsoluteClippingRect() const + { + return AbsoluteClippingRect; + } + + + //! Sets whether the element will ignore its parent's clipping rectangle + void setNotClipped(bool noClip) + { + NoClip = noClip; + } + + + //! Gets whether the element will ignore its parent's clipping rectangle + bool isNotClipped() const + { + return NoClip; + } + + + //! Sets the maximum size allowed for this element + /** If set to 0,0, there is no maximum size */ + void setMaxSize(core::dimension2di size) + { + MaxSize = size; + updateAbsolutePosition(); + } + + + //! Sets the minimum size allowed for this element + void setMinSize(core::dimension2di size) + { + MinSize = size; + if (MinSize.Width < 1) + MinSize.Width = 1; + if (MinSize.Height < 1) + MinSize.Height = 1; + updateAbsolutePosition(); + } + + + void setAlignment(EGUI_ALIGNMENT left, EGUI_ALIGNMENT right, EGUI_ALIGNMENT top, EGUI_ALIGNMENT bottom) + { + AlignLeft = left; + AlignRight = right; + AlignTop = top; + AlignBottom = bottom; + + if (Parent) + { + core::rect r(Parent->getAbsolutePosition()); + + core::dimension2df d((f32)r.getSize().Width, (f32)r.getSize().Height); + + if (AlignLeft == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.X = (f32)DesiredRect.UpperLeftCorner.X / d.Width; + if (AlignRight == EGUIA_SCALE) + ScaleRect.LowerRightCorner.X = (f32)DesiredRect.LowerRightCorner.X / d.Width; + if (AlignTop == EGUIA_SCALE) + ScaleRect.UpperLeftCorner.Y = (f32)DesiredRect.UpperLeftCorner.Y / d.Height; + if (AlignBottom == EGUIA_SCALE) + ScaleRect.LowerRightCorner.Y = (f32)DesiredRect.LowerRightCorner.Y / d.Height; + } + } + + + //! Updates the absolute position. + virtual void updateAbsolutePosition() + { + core::rect parentAbsolute(0,0,0,0); + core::rect parentAbsoluteClip; + s32 diffx, diffy; + f32 fw=0.f, fh=0.f; + + if (Parent) + { + parentAbsolute = Parent->AbsoluteRect; + + if (NoClip) + { + IGUIElement* p=this; + while (p && p->NoClip && p->Parent) + p = p->Parent; + if (p->Parent) + parentAbsoluteClip = p->Parent->AbsoluteClippingRect; + else + parentAbsoluteClip = p->AbsoluteClippingRect; + } + else + parentAbsoluteClip = Parent->AbsoluteClippingRect; + } + + + diffx = parentAbsolute.getWidth() - LastParentRect.getWidth(); + diffy = parentAbsolute.getHeight() - LastParentRect.getHeight(); + + if (AlignLeft == EGUIA_SCALE || AlignRight == EGUIA_SCALE) + fw = (f32)parentAbsolute.getWidth(); + + if (AlignTop == EGUIA_SCALE || AlignBottom == EGUIA_SCALE) + fh = (f32)parentAbsolute.getHeight(); + + + switch (AlignLeft) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.UpperLeftCorner.X += diffx; + break; + case EGUIA_CENTER: + DesiredRect.UpperLeftCorner.X += diffx/2; + break; + case EGUIA_SCALE: + DesiredRect.UpperLeftCorner.X = (s32)(ScaleRect.UpperLeftCorner.X * fw); + break; + } + + switch (AlignRight) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.LowerRightCorner.X += diffx; + break; + case EGUIA_CENTER: + DesiredRect.LowerRightCorner.X += diffx/2; + break; + case EGUIA_SCALE: + DesiredRect.LowerRightCorner.X = (s32)(ScaleRect.LowerRightCorner.X * fw); + break; + } + + switch (AlignTop) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.UpperLeftCorner.Y += diffy; + break; + case EGUIA_CENTER: + DesiredRect.UpperLeftCorner.Y += diffy/2; + break; + case EGUIA_SCALE: + DesiredRect.UpperLeftCorner.Y = (s32)(ScaleRect.UpperLeftCorner.Y * fh); + break; + } + + switch (AlignBottom) + { + case EGUIA_UPPERLEFT: + break; + case EGUIA_LOWERRIGHT: + DesiredRect.LowerRightCorner.Y += diffy; + break; + case EGUIA_CENTER: + DesiredRect.LowerRightCorner.Y += diffy/2; + break; + case EGUIA_SCALE: + DesiredRect.LowerRightCorner.Y = (s32)(ScaleRect.LowerRightCorner.Y * fh); + break; + } + + RelativeRect = DesiredRect; + + s32 w = RelativeRect.getWidth(); + s32 h = RelativeRect.getHeight(); + + // make sure the desired rectangle is allowed + if (w < MinSize.Width) + RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MinSize.Width; + if (h < MinSize.Height) + RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MinSize.Height; + if (MaxSize.Width && w > MaxSize.Width) + RelativeRect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + MaxSize.Width; + if (MaxSize.Height && h > MaxSize.Height) + RelativeRect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + MaxSize.Height; + + RelativeRect.repair(); + + AbsoluteRect = RelativeRect + parentAbsolute.UpperLeftCorner; + + if (!Parent) + parentAbsoluteClip = AbsoluteRect; + + AbsoluteClippingRect = AbsoluteRect; + AbsoluteClippingRect.clipAgainst(parentAbsoluteClip); + + LastParentRect = parentAbsolute; + + // update all children + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->updateAbsolutePosition(); + } + } + + + //! Returns the child element, which is at the position of the point. + IGUIElement* getElementFromPoint(const core::position2d& point) + { + IGUIElement* target = 0; + + // we have to search from back to front, because later children + // might be drawn over the top of earlier ones. + + core::list::Iterator it = Children.getLast(); + + if (IsVisible) + while(it != Children.end()) + { + target = (*it)->getElementFromPoint(point); + if (target) + return target; + + --it; + } + + if (IsVisible && isPointInside(point)) + target = this; + + return target; + } + + + //! Returns true if a point is within this element. + //! Elements with a shape other than a rectangle will override this method + virtual bool isPointInside(const core::position2d& point) const + { + return AbsoluteClippingRect.isPointInside(point); + } + + + //! Adds a GUI element as new child of this element. + virtual void addChild(IGUIElement* child) + { + if (child) + { + child->grab(); + child->remove(); // remove from old parent + child->LastParentRect = getAbsolutePosition(); + child->Parent = this; + Children.push_back(child); + } + } + + + //! Removes a child. + virtual void removeChild(IGUIElement* child) + { + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + if ((*it) == child) + { + (*it)->Parent = 0; + (*it)->drop(); + Children.erase(it); + return; + } + } + + + //! Removes this element from its parent. + virtual void remove() + { + if (Parent) + Parent->removeChild(this); + } + + + //! Draws the element and its children. + virtual void draw() + { + if (!IsVisible) + return; + + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->draw(); + } + + + //! animate the element and its children. + virtual void OnPostRender(u32 timeMs) + { + if (!IsVisible) + return; + + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnPostRender( timeMs ); + } + + + //! Moves this element. + virtual void move(core::position2d absoluteMovement) + { + setRelativePosition(DesiredRect + absoluteMovement); + } + + + //! Returns true if element is visible. + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + + //! Sets the visible state of this element. + virtual void setVisible(bool visible) + { + IsVisible = visible; + } + + + //! Returns true if this element was created as part of its parent control + virtual bool isSubElement() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsSubElement; + } + + + //! Sets whether this control was created as part of its parent, + //! for example when a scrollbar is part of a listbox. + //! SubElements are not saved to disk when calling guiEnvironment->saveGUI() + virtual void setSubElement(bool subElement) + { + IsSubElement = subElement; + } + + + //! If set to true, the focus will visit this element when using + //! the tab key to cycle through elements. + //! If this element is a tab group (see isTabGroup/setTabGroup) then + //! ctrl+tab will be used instead. + void setTabStop(bool enable) + { + IsTabStop = enable; + } + + + //! Returns true if this element can be focused by navigating with the tab key + bool isTabStop() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsTabStop; + } + + + //! Sets the priority of focus when using the tab key to navigate between a group + //! of elements. See setTabGroup, isTabGroup and getTabGroup for information on tab groups. + //! Elements with a lower number are focused first + void setTabOrder(s32 index) + { + // negative = autonumber + if (index < 0) + { + TabOrder = 0; + IGUIElement *el = getTabGroup(); + while (IsTabGroup && el && el->Parent) + el = el->Parent; + + IGUIElement *first=0, *closest=0; + if (el) + { + // find the highest element number + el->getNextElement(-1, true, IsTabGroup, first, closest, true); + if (first) + { + TabOrder = first->getTabOrder() + 1; + } + } + + } + else + TabOrder = index; + } + + + //! Returns the number in the tab order sequence + s32 getTabOrder() const + { + return TabOrder; + } + + + //! Sets whether this element is a container for a group of elements which + //! can be navigated using the tab key. For example, windows are tab groups. + //! Groups can be navigated using ctrl+tab, providing isTabStop is true. + void setTabGroup(bool isGroup) + { + IsTabGroup = isGroup; + } + + + //! Returns true if this element is a tab group. + bool isTabGroup() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsTabGroup; + } + + + //! Returns the container element which holds all elements in this element's + //! tab group. + IGUIElement* getTabGroup() + { + IGUIElement *ret=this; + + while (ret && !ret->isTabGroup()) + ret = ret->getParent(); + + return ret; + } + + + //! Returns true if element is enabled. + virtual bool isEnabled() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsEnabled; + } + + + //! Sets the enabled state of this element. + virtual void setEnabled(bool enabled) + { + IsEnabled = enabled; + } + + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text) + { + Text = text; + } + + + //! Returns caption of this element. + virtual const wchar_t* getText() const + { + return Text.c_str(); + } + + + //! Sets the new caption of this element. + virtual void setToolTipText(const wchar_t* text) + { + ToolTipText = text; + } + + + //! Returns caption of this element. + virtual const core::stringw& getToolTipText() const + { + return ToolTipText; + } + + + //! Returns id. Can be used to identify the element. + virtual s32 getID() const + { + return ID; + } + + + //! Sets the id of this element + virtual void setID(s32 id) + { + ID = id; + } + + + //! Called if an event happened. + virtual bool OnEvent(const SEvent& event) + { + return Parent ? Parent->OnEvent(event) : false; + } + + + //! Brings a child to front + /** \return Returns true if successful, false if not. */ + virtual bool bringToFront(IGUIElement* element) + { + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + if (element == (*it)) + { + Children.erase(it); + Children.push_back(element); + return true; + } + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns list with children of this element + virtual const core::list& getChildren() const + { + return Children; + } + + + //! Finds the first element with the given id. + /** \param id: Id to search for. + \param searchchildren: Set this to true, if also children of this + element may contain the element with the searched id and they + should be searched too. + \return Returns the first element with the given id. If no element + with this id was found, 0 is returned. */ + virtual IGUIElement* getElementFromId(s32 id, bool searchchildren=false) const + { + IGUIElement* e = 0; + + core::list::ConstIterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + if ((*it)->getID() == id) + return (*it); + + if (searchchildren) + e = (*it)->getElementFromId(id, true); + + if (e) + return e; + } + + return e; + } + + + //! returns true if the given element is a child of this one. + //! \param child: The child element to check + bool isMyChild(IGUIElement* child) const + { + if (!child) + return false; + do + { + if (child->Parent) + child = child->Parent; + + } while (child->Parent && child != this); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return child == this; + } + + + //! searches elements to find the closest next element to tab to + //! \param startOrder: The TabOrder of the current element, -1 if none + //! \param reverse: true if searching for a lower number + //! \param group: true if searching for a higher one + //! \param first: element with the highest/lowest known tab order depending on search direction + //! \param closest: the closest match, depending on tab order and direction + //! \param includeInvisible: includes invisible elements in the search (default=false) + //! \return true if successfully found an element, false to continue searching/fail + bool getNextElement(s32 startOrder, bool reverse, bool group, + IGUIElement*& first, IGUIElement*& closest, bool includeInvisible=false) const + { + // we'll stop searching if we find this number + s32 wanted = startOrder + ( reverse ? -1 : 1 ); + if (wanted==-2) + wanted = 1073741824; // maximum s32 + + core::list::ConstIterator it = Children.begin(); + + s32 closestOrder, currentOrder; + + while(it != Children.end()) + { + // ignore invisible elements and their children + if ( ( (*it)->isVisible() || includeInvisible ) && + (group == true || (*it)->isTabGroup() == false) ) + { + // only check tab stops and those with the same group status + if ((*it)->isTabStop() && ((*it)->isTabGroup() == group)) + { + currentOrder = (*it)->getTabOrder(); + + // is this what we're looking for? + if (currentOrder == wanted) + { + closest = *it; + return true; + } + + // is it closer than the current closest? + if (closest) + { + closestOrder = closest->getTabOrder(); + if ( ( reverse && currentOrder > closestOrder && currentOrder < startOrder) + ||(!reverse && currentOrder < closestOrder && currentOrder > startOrder)) + { + closest = *it; + } + } + else + if ( (reverse && currentOrder < startOrder) || (!reverse && currentOrder > startOrder) ) + { + closest = *it; + } + + // is it before the current first? + if (first) + { + closestOrder = first->getTabOrder(); + + if ( (reverse && closestOrder < currentOrder) || (!reverse && closestOrder > currentOrder) ) + { + first = *it; + } + } + else + { + first = *it; + } + } + // search within children + if ((*it)->getNextElement(startOrder, reverse, group, first, closest)) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + } + } + ++it; + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the gui element. + /** This is needed for the .NET wrapper but will be used + later for serializing and deserializing. + If you wrote your own GUIElements, you need to set the type for your element as first parameter + in the constructor of IGUIElement. For own (=unknown) elements, simply use EGUIET_ELEMENT as type */ + EGUI_ELEMENT_TYPE getType() const + { + return Type; + } + + + //! Returns the type name of the gui element. + /** This is needed serializing elements. For serializing your own elements, override this function + and return your own type name which is created by your IGUIElementFactory */ + virtual const c8* getTypeName() const + { + return GUIElementTypeNames[Type]; + } + + + //! Writes attributes of the scene node. + //! Implement this to expose the attributes of your scene node for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const + { + out->addInt("Id", ID ); + out->addString("Caption", getText()); + out->addRect("Rect", DesiredRect); + out->addPosition2d("MinSize", core::position2di(MinSize.Width, MinSize.Height)); + out->addPosition2d("MaxSize", core::position2di(MaxSize.Width, MaxSize.Height)); + out->addBool("NoClip", NoClip); + out->addEnum("LeftAlign", AlignLeft, GUIAlignmentNames); + out->addEnum("RightAlign", AlignRight, GUIAlignmentNames); + out->addEnum("TopAlign", AlignTop, GUIAlignmentNames); + out->addEnum("BottomAlign", AlignBottom, GUIAlignmentNames); + out->addBool("Visible", IsVisible); + out->addBool("Enabled", IsEnabled); + out->addBool("TabStop", IsTabStop); + out->addBool("TabGroup", IsTabGroup); + out->addInt("TabOrder", TabOrder); + } + + + //! Reads attributes of the scene node. + //! Implement this to set the attributes of your scene node for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) + { + setID(in->getAttributeAsInt("Id")); + setText(in->getAttributeAsStringW("Caption").c_str()); + setVisible(in->getAttributeAsBool("Visible")); + setEnabled(in->getAttributeAsBool("Enabled")); + IsTabStop = in->getAttributeAsBool("TabStop"); + IsTabGroup = in->getAttributeAsBool("TabGroup"); + TabOrder = in->getAttributeAsInt("TabOrder"); + + core::position2di p = in->getAttributeAsPosition2d("MaxSize"); + setMaxSize(core::dimension2di(p.X,p.Y)); + + p = in->getAttributeAsPosition2d("MinSize"); + setMinSize(core::dimension2di(p.X,p.Y)); + + setNotClipped(in->getAttributeAsBool("NoClip")); + setAlignment((EGUI_ALIGNMENT) in->getAttributeAsEnumeration("LeftAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("RightAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("TopAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT)in->getAttributeAsEnumeration("BottomAlign", GUIAlignmentNames)); + + setRelativePosition(in->getAttributeAsRect("Rect")); + } + +protected: + + //! List of all children of this element + core::list Children; + + //! Pointer to the parent + IGUIElement* Parent; + + //! relative rect of element + core::rect RelativeRect; + + //! absolute rect of element + core::rect AbsoluteRect; + + //! absolute clipping rect of element + core::rect AbsoluteClippingRect; + + //! the rectangle the element would prefer to be, + //! if it was not constrained by parent or max/min size + core::rect DesiredRect; + + //! for calculating the difference when resizing parent + core::rect LastParentRect; + + //! relative scale of the element inside its parent + core::rect ScaleRect; + + //! maximum and minimum size of the element + core::dimension2di MaxSize, MinSize; + + //! is visible? + bool IsVisible; + + //! is enabled? + bool IsEnabled; + + //! is a part of a larger whole and should not be serialized? + bool IsSubElement; + + //! does this element ignore its parent's clipping rectangle? + bool NoClip; + + //! caption + core::stringw Text; + + //! tooltip + core::stringw ToolTipText; + + //! id + s32 ID; + + //! tab stop like in windows + bool IsTabStop; + + //! tab order + s32 TabOrder; + + //! tab groups are containers like windows, use ctrl+tab to navigate + bool IsTabGroup; + + //! tells the element how to act when its parent is resized + EGUI_ALIGNMENT AlignLeft, AlignRight, AlignTop, AlignBottom; + + //! GUI Environment + IGUIEnvironment* Environment; + + //! type of element + EGUI_ELEMENT_TYPE Type; +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIElementFactory.h b/src/dep/include/irrlicht/IGUIElementFactory.h new file mode 100644 index 0000000..15fc88e --- /dev/null +++ b/src/dep/include/irrlicht/IGUIElementFactory.h @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ +#define __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "EGUIElementTypes.h" + +namespace irr +{ + + +namespace gui +{ + class IGUIElement; + + //! Interface making it possible to dynamicly create GUI elements + /** To be able to add custom elements to Irrlicht and to make it possible for the + scene manager to save and load them, simply implement this interface and register it + in your gui environment via IGUIEnvironment::registerGUIElementFactory. + Note: When implementing your own element factory, don't call IGUIEnvironment::grab() to + increase the reference counter of the environment. This is not necessary because the + it will grab() the factory anyway, and otherwise cyclic references will be created. + */ + class IGUIElementFactory : public virtual IReferenceCounted + { + public: + + // destructor + virtual ~IGUIElementFactory() {} + + //! adds an element to the gui environment based on its type id + /** \param type: Type of the element to add. + \param parent: Parent scene node of the new element, can be null to add to the root. + \return Returns pointer to the new element or null if not successful. */ + virtual IGUIElement* addGUIElement(EGUI_ELEMENT_TYPE type, IGUIElement* parent=0) = 0; + + //! adds a GUI element to the GUI Environment based on its type name + /** \param typeName: Type name of the element to add. + \param parent: Parent scene node of the new element, can be null to add it to the root. + \return Returns pointer to the new element or null if not successful. */ + virtual IGUIElement* addGUIElement(const c8* typeName, IGUIElement* parent=0) = 0; + + //! returns amount of GUI element types this factory is able to create + virtual s32 getCreatableGUIElementTypeCount() const = 0; + + //! returns type of a createable element type + /** \param idx: Index of the element type in this factory. Must be a value between 0 and + getCreatableGUIElementTypeCount() */ + virtual EGUI_ELEMENT_TYPE getCreateableGUIElementType(s32 idx) const = 0; + + //! returns type name of a createable GUI element type by index + /** \param idx: Index of the type in this factory. Must be a value between 0 and + getCreatableGUIElementTypeCount() */ + virtual const c8* getCreateableGUIElementTypeName(s32 idx) const = 0; + + //! returns type name of a createable GUI element + /** \param type: Type of GUI element. + \return: Returns name of the type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableGUIElementTypeName(EGUI_ELEMENT_TYPE type) const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_ELEMENT_FACTORY_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IGUIEnvironment.h b/src/dep/include/irrlicht/IGUIEnvironment.h new file mode 100644 index 0000000..6c34538 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIEnvironment.h @@ -0,0 +1,428 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_ENVIRONMENT_H_INCLUDED__ +#define __I_GUI_ENVIRONMENT_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IGUISkin.h" +#include "rect.h" +#include "EMessageBoxFlags.h" +#include "IEventReceiver.h" +#include "IXMLReader.h" + +namespace irr +{ + class IOSOperator; + class IEventReceiver; + + namespace io + { + class IXMLWriter; + class IReadFile; + class IWriteFile; + class IFileSystem; + } // end namespace io + namespace video + { + class IVideoDriver; + class ITexture; + } // end namespace video + +namespace gui +{ + +class IGUIElement; +class IGUIFont; +class IGUISpriteBank; +class IGUIScrollBar; +class IGUIImage; +class IGUIMeshViewer; +class IGUICheckBox; +class IGUIListBox; +class IGUIFileOpenDialog; +class IGUIColorSelectDialog; +class IGUIInOutFader; +class IGUIStaticText; +class IGUIEditBox; +class IGUISpinBox; +class IGUITabControl; +class IGUITab; +class IGUIContextMenu; +class IGUIComboBox; +class IGUIToolBar; +class IGUIButton; +class IGUIWindow; +class IGUIElementFactory; + +//! GUI Environment. Used as factory and manager of all other GUI elements. +class IGUIEnvironment : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IGUIEnvironment() {}; + + //! Draws all gui elements. + virtual void drawAll() = 0; + + //! Sets the focus to an element. + /** Causes a EGET_ELEMENT_FOCUS_LOST event followed by a EGET_ELEMENT_FOCUSED event. + If someone absorbed either of the events, then the focus will not be changed. + \return Returns true on success, false on failure */ + virtual bool setFocus(IGUIElement* element) = 0; + + //! Returns the element with the focus + virtual IGUIElement* getFocus() const = 0; + + //! Removes the focus from an element. + /** Causes a EGET_ELEMENT_FOCUS_LOST event. If the event is absorbed then the focus + will not be changed. + \return Returns true on success, false on failure */ + virtual bool removeFocus(IGUIElement* element) = 0; + + //! Returns if the element has focus + virtual bool hasFocus(IGUIElement* element) const = 0; + + //! Returns the current video driver. + virtual video::IVideoDriver* getVideoDriver() const = 0; + + //! Returns the file system. + virtual io::IFileSystem* getFileSystem() const = 0; + + //! returns a pointer to the OS operator + virtual IOSOperator* getOSOperator() const = 0; + + //! removes all elements from the environment. + virtual void clear() = 0; + + //! Posts an input event to the environment. + /** Usually you do not have to + use this method, it is used by the internal engine. */ + virtual bool postEventFromUser(const SEvent& event) = 0; + + //! This sets a new event receiver for gui events. + /** Usually you do not have to + use this method, it is used by the internal engine. */ + virtual void setUserEventReceiver(IEventReceiver* evr) = 0; + + //! Returns pointer to the current gui skin. + virtual IGUISkin* getSkin() const = 0; + + //! Sets a new GUI Skin + /** You can use this to change the appearance of the whole GUI Environment. You + can set one of the built-in skins or implement your own class derived from + IGUISkin and enable it using this method. + To set for example the built-in Windows classic skin, use the following code: + \code + gui::IGUISkin* newskin = environment->createSkin(gui::EGST_WINDOWS_CLASSIC); + environment->setSkin(newskin); + newskin->drop(); + \endcode + */ + virtual void setSkin(IGUISkin* skin) = 0; + + //! Creates a new GUI Skin based on a template. + /** Use setSkin() to set the created skin. + \return Returns a pointer to the created skin. + If you no longer need it, you should call IGUISkin::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IGUISkin* createSkin(EGUI_SKIN_TYPE type) = 0; + + //! Returns pointer to the font with the specified file name. + /** Loads the font if it was not loaded before. Returns 0 if the font could not be loaded. + \return + returns a pointer to the font. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIFont* getFont(const c8* filename) = 0; + + //! Returns the default built-in font. + virtual IGUIFont* getBuiltInFont() const = 0; + + //! Returns pointer to the sprite bank with the specified file name. + /** Loads the bank if it was not loaded before. Returns 0 if it could not be loaded. + \return + returns a pointer to the sprite bank. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUISpriteBank* getSpriteBank(const c8* filename) = 0; + + //! adds an empty sprite bank to the manager + virtual IGUISpriteBank* addEmptySpriteBank(const c8 *name) = 0; + + //! Returns the root gui element. + /** This is the first gui element, parent of all other + gui elements. You'll never need to use this method, unless you are not creating + your own gui elements, trying to add them to the gui elements without a parent. + The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIElement* getRootGUIElement() = 0; + + //! Adds an button element. + /** \return + Returns a pointer to the created button. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIButton* addButton(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, const wchar_t* tooltiptext = 0) = 0; + + //! Adds an empty window element. + /** \param modal: Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \return + Returns a pointer to the created window. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIWindow* addWindow(const core::rect& rectangle, bool modal = false, + const wchar_t* text=0, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a modal screen. This control stops its parent's members from being + //! able to recieve input until its last child is removed, it then deletes its self. + /** \return + Returns a pointer to the created window. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIElement* addModalScreen(IGUIElement* parent) = 0; + + //! Adds a message box. + /** \param caption: Text to be displayed the title of the message box. + \param text: Text to be displayed in the body of the message box. + \param modal: Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \param flags: Flags specifying the layout of the message box. For example + to create a message box with an OK and a CANCEL button on it, set this + to (EMBF_OK | EMBF_CANCEL). + \param parent: Parent gui element of the message box. + \param id: Id with which the gui element can be identified. + \return + Returns a pointer to the created message box. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIWindow* addMessageBox(const wchar_t* caption, const wchar_t* text=0, + bool modal = true, s32 flags = EMBF_OK, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a scrollbar. + /** \return + Returns a pointer to the created scrollbar. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds an image element. + /** \param image: Image to be displayed. + \param pos: Position of the image. The width and height of the image is taken + from the image. + \param useAlphaChannel: Sets if the image should use the alpha channel of the texture + to draw itself. + \return + Returns a pointer to the created image element. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIImage* addImage(video::ITexture* image, core::position2d pos, + bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds an image element. + /** Use IGUIImage::setImage later to set the image to be displayed. + \return + Returns a pointer to the created image element. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIImage* addImage(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds a checkbox element. + /** \return + Returns a pointer to the created check box. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUICheckBox* addCheckBox(bool checked, const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds a list box element. + /** \return + Returns a pointer to the created list box. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIListBox* addListBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) = 0; + + //! Adds an mesh viewer. Not 100% implemented yet. + /** \return + Returns a pointer to the created mesh viewer. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIMeshViewer* addMeshViewer(const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) = 0; + + //! Adds a file open dialog. + /** \param modal: Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \return + Returns a pointer to the created file open dialog. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title = 0, + bool modal=true, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a color select dialog. + /** \param modal: Defines if the dialog is modal. This means, that all other + gui elements which were created before the message box cannot be used + until this messagebox is removed. + \return + Returns a pointer to the created file open dialog. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIColorSelectDialog* addColorSelectDialog(const wchar_t* title = 0, + bool modal=true, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a static text. + /** The returned pointer must not be dropped. + \param text is the text to be displayed. Can be altered after creation with SetText(). + \param rectangle is the position of the static text. + \param border has to be set to true if the static text should have a 3d border. + \param wordWrap specifies, if the text should be wrapped into multiple lines. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the fader directly in the environment. + \param id is a s32 to identify the static text element. + \param fillBackground specifies if the background will be filled. Default: false. + \return + Returns a pointer to the created static text. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect& rectangle, + bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, + bool fillBackground = false) = 0; + + //! Adds an edit box. + /** Supports unicode input from every keyboard around the world, + scrolling, copying and pasting (exchanging data with the clipboard directly), maximum + character amount, marking and all shortcuts like ctrl+X, ctrl+V, ctrg+C, + shift+Left, shift+Right, Home, End, and so on. + \param text is the text to be displayed. Can be altered after creation with setText(). + \param rectangle is the position of the edit box. + \param border has to be set to true if the edit box should have a 3d border. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the edit box directly in the environment. + \param id is a s32 to identify the edit box. + \return + Returns a pointer to the created edit box. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect& rectangle, + bool border=true, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a spin box. + /** An edit box with up and down buttons + \param text is the text to be displayed. Can be altered after creation with setText(). + \param rectangle is the position of the spin box. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the spin box directly in the environment. + \param id is a s32 to identify the spin box. + \return + Returns a pointer to the created spin box. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUISpinBox* addSpinBox(const wchar_t* text, const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds an element for fading in or out. + /* \param rectangle: Pointer to rectangle specifing the borders of the element. + If the pointer is NULL, the whole screen is used. + \param parent: Parent item of the element. E.g. a window. Set it to 0 to place the static text directly in the environment. + \param id: A s32 to identify the text. + \return + Returns a pointer to the created in-out-fader. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUIInOutFader* addInOutFader(const core::rect* rectangle=0, IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a tab control to the environment. + /** \param rectangle is the position of the tab control. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the tab control directly in the environment. + \param fillbackground specifies if the background of the tab control should be drawn to. + \param border specifiys if a flat 3d border should be drawn. + This is usually not necesarry unless you don't place the control directly into the environment without a window as parent. + \param id is a s32 to identify the tab control. + \return + Returns a pointer to the created tab control element. Returns 0 if an error occured. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IGUITabControl* addTabControl(const core::rect& rectangle, + IGUIElement* parent=0, bool fillbackground=false, + bool border=true, s32 id=-1) = 0; + + //! Adds tab to the environment. + /** You can use this element to group other elements. This is not used for creating tabs on tab controls, + please use IGUITabControl::addTab() for this instead. + \param rectangle is the position of the tab. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the tab directly in the environment. + \param id is a s32 to identify the tab. */ + virtual IGUITab* addTab(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a context menu to the environment. + /** \param rectangle is the position of the menu. Note that the menu is + resizing itself based on what items you add. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the menu directly in the environment. + \param id is a s32 to identify the menu. */ + virtual IGUIContextMenu* addContextMenu(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a menu to the environment. + /* This is like the menu you can find on top of most windows in modern graphical user interfaces. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the menu directly in the environment. + \param id is a s32 to identify the menu. */ + virtual IGUIContextMenu* addMenu(IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a toolbar to the environment. + /** It is like a menu is always placed on top + in its parent, and contains buttons. + \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the tool bar directly in the environment. + \param id is a s32 to identify the tool bar. */ + virtual IGUIToolBar* addToolBar(IGUIElement* parent=0, s32 id=-1) = 0; + + //! Adds a combo box to the environment. + /** \param parent is the parent item of the element. E.g. a window. Set it to 0 to place the combo box directly in the environment. + \param id is a s32 to identify the combo box. */ + virtual IGUIComboBox* addComboBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1) = 0; + + //! Returns the default element factory which can create all built in elements + virtual IGUIElementFactory* getDefaultGUIElementFactory() const = 0; + + //! Adds an element factory to the gui environment. + /** Use this to extend the gui environment with new element types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerGUIElementFactory(IGUIElementFactory* factoryToAdd) = 0; + + //! Returns amount of registered gui element factories. + virtual u32 getRegisteredGUIElementFactoryCount() const = 0; + + //! Returns a gui element factory by index + virtual IGUIElementFactory* getGUIElementFactory(u32 index) const = 0; + + //! Adds a GUI Element by its name + virtual IGUIElement* addGUIElement(const c8* elementName, IGUIElement* parent=0) = 0; + + //! Saves the current gui into a file. + //! \param filename: Name of the file. + //! \param start: The GUIElement to start with. Root if 0. + virtual bool saveGUI(const c8* filename, IGUIElement* start=0) = 0; + + //! Saves the current gui into a file. + //! \param file: The file to write to. + //! \param start: The GUIElement to start with. Root if 0. + virtual bool saveGUI(io::IWriteFile* file, IGUIElement* start=0) = 0; + + //! Loads the gui. Note that the current gui is not cleared before. + //! \param filename: Name of the file . + //! \param parent: Parent for the loaded GUI, root if 0. + virtual bool loadGUI(const c8* filename, IGUIElement* parent=0) = 0; + + //! Loads the gui. Note that the current gui is not cleared before. + //! \param file: The file to load from. + //! \param parent: Parent for the loaded GUI, root if 0. + virtual bool loadGUI(io::IReadFile* file, IGUIElement* parent=0) = 0; + + //! Writes attributes of the gui environment + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const =0; + + //! Reads attributes of the gui environment + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)=0; + + //! writes an element + virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) =0; + + //! reads an element + virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* parent) =0; + +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIFileOpenDialog.h b/src/dep/include/irrlicht/IGUIFileOpenDialog.h new file mode 100644 index 0000000..30c26b9 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIFileOpenDialog.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ +#define __I_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Standard file chooser dialog. + class IGUIFileOpenDialog : public IGUIElement + { + public: + + //! constructor + IGUIFileOpenDialog(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_FILE_OPEN_DIALOG, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIFileOpenDialog() {} + + //! Returns the filename of the selected file. Returns NULL, if no file was selected. + virtual const wchar_t* getFileName() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIFont.h b/src/dep/include/irrlicht/IGUIFont.h new file mode 100644 index 0000000..ec942e5 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIFont.h @@ -0,0 +1,95 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FONT_H_INCLUDED__ +#define __I_GUI_FONT_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SColor.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + +//! An enum for the different types of GUI font. +enum EGUI_FONT_TYPE +{ + //! Bitmap fonts loaded from an XML file or a texture. + EGFT_BITMAP = 0, + + //! Scalable vector fonts loaded from an XML file. + //! These fonts reside in system memory and use no video memory + //! until they are displayed. These are slower than bitmap fonts + //! but can be easily scaled and rotated. + EGFT_VECTOR, + + //! A font which uses a the native API provided by the operating system. + //! Currently not used. + EGFT_OS, + + //! An external font type provided by the user. + EGFT_CUSTOM +}; + +//! Font interface. +class IGUIFont : public virtual IReferenceCounted +{ +public: + + //! Destructor + virtual ~IGUIFont() {} + + //! Draws an text and clips it to the specified rectangle if wanted. + /** \param text: Text to draw + \param position: Rectangle specifying position where to draw the text. + \param color: Color of the text + \param hcenter: Specifiies if the text should be centered horizontally into the rectangle. + \param vcenter: Specifiies if the text should be centered vertically into the rectangle. + \param clip: Optional pointer to a rectangle against which the text will be clipped. + If the pointer is null, no clipping will be done. */ + virtual void draw(const wchar_t* text, const core::rect& position, + video::SColor color, bool hcenter=false, bool vcenter=false, + const core::rect* clip=0) = 0; + + //! Calculates the dimension of a text. + /** \return Returns width and height of the area covered by the text if it would be + drawn. */ + virtual core::dimension2d getDimension(const wchar_t* text) const = 0; + + //! Calculates the index of the character in the text which is on a specific position. + /** \param text: Text string. + \param pixel_x: X pixel position of which the index of the character will be returned. + \return Returns zero based index of the character in the text, and -1 if no no character + is on this position. (=the text is too short). */ + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const = 0; + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_CUSTOM; } + + //! Sets global kerning for the font. + virtual void setKerningWidth (s32 kerning) = 0; + virtual void setKerningHeight (s32 kerning) = 0; + + //! Gets kerning values (distance between letters) for the font. If no parameters are provided, + /** the global kerning distance is returned. + \param thisLetter: If this parameter is provided, the left side kerning for this letter is added + to the global kerning value. For example, a space might only be one pixel wide, but it may + be displayed as several pixels. + \param previousLetter: If provided, kerning is calculated for both letters and added to the global + kerning value. For example, in a font which supports kerning pairs a string such as 'Wo' may have + the 'o' tucked neatly under the 'W'. + */ + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const = 0; + + //! Returns the distance between letters + virtual s32 getKerningHeight() const = 0; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIFontBitmap.h b/src/dep/include/irrlicht/IGUIFontBitmap.h new file mode 100644 index 0000000..4a4a22f --- /dev/null +++ b/src/dep/include/irrlicht/IGUIFontBitmap.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_FONT_BITMAP_H_INCLUDED__ +#define __I_GUI_FONT_BITMAP_H_INCLUDED__ + +#include "IGUIFont.h" + +namespace irr +{ +namespace gui +{ + class IGUISpriteBank; + +//! Font interface. +class IGUIFontBitmap : public IGUIFont +{ +public: + + //! Destructor + virtual ~IGUIFontBitmap() {} + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; } + + //! returns the parsed Symbol Information + virtual IGUISpriteBank* getSpriteBank() const = 0; + + //! returns the sprite number from a given character + virtual u32 getSpriteNoFromChar(const wchar_t *c) const = 0; + + //! Gets kerning values (distance between letters) for the font. If no parameters are provided, + /** the global kerning distance is returned. + \param thisLetter: If this parameter is provided, the left side kerning for this letter is added + to the global kerning value. For example, a space might only be one pixel wide, but it may + be displayed as several pixels. + \param previousLetter: If provided, kerning is calculated for both letters and added to the global + kerning value. For example, EGFT_BITMAP will add the right kerning value of previousLetter to the + left side kerning value of thisLetter, then add the global value. + */ + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const = 0; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIImage.h b/src/dep/include/irrlicht/IGUIImage.h new file mode 100644 index 0000000..dcb5ad0 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIImage.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_IMAGE_H_INCLUDED__ +#define __I_GUI_IMAGE_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} +namespace gui +{ + + //! GUI element displaying an image. + class IGUIImage : public IGUIElement + { + public: + + //! constructor + IGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_IMAGE, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIImage() {} + + //! Sets an image + virtual void setImage(video::ITexture* image) = 0; + + //! Sets the colour of the image + virtual void setColor(video::SColor color) = 0; + + //! Sets if the image should scale to fit the element + virtual void setScaleImage(bool scale) = 0; + + //! Sets if the image should use its alpha channel to draw itself + virtual void setUseAlphaChannel(bool use) = 0; + + //! Returns true if the image is scaled to fit, false if not + virtual bool isImageScaled() const = 0; + + //! Returns true if the image is using the alpha channel, false if not + virtual bool isAlphaChannelUsed() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIInOutFader.h b/src/dep/include/irrlicht/IGUIInOutFader.h new file mode 100644 index 0000000..6661645 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIInOutFader.h @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_IN_OUT_FADER_H_INCLUDED__ +#define __I_GUI_IN_OUT_FADER_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + + //! Element for fading out or in + /** Here is a small example on how the class is used. In this example we fade + in from a total red screen in the beginning. As you can see, the fader is not + only useful for dramatic in and out fading, but also to show that the player + is hit in a first person shooter game for example. + \code + gui::IGUIInOutFader* fader = device->getGUIEnvironment()->addInOutFader(); + fader->setColor(video::SColor(0,255,0,0)); + fader->fadeIn(4000); + \endcode + */ + class IGUIInOutFader : public IGUIElement + { + public: + + //! constructor + IGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_IN_OUT_FADER, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIInOutFader() {} + + //! Gets the color to fade out to or to fade in from. + virtual video::SColor getColor() const = 0; + + //! Sets the color to fade out to or to fade in from. + //! \param color: Color to where it is faded out od from it is faded in. + virtual void setColor(video::SColor color) = 0; + virtual void setColor(video::SColor source, video::SColor dest) = 0; + + //! Starts the fade in process. In the beginning the whole rect is drawn by + //! the set color (black by default) and at the end of the overgiven + //! time the color has faded out. + //! \param time: Time specifing how long it should need to fade in, + //! in milliseconds. + virtual void fadeIn(u32 time) = 0; + + //! Starts the fade out process. In the beginning everything is visible, + //! and at the end of the time only the set color (black by the fault) + //! will be drawn. + //! \param time: Time specifing how long it should need to fade out, + //! in milliseconds. + virtual void fadeOut(u32 time) = 0; + + //! Returns if the fade in or out process is done. + virtual bool isReady() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIListBox.h b/src/dep/include/irrlicht/IGUIListBox.h new file mode 100644 index 0000000..0b3cb0f --- /dev/null +++ b/src/dep/include/irrlicht/IGUIListBox.h @@ -0,0 +1,126 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_LIST_BOX_H_INCLUDED__ +#define __I_GUI_LIST_BOX_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + class IGUISpriteBank; + + //! Enumeration for listbox colors + enum EGUI_LISTBOX_COLOR + { + //! Color of text + EGUI_LBC_TEXT=0, + //! Color of selected text + EGUI_LBC_TEXT_HIGHLIGHT, + //! Color of icon + EGUI_LBC_ICON, + //! Color of selected icon + EGUI_LBC_ICON_HIGHLIGHT, + //! Not used, just counts the number of available colors + EGUI_LBC_COUNT + }; + + + //! Default list box GUI element. + class IGUIListBox : public IGUIElement + { + public: + //! constructor + IGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_LIST_BOX, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIListBox() {} + + //! returns amount of list items + virtual u32 getItemCount() const = 0; + + //! returns string of a list item. the may id be a value from 0 to itemCount-1 + virtual const wchar_t* getListItem(u32 id) const = 0; + + //! adds an list item, returns id of item + virtual u32 addItem(const wchar_t* text) = 0; + + //! adds an list item with an icon + //! \param text Text of list entry + //! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon + //! \return + //! returns the id of the new created item + virtual u32 addItem(const wchar_t* text, s32 icon) = 0; + + //! Removes an item from the list + virtual void removeItem(u32 index) = 0; + + //! Returns the icon of an item + virtual s32 getIcon(u32 index) const = 0; + + //! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of + //! the built-in-font by default. A sprite can be displayed in front of every list item. + //! An icon is an index within the icon sprite bank. Several default icons are available in the + //! skin through getIcon + virtual void setSpriteBank(IGUISpriteBank* bank) = 0; + + //! clears the list, deletes all items in the listbox + virtual void clear() = 0; + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const = 0; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 index) = 0; + + //! set whether the listbox should scroll to show a newly selected item + //! or a new item as it is added to the list. + virtual void setAutoScrollEnabled(bool scroll) = 0; + + //! returns true if automatic scrolling is enabled, false if not. + virtual bool isAutoScrollEnabled() const = 0; + + //! set all item colors at given index to color + virtual void setItemOverrideColor(u32 index, const video::SColor &color) = 0; + + //! set all item colors of specified type at given index to color + virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, const video::SColor &color) = 0; + + //! clear all item colors at index + virtual void clearItemOverrideColor(u32 index) = 0; + + //! clear item color at index for given colortype + virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) = 0; + + //! has the item at index it's color overwritten? + virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const = 0; + + //! return the overwrite color at given item index. + virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const = 0; + + //! return the default color which is used for the given colorType + virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const = 0; + + //! set the item at the given index + virtual void setItem(u32 index, const wchar_t* text, s32 icon) = 0; + + //! Insert the item at the given index + //! Return the index on success or -1 on failure. + virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon) = 0; + + //! Swap the items at the given indices + virtual void swapItems(u32 index1, u32 index2) = 0; +}; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIMeshViewer.h b/src/dep/include/irrlicht/IGUIMeshViewer.h new file mode 100644 index 0000000..5500cc8 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIMeshViewer.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_MESH_VIEWER_H_INCLUDED__ +#define __I_GUI_MESH_VIEWER_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ + +namespace video +{ + class SMaterial; +} // end namespace video + +namespace scene +{ + class IAnimatedMesh; +} // end namespace scene + +namespace gui +{ + + //! 3d mesh viewing GUI element. + class IGUIMeshViewer : public IGUIElement + { + public: + + //! constructor + IGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_MESH_VIEWER, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIMeshViewer() {} + + //! Sets the mesh to be shown + virtual void setMesh(scene::IAnimatedMesh* mesh) = 0; + + //! Gets the displayed mesh + virtual scene::IAnimatedMesh* getMesh() const = 0; + + //! Sets the material + virtual void setMaterial(const video::SMaterial& material) = 0; + + //! Gets the material + virtual const video::SMaterial& getMaterial() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIScrollBar.h b/src/dep/include/irrlicht/IGUIScrollBar.h new file mode 100644 index 0000000..0d6dca3 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIScrollBar.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SCROLL_BAR_H_INCLUDED__ +#define __I_GUI_SCROLL_BAR_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + //! Default scroll bar GUI element. + class IGUIScrollBar : public IGUIElement + { + public: + + //! constructor + IGUIScrollBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_SCROLL_BAR, environment, parent, id, rectangle) {} + + //! destructor + ~IGUIScrollBar() {}; + + //! gets the maximum value of the scrollbar. + virtual s32 getMax() const = 0; + + //! sets the maximum value of the scrollbar. + virtual void setMax(s32 max) = 0; + + //! gets the small step value + virtual s32 getSmallStep() const = 0; + + //! Sets the small step, the amount that the value changes by when clicking + //! on the buttons or using the cursor keys. + virtual void setSmallStep(s32 step) = 0; + + //! gets the large step value + virtual s32 getLargeStep() const = 0; + + //! Sets the large step, the amount that the value changes by when clicking + //! in the tray, or using the page up and page down keys. + virtual void setLargeStep(s32 step) = 0; + + //! gets the current position of the scrollbar + virtual s32 getPos() const = 0; + + //! sets the current position of the scrollbar + virtual void setPos(s32 pos) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUISkin.h b/src/dep/include/irrlicht/IGUISkin.h new file mode 100644 index 0000000..1ccfded --- /dev/null +++ b/src/dep/include/irrlicht/IGUISkin.h @@ -0,0 +1,515 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_SKIN_H_INCLUDED__ +#define __I_GUI_SKIN_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "SColor.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + class IGUISpriteBank; + class IGUIElement; + + //! Enumeration of available default skins. + /** To set one of the skins, use the following code, for example to set + the Windows classic skin: + \code + gui::IGUISkin* newskin = environment->createSkin(gui::EGST_WINDOWS_CLASSIC); + environment->setSkin(newskin); + newskin->drop(); + \endcode + */ + enum EGUI_SKIN_TYPE + { + //! Default windows look and feel + EGST_WINDOWS_CLASSIC=0, + //! Like EGST_WINDOWS_CLASSIC, but with metallic shaded windows and buttons + EGST_WINDOWS_METALLIC, + //! Burning's skin + EGST_BURNING_SKIN, + + //! An unknown skin, not serializable at present + EGST_UNKNOWN + }; + + //! Names for gui element types + const c8* const GUISkinTypeNames[] = + { + "windowsClassic", + "windowsMetallic", + "burning", + "unknown", + 0, + }; + + + //! Enumeration for skin colors + enum EGUI_DEFAULT_COLOR + { + //! Dark shadow for three-dimensional display elements. + EGDC_3D_DARK_SHADOW = 0, + //! Shadow color for three-dimensional display elements (for edges facing away from the light source). + EGDC_3D_SHADOW, + //! Face color for three-dimensional display elements and for dialog box backgrounds. + EGDC_3D_FACE, + //! Highlight color for three-dimensional display elements (for edges facing the light source.) + EGDC_3D_HIGH_LIGHT, + //! Light color for three-dimensional display elements (for edges facing the light source.) + EGDC_3D_LIGHT, + //! Active window border. + EGDC_ACTIVE_BORDER, + //! Active window title bar text. + EGDC_ACTIVE_CAPTION, + //! Background color of multiple document interface (MDI) applications. + EGDC_APP_WORKSPACE, + //! Text on a button + EGDC_BUTTON_TEXT, + //! Grayed (disabled) text. + EGDC_GRAY_TEXT, + //! Item(s) selected in a control. + EGDC_HIGH_LIGHT, + //! Text of item(s) selected in a control. + EGDC_HIGH_LIGHT_TEXT, + //! Inactive window border. + EGDC_INACTIVE_BORDER, + //! Inactive window caption. + EGDC_INACTIVE_CAPTION, + //! Tool tip text color + EGDC_TOOLTIP, + //! Tool tip background color + EGDC_TOOLTIP_BACKGROUND, + //! Scrollbar gray area + EGDC_SCROLLBAR, + //! Window background + EGDC_WINDOW, + //! Window symbols like on close buttons, scroll bars and check boxes + EGDC_WINDOW_SYMBOL, + //! Icons in a list or tree + EGDC_ICON, + //! Selected icons in a list or tree + EGDC_ICON_HIGH_LIGHT, + //! this value is not used, it only specifies the amount of default colors + //! available. + EGDC_COUNT + }; + + //! Names for default skin colors + const c8* const GUISkinColorNames[] = + { + "3DDarkShadow", + "3DShadow", + "3DFace", + "3DHighlight", + "3DLight", + "ActiveBorder", + "ActiveCaption", + "AppWorkspace", + "ButtonText", + "GrayText", + "Highlight", + "HighlightText", + "InactiveBorder", + "InactiveCaption", + "ToolTip", + "ToolTipBackground", + "ScrollBar", + "Window", + "WindowSymbol", + "Icon", + "IconHighlight", + 0, + }; + + //! Enumeration for default sizes. + enum EGUI_DEFAULT_SIZE + { + //! default with / height of scrollbar + EGDS_SCROLLBAR_SIZE = 0, + //! height of menu + EGDS_MENU_HEIGHT, + //! width of a window button + EGDS_WINDOW_BUTTON_WIDTH, + //! width of a checkbox check + EGDS_CHECK_BOX_WIDTH, + //! width of a messagebox + EGDS_MESSAGE_BOX_WIDTH, + //! height of a messagebox + EGDS_MESSAGE_BOX_HEIGHT, + //! width of a default button + EGDS_BUTTON_WIDTH, + //! height of a default button + EGDS_BUTTON_HEIGHT, + //! distance for text from background + EGDS_TEXT_DISTANCE_X, + //! distance for text from background + EGDS_TEXT_DISTANCE_Y, + //! this value is not used, it only specifies the amount of default sizes + //! available. + EGDS_COUNT + }; + + + //! Names for default skin sizes + const c8* const GUISkinSizeNames[] = + { + "ScrollBarSize", + "MenuHeight", + "WindowButtonWidth", + "CheckBoxWidth", + "MessageBoxWidth", + "MessageBoxHeight", + "ButtonWidth", + "ButtonHeight", + "TextDistanceX", + "TextDistanceY", + 0, + }; + + + enum EGUI_DEFAULT_TEXT + { + //! Text for the OK button on a message box + EGDT_MSG_BOX_OK = 0, + //! Text for the Cancel button on a message box + EGDT_MSG_BOX_CANCEL, + //! Text for the Yes button on a message box + EGDT_MSG_BOX_YES, + //! Text for the No button on a message box + EGDT_MSG_BOX_NO, + //! Tooltip text for window close button + EGDT_WINDOW_CLOSE, + //! Tooltip text for window maximize button + EGDT_WINDOW_MAXIMIZE, + //! Tooltip text for window minimize button + EGDT_WINDOW_MINIMIZE, + //! Tooltip text for window restore button + EGDT_WINDOW_RESTORE, + + //! this value is not used, it only specifies the number of default texts + EGDT_COUNT + }; + + //! Names for default skin sizes + const c8* const GUISkinTextNames[] = + { + "MessageBoxOkay", + "MessageBoxCancel", + "MessageBoxYes", + "MessageBoxNo", + "WindowButtonClose", + "WindowButtonMaximize", + "WindowButtonMinimize", + "WindowButtonRestore", + 0, + }; + + //! Customizable symbols for GUI + enum EGUI_DEFAULT_ICON + { + //! maximize window button + EGDI_WINDOW_MAXIMIZE = 0, + //! restore window button + EGDI_WINDOW_RESTORE, + //! close window button + EGDI_WINDOW_CLOSE, + //! minimize window button + EGDI_WINDOW_MINIMIZE, + //! resize icon for bottom right corner of a window + EGDI_WINDOW_RESIZE, + //! scroll bar up button + EGDI_CURSOR_UP, + //! scroll bar down button + EGDI_CURSOR_DOWN, + //! scroll bar left button + EGDI_CURSOR_LEFT, + //! scroll bar right button + EGDI_CURSOR_RIGHT, + //! icon for menu children + EGDI_MENU_MORE, + //! tick for checkbox + EGDI_CHECK_BOX_CHECKED, + //! down arrow for dropdown menus + EGDI_DROP_DOWN, + //! smaller up arrow + EGDI_SMALL_CURSOR_UP, + //! smaller down arrow + EGDI_SMALL_CURSOR_DOWN, + //! selection dot in a radio button + EGDI_RADIO_BUTTON_CHECKED, + //! << icon indicating there is more content to the left + EGDI_MORE_LEFT, + //! >> icon indicating that there is more content to the right + EGDI_MORE_RIGHT, + //! icon indicating that there is more content above + EGDI_MORE_UP, + //! icon indicating that there is more content below + EGDI_MORE_DOWN, + //! plus icon for trees + EGDI_EXPAND, + //! minus icon for trees + EGDI_COLLAPSE, + //! file icon for file selection + EGDI_FILE, + //! folder icon for file selection + EGDI_DIRECTORY, + + //! value not used, it only specifies the number of icons + EGDI_COUNT + }; + + const c8* const GUISkinIconNames[] = + { + "windowMaximize", + "windowRestore", + "windowClose", + "windowMinimize", + "windowResize", + "cursorUp", + "cursorDown", + "cursorLeft", + "cursorRight", + "menuMore", + "checkBoxChecked", + "dropDown", + "smallCursorUp", + "smallCursorDown", + "radioButtonChecked", + "moreLeft", + "moreRight", + "moreUp", + "moreDown", + "expand", + "collapse", + "file", + "directory", + 0 + }; + + // Customizable fonts + enum EGUI_DEFAULT_FONT + { + //! For static text, edit boxes, lists and most other places + EGDF_DEFAULT=0, + //! Font for buttons + EGDF_BUTTON, + //! Font for window title bars + EGDF_WINDOW, + //! Font for menu items + EGDF_MENU, + //! Font for tooltips + EGDF_TOOLTIP, + //! this value is not used, it only specifies the amount of default fonts + //! available. + EGDF_COUNT + }; + + const c8* const GUISkinFontNames[] = + { + "defaultFont", + "buttonFont", + "windowFont", + "menuFont", + "tooltipFont", + 0 + }; + + //! A skin modifies the look of the GUI elements. + class IGUISkin : public virtual io::IAttributeExchangingObject + { + public: + + //! destructor + virtual ~IGUISkin() {}; + + //! returns default color + virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const = 0; + + //! sets a default color + virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) = 0; + + //! returns size for the given size type + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const = 0; + + //! Returns a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const = 0; + + //! Sets a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) = 0; + + //! sets a default size + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size) = 0; + + //! returns the default font + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const = 0; + + //! sets a default font + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT) = 0; + + //! returns the sprite bank + virtual IGUISpriteBank* getSpriteBank() const = 0; + + //! sets the sprite bank + virtual void setSpriteBank(IGUISpriteBank* bank) = 0; + + //! Returns a default icon + /** Returns the sprite index within the sprite bank */ + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const = 0; + + //! Sets a default icon + /** Sets the sprite index used for drawing icons like arrows, + close buttons and ticks in checkboxes + \param icon: Enum specifying which icon to change + \param index: The sprite index used to draw this icon */ + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index) = 0; + + //! draws a standard 3d button pane + /** Used for drawing for example buttons in normal state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a pressed 3d button pane + /** Used for drawing for example buttons in pressed state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a sunken 3d pane + /** Used for drawing the background of edit, combo or check boxes. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param bgcolor: Background color. + \param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. + \param fillBackGround: Specifies if the background should be filled with the background + color or not be drawn at all. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, bool fillBackGround, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a window background + /** Used for drawing the background of dialogs and windows. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param titleBarColor: Title color. + \param drawTitleBar: True to enable title drawing. + \param rect: Defining area where to draw. + \param clip: Clip area. + \return Returns rect where it would be good to draw title bar text. */ + virtual core::rect draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a standard 3d menu pane + /** Used for drawing for menus and context menus. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a standard 3d tool bar + /** Used for drawing for toolbars and menus. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DToolBar(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0) = 0; + + //! draws a tab button + /** Used for drawing for tab buttons on top of tabs. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param active: Specifies if the tab is currently active. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect& rect, const core::rect* clip=0) = 0; + + //! draws a tab control body + /** \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by IGUISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param border: Specifies if the border should be drawn. + \param background: Specifies if the background should be drawn. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip=0) = 0; + + //! draws an icon, usually from the skin's sprite bank + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param icon: Specifies the icon to be drawn. + \param position: The position to draw the icon + \param starttime: The time at the start of the animation + \param currenttime: The present time, used to calculate the frame number + \param loop: Whether the animation should loop or not + \param clip: Clip area. */ + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect* clip=0) = 0; + + //! draws a 2d rectangle. + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param color: Color of the rectangle to draw. The alpha component specifies how + transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color, + const core::rect& pos, const core::rect* clip = 0) = 0; + + //! get the type of this skin + virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; }; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUISpinBox.h b/src/dep/include/irrlicht/IGUISpinBox.h new file mode 100644 index 0000000..93cc033 --- /dev/null +++ b/src/dep/include/irrlicht/IGUISpinBox.h @@ -0,0 +1,70 @@ +// Copyright (C) 2006 Michael Zeilfelder +// This file uses the licence of the Irrlicht Engine. + +#ifndef __I_GUI_SPIN_BOX_H_INCLUDED__ +#define __I_GUI_SPIN_BOX_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + class IGUIEditBox; + + //! Single line edit box + spin buttons + class IGUISpinBox : public IGUIElement + { + public: + + //! constructor + IGUISpinBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : IGUIElement(EGUIET_SPIN_BOX, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUISpinBox() {} + + //! Access the edit box used in the spin control + /** \param enable: If set to true, the override color, which can be set + with IGUIEditBox::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual IGUIEditBox* getEditBox() const = 0; + + //! set the current value of the spinbox + /** \param val: value to be set in the spinbox */ + virtual void setValue(f32 val) = 0; + + //! Get the current value of the spinbox + virtual f32 getValue() const = 0; + + //! set the range of values which can be used in the spinbox + /** \param min: minimum value + \param max: maximum value */ + virtual void setRange(f32 min, f32 max) = 0; + + //! get the minimum value which can be used in the spinbox + virtual f32 getMin() const = 0; + + //! get the maximum value which can be used in the spinbox + virtual f32 getMax() const = 0; + + //! Step size by which values are changed when pressing the spinbuttons + /** The step size also determines the number of decimal places to display + \param step: stepsize used for value changes when pressing spinbuttons */ + virtual void setStepSize(f32 step=1.f) = 0; + + //! Sets the number of decimal places to display. + /** \param places: The number of decimal places to display, use -1 to reset */ + virtual void setDecimalPlaces(s32 places) = 0; + + //! get the current step size + virtual f32 getStepSize() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_SPIN_BOX_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IGUISpriteBank.h b/src/dep/include/irrlicht/IGUISpriteBank.h new file mode 100644 index 0000000..cd01763 --- /dev/null +++ b/src/dep/include/irrlicht/IGUISpriteBank.h @@ -0,0 +1,73 @@ + +#ifndef __I_GUI_SPRITE_BANK_H_INCLUDED__ +#define __I_GUI_SPRITE_BANK_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "SColor.h" +#include "rect.h" + +namespace irr +{ + +namespace video +{ + class ITexture; +} // end namespace video + +namespace gui +{ + +struct SGUISpriteFrame +{ + u32 textureNumber; + u32 rectNumber; +}; + +struct SGUISprite +{ + SGUISprite() : Frames(), frameTime(0) { }; + core::array Frames; + u32 frameTime; +}; + + +//! Sprite bank interface. +class IGUISpriteBank : public virtual IReferenceCounted +{ +public: + + //! Destructor + virtual ~IGUISpriteBank() {} + + //! Returns the list of rectangles held by the sprite bank + virtual core::array< core::rect >& getPositions() = 0; + + //! Returns the array of animated sprites within the sprite bank + virtual core::array< SGUISprite >& getSprites() = 0; + + //! Returns the number of textures held by the sprite bank + virtual u32 getTextureCount() const = 0; + + //! Gets the texture with the specified index + virtual video::ITexture* getTexture(u32 index) const = 0; + + //! Adds a texture to the sprite bank + virtual void addTexture(video::ITexture* texture) = 0; + + //! Changes one of the textures in the sprite bank + virtual void setTexture(u32 index, video::ITexture* texture) = 0; + + //! Draws a sprite in 2d with position and color + virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false) = 0; + +}; + + +} // end namespace gui +} // end namespace irr + +#endif // __I_GUI_SPRITE_BANK_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IGUIStaticText.h b/src/dep/include/irrlicht/IGUIStaticText.h new file mode 100644 index 0000000..8041ffb --- /dev/null +++ b/src/dep/include/irrlicht/IGUIStaticText.h @@ -0,0 +1,104 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_STATIC_TEXT_H_INCLUDED__ +#define __I_GUI_STATIC_TEXT_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + class IGUIFont; + + //! Multi or single line text label. + class IGUIStaticText : public IGUIElement + { + public: + + //! constructor + IGUIStaticText(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_STATIC_TEXT, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIStaticText() {} + + //! Sets another skin independent font. + /** If this is set to zero, the button uses the font of the skin. + \param font: New font to set. */ + virtual void setOverrideFont(IGUIFont* font=0) = 0; + + //! Gets the override font (if any) + //! \return The override font (may be 0) + virtual IGUIFont* getOverrideFont(void) const = 0; + + //! Sets another color for the text. + /** If set, the static text does not use the EGDC_BUTTON_TEXT color defined + in the skin, but the set color instead. You don't need to call + IGUIStaticText::enableOverrrideColor(true) after this, this is done + by this function. + If you set a color, and you want the text displayed with the color + of the skin again, call IGUIStaticText::enableOverrideColor(false); + \param color: New color of the text. */ + virtual void setOverrideColor(video::SColor color) = 0; + + //! Gets the override color + //! \return: The override color + virtual video::SColor const& getOverrideColor(void) const = 0; + + //! Sets if the static text should use the overide color or the color in the gui skin. + /** \param enable: If set to true, the override color, which can be set + with IGUIStaticText::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual void enableOverrideColor(bool enable) = 0; + + //! Checks if an override color is enabled + //! \return true if the override color is enabled, false otherwise + virtual bool isOverrideColorEnabled(void) const = 0; + + //! Sets another color for the background. + virtual void setBackgroundColor(video::SColor color) = 0; + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw) = 0; + + //! Sets whether to draw the border + virtual void setDrawBorder(bool draw) = 0; + + //! Sets text justification mode + /** \param horizontal: EGUIA_UPPERLEFT for left justified (default), + EGUIA_LOWEERRIGHT for right justified, or EGUIA_CENTER for centered text. + \param vertical: EGUIA_UPPERLEFT to align with top edge, + EGUIA_LOWEERRIGHT for bottom edge, or EGUIA_CENTER for centered text (default). */ + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) = 0; + + //! Enables or disables word wrap for using the static text as multiline text control. + /** \param enable: If set to true, words going over one line are + broken on to the next line. */ + virtual void setWordWrap(bool enable) = 0; + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled(void) const = 0; + + //! Returns the height of the text in pixels when it is drawn. + /** This is useful for adjusting the layout of gui elements based on the height + of the multiline text in this element. + \return Returns height of text in pixels. */ + virtual s32 getTextHeight() const = 0; + + //! Returns the width of the current text, in the current font + /** If the text is broken, this returns the width of the widest line + \return The width of the text, or the widest broken line. */ + virtual s32 getTextWidth(void) const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUITabControl.h b/src/dep/include/irrlicht/IGUITabControl.h new file mode 100644 index 0000000..a296fd9 --- /dev/null +++ b/src/dep/include/irrlicht/IGUITabControl.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TAB_CONTROL_H_INCLUDED__ +#define __I_GUI_TAB_CONTROL_H_INCLUDED__ + +#include "IGUIElement.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + //! A tab, onto which other gui elements could be added. + class IGUITab : public IGUIElement + { + public: + + //! constructor + IGUITab(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_TAB, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUITab() {} + + //! Returns number of tab if in tabcontrol. + /** Can be accessed later IGUITabControl::getTab() by this number. */ + virtual s32 getNumber() const = 0; + + //! sets if the tab should draw its background + virtual void setDrawBackground(bool draw=true) = 0; + + //! sets the color of the background, if it should be drawn. + virtual void setBackgroundColor(video::SColor c) = 0; + + //! returns true if the tab is drawing its background, false if not + virtual bool isDrawingBackground() const = 0; + + //! returns the color of the background + virtual video::SColor getBackgroundColor() const = 0; + }; + + //! A standard tab control + class IGUITabControl : public IGUIElement + { + public: + + //! constructor + IGUITabControl(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_TAB_CONTROL, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUITabControl() {} + + //! Adds a tab + virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1) = 0; + + //! Returns amount of tabs in the tabcontrol + virtual s32 getTabCount() const = 0; + + //! Returns a tab based on zero based index + /** \param idx: zero based index of tab. Is a value betwenn 0 and getTabcount()-1; + \return Returns pointer to the Tab. Returns 0 if no tab + is corresponding to this tab. */ + virtual IGUITab* getTab(s32 idx) const = 0; + + //! Brings a tab to front. + /** \param idx: number of the tab. + \return Returns true if successful. */ + virtual bool setActiveTab(s32 idx) = 0; + + //! Brings a tab to front. + /** \param tab: pointer to the tab. + \return Returns true if successful. */ + virtual bool setActiveTab(IGUIElement *tab) = 0; + + //! Returns which tab is currently active + virtual s32 getActiveTab() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIToolbar.h b/src/dep/include/irrlicht/IGUIToolbar.h new file mode 100644 index 0000000..f174d0d --- /dev/null +++ b/src/dep/include/irrlicht/IGUIToolbar.h @@ -0,0 +1,43 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_TOOL_BAR_H_INCLUDED__ +#define __I_GUI_TOOL_BAR_H_INCLUDED__ + +#include "IGUIElement.h" + +namespace irr +{ +namespace video +{ + class ITexture; +} // end namespace video +namespace gui +{ + class IGUIButton; + + //! Stays at the top of its parent like the menu bar and contains tool buttons + class IGUIToolBar : public IGUIElement + { + public: + + //! constructor + IGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_TOOL_BAR, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIToolBar() {} + + //! Adds a button to the tool bar + virtual IGUIButton* addButton(s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext=0, + video::ITexture* img=0, video::ITexture* pressedimg=0, + bool isPushButton=false, bool useAlphaChannel=false) = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IGUIWindow.h b/src/dep/include/irrlicht/IGUIWindow.h new file mode 100644 index 0000000..1ee7c07 --- /dev/null +++ b/src/dep/include/irrlicht/IGUIWindow.h @@ -0,0 +1,44 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_GUI_WINDOW_H_INCLUDED__ +#define __I_GUI_WINDOW_H_INCLUDED__ + +#include "IGUIElement.h" +#include "EMessageBoxFlags.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + + //! Default moveable window GUI element with border, caption and close icons. + class IGUIWindow : public IGUIElement + { + public: + + //! constructor + IGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_WINDOW, environment, parent, id, rectangle) {} + + //! destructor + virtual ~IGUIWindow() {} + + //! Returns pointer to the close button + virtual IGUIButton* getCloseButton() const = 0; + + //! Returns pointer to the minimize button + virtual IGUIButton* getMinimizeButton() const = 0; + + //! Returns pointer to the maximize button + virtual IGUIButton* getMaximizeButton() const = 0; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IImage.h b/src/dep/include/irrlicht/IImage.h new file mode 100644 index 0000000..7167656 --- /dev/null +++ b/src/dep/include/irrlicht/IImage.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IMAGE_H_INCLUDED__ +#define __I_IMAGE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "position2d.h" +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! An enum for the color format of textures used by the Irrlicht Engine. +/** A color format specifies how color information is stored. */ +enum ECOLOR_FORMAT +{ + //! 16 bit color format used by the software driver, and thus preferred + //! by all other irrlicht engine video drivers. There are 5 bits for every + //! color component, and a single bit is left for alpha information. + ECF_A1R5G5B5 = 0, + + //! Standard 16 bit color format. + ECF_R5G6B5, + + //! 24 bit color, no alpha channel, but 8 bit for red, green and blue. + ECF_R8G8B8, + + //! Default 32 bit color format. 8 bits are used for every component: + //! red, green, blue and alpha. + ECF_A8R8G8B8 +}; + + +//! Interface for software image data. +/** Image loaders create these images from files. IVideoDrivers convert +these images into their (hardware) textures. +*/ +class IImage : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IImage() {} + + //! Lock function. Use this to get a pointer to the image data. After you + //! don't need the pointer anymore, you must call unlock(). + //! \return Returns pointer to the image data. What type of data + //! is pointed to depends on the color format of the image. For example + //! if the color format is ECF_A8R8G8B8, it is of u32. + //! Be sure to call unlock() after you don't need the pointer any more. + virtual void* lock() = 0; + + //! Unlock function. + //! Should be called after the pointer received by lock() is not + //! needed anymore. + virtual void unlock() = 0; + + //! Returns width and height of image data. + virtual const core::dimension2d& getDimension() const = 0; + + //! Returns bits per pixel. + virtual u32 getBitsPerPixel() const = 0; + + //! Returns bytes per pixel + virtual u32 getBytesPerPixel() const = 0; + + //! Returns image data size in bytes + virtual u32 getImageDataSizeInBytes() const = 0; + + //! Returns image data size in pixels + virtual u32 getImageDataSizeInPixels() const = 0; + + //! returns a pixel + virtual SColor getPixel(u32 x, u32 y) const = 0; + + //! sets a pixel + virtual void setPixel(u32 x, u32 y, const SColor &color ) = 0; + + //! returns the color format + virtual ECOLOR_FORMAT getColorFormat() const = 0; + + //! returns mask for red value of a pixel + virtual u32 getRedMask() const = 0; + + //! returns mask for green value of a pixel + virtual u32 getGreenMask() const = 0; + + //! returns mask for blue value of a pixel + virtual u32 getBlueMask() const = 0; + + //! returns mask for alpha value of a pixel + virtual u32 getAlphaMask() const = 0; + + //! returns pitch of image + virtual u32 getPitch() const = 0; + + //! copies the image into the target, scaling the image to fit + virtual void copyToScaling(void* target, s32 width, s32 height, ECOLOR_FORMAT format=ECF_A8R8G8B8, u32 pitch=0) = 0; + + //! copies the image into the target, scaling the image to fit + virtual void copyToScaling(IImage* target) = 0; + +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IImageLoader.h b/src/dep/include/irrlicht/IImageLoader.h new file mode 100644 index 0000000..399c5b4 --- /dev/null +++ b/src/dep/include/irrlicht/IImageLoader.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SURFACE_LOADER_H_INCLUDED__ +#define __I_SURFACE_LOADER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IImage.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace video +{ + +//! Class which is able to create a image from a file. +/** If you want the Irrlicht Engine be able to load textures of +currently unsupported file formats (e.g .gif), then implement +this and add your new Surface loader with +IVideoDriver::addExternalImageLoader() to the engine. */ +class IImageLoader : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IImageLoader() {} + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const = 0; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const = 0; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IImageWriter.h b/src/dep/include/irrlicht/IImageWriter.h new file mode 100644 index 0000000..081b835 --- /dev/null +++ b/src/dep/include/irrlicht/IImageWriter.h @@ -0,0 +1,36 @@ +#ifndef _I_IMAGE_WRITER_H_INCLUDED__ +#define _I_IMAGE_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; +} // end namespace io + +namespace video +{ + class IImage; + + +//! Interface for writing software image data. +class IImageWriter : public IReferenceCounted +{ +public: + //! destructor + virtual ~IImageWriter() { } + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const = 0; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param = 0) const = 0; +}; + +} // namespace video +} // namespace irr + +#endif // _I_IMAGE_WRITER_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/ILightSceneNode.h b/src/dep/include/irrlicht/ILightSceneNode.h new file mode 100644 index 0000000..6a526dc --- /dev/null +++ b/src/dep/include/irrlicht/ILightSceneNode.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __I_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "SLight.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a dynamic light. +/** You can switch the light on and off by +making it visible or not, and let it be animated by ordinary scene node animators. +If you set the light type to be directional, you will need to set the direction of the +light source manually in the SLight structure, the position of the scene node will have no +effect on this direction. +*/ +class ILightSceneNode : public ISceneNode +{ +public: + + //! constructor + ILightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! Sets the light data associated with this ILightSceneNode + virtual void setLightData(const video::SLight& light) = 0; + + //! Gets the light data associated with this ILightSceneNode + //! \return Returns the light data. + virtual const video::SLight& getLightData() const = 0; + + //! Gets the light data associated with this ILightSceneNode + //! \return Returns the light data. + virtual video::SLight& getLightData() = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/ILogger.h b/src/dep/include/irrlicht/ILogger.h new file mode 100644 index 0000000..1aefb30 --- /dev/null +++ b/src/dep/include/irrlicht/ILogger.h @@ -0,0 +1,95 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_LOGGER_H_INCLUDED__ +#define __I_LOGGER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +enum ELOG_LEVEL +{ + //! High log level, warnings, errors and important information + //! texts are printed out. + ELL_INFORMATION = 0, + + //! Default log level, warnings and errors are printed out + ELL_WARNING, + + //! Low log level, only errors are printed into the log + ELL_ERROR, + + //! Nothing is printed out to the log + ELL_NONE +}; + + +//! Interface for logging messages, warnings and errors +class ILogger : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~ILogger() {} + + //! Returns the current set log level. + virtual ELOG_LEVEL getLogLevel() const = 0; + + //! Sets a new log level. With this value, texts which are sent to + //! the logger are filtered out. For example setting this value to + //! ELL_WARNING, only warnings and + //! errors are printed out. Setting it to ELL_INFORMATION, which is + //! the default setting, warnings, + //! errors and informational texts are printed out. + //! \param ll: new log level filter value. + virtual void setLogLevel(ELOG_LEVEL ll) = 0; + + //! Prints out a text into the log + //! \param text: Text to print out. + //! \param ll: Log level of the text. If the text is an error, set + //! it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + //! is just an informational text, set it to ELL_INFORMATION. Texts are + //! filtered with these levels. If you want to be a text displayed, + //! independent on what level filter is set, use ELL_NONE. + virtual void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + //! Prints out a text into the log + //! \param text: Text to print out. + //! \param hint: Additional info. This string is added after a " :" to the + //! string. + //! \param ll: Log level of the text. If the text is an error, set + //! it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + //! is just an informational text, set it to ELL_INFORMATION. Texts are + //! filtered with these levels. If you want to be a text displayed, + //! independent on what level filter is set, use ELL_NONE. + virtual void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + //! Prints out a text into the log + //! \param text: Text to print out. + //! \param hint: Additional info. This string is added after a " :" to the + //! string. + //! \param ll: Log level of the text. If the text is an error, set + //! it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + //! is just an informational text, set it to ELL_INFORMATION. Texts are + //! filtered with these levels. If you want to be a text displayed, + //! independent on what level filter is set, use ELL_NONE. + virtual void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) = 0; + + + //! Prints out a text into the log + //! \param text: Text to print out. + //! \param ll: Log level of the text. If the text is an error, set + //! it to ELL_ERROR, if it is warning set it to ELL_WARNING, and if it + //! is just an informational text, set it to ELL_INFORMATION. Texts are + //! filtered with these levels. If you want to be a text displayed, + //! independent on what level filter is set, use ELL_NONE. + virtual void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION) = 0; +}; + +} // end namespace + +#endif + diff --git a/src/dep/include/irrlicht/IMaterialRenderer.h b/src/dep/include/irrlicht/IMaterialRenderer.h new file mode 100644 index 0000000..2eff280 --- /dev/null +++ b/src/dep/include/irrlicht/IMaterialRenderer.h @@ -0,0 +1,97 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MATERIAL_RENDERER_H_INCLUDED__ +#define __I_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IMaterialRendererServices; + +//! Interface for material rendering. Can be used to extend the engine with new materials. +/** Refer to IVideoDriver::addMaterialRenderer() for more informations on how to extend the engine + with new materials. +*/ +class IMaterialRenderer : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IMaterialRenderer() {} + + //! Called by the IVideoDriver implementation the let the renderer set its needed render states. + /** This is called during the IVideoDriver::setMaterial() call. + When overriding this, you can set some renderstates or for example a vertex or pixel shader + if you like. + \param material: The new material parameters to be set. The renderer may change the material + flags in this material. For example if this material does not accept the zbuffer = true, it + can set it to false. This is useful, because in the next lastMaterial will be just the material + in this call. + \param lastMaterial: The material parameters which have been set before this material. + \param resetAllRenderstates: True if all renderstates should really be reset. This is usually + true if the last rendering mode was not a usual 3d rendering mode, but for example + a 2d rendering mode. + You should reset really all renderstates if this is true, no matter if the lastMaterial had + some similar settings. This is used because in most cases, some common renderstates are not + changed if they are already there, for example bilinear filtering, wireframe, gouraudshading, + lighting, zbuffer, zwriteenable, backfaceculling and fogenable. + \param services: Interface providing some methods for changing advanced, internal + states of a IVideoDriver. */ + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) {}; + + //! Called every time before a new bunch of geometry is being drawn using this material with + //! for example drawIndexedTriangleList() call. + /** OnSetMaterial should normally only be called if the renderer decides that the renderstates should be changed, it won't be called if for + example two drawIndexedTriangleList() will be called with the same material set. This + method will be called every time. This is useful for example for materials with shaders, + which don't only set new renderstates but also shader constants. + \param service: Pointer to interface providing methos for setting constants and other things. + \param vtxtype: Vertex type with which the next rendering will be done. This can be used + by the material renderer to set some specific optimized shaders or if this is an incompatible + vertex type for this renderer, to refuse rendering for example. + \return Returns true if everything is ok, and false if nothing should be rendered. + The material renderer can choose to return false for example if he doesn't support the + specified vertex type. This is actually done in D3D8 and D3D9 when using a + normal mapped material with a vertex type other than EVT_TANGENTS. */ + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) { return true; }; + + //! Called by the IVideoDriver to unset this material. + /** Called during the + IVideoDriver::setMaterial() call before the new material will get the OnSetMaterial() + call. */ + virtual void OnUnsetMaterial() {} + + //! Returns if the material is transparent. + /** The scene managment needs to know this + for being able to sort the materials by opaque and transparent. */ + virtual bool isTransparent() const { return false; } + + //! Returns the render capability of the material. + /** Because some more complex materials + are implemented in multiple ways and need special hardware capabilities, it is possible + to query how the current material renderer is performing on the current hardware with this + function. + \return Returns 0 if everything is running fine. Any other value is material renderer + specific and means for example that the renderer switched back to a fall back material because + it cannot use the latest shaders. More specific examples: + Fixed function pipeline materials should return 0 in most cases, parallax mapped + material will only return 0 when at least pixel shader 1.4 is available on that machine. */ + virtual s32 getRenderCapability() const { return 0; } +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMaterialRendererServices.h b/src/dep/include/irrlicht/IMaterialRendererServices.h new file mode 100644 index 0000000..f561a53 --- /dev/null +++ b/src/dep/include/irrlicht/IMaterialRendererServices.h @@ -0,0 +1,93 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MATERIAL_RENDERER_SERVICES_H_INCLUDED__ +#define __I_MATERIAL_RENDERER_SERVICES_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; + + +//! Interface providing some methods for changing advanced, internal states of a IVideoDriver. +class IMaterialRendererServices +{ +public: + + //! destructor + virtual ~IMaterialRendererServices() {} + + //! Can be called by an IMaterialRenderer to make its work easier. + //! Sets all basic renderstates if needed. + //! Basic render states are diffuse, ambient, specular, and emissive color, specular power, + //! bilinear and trilinear filtering, wireframe mode, + //! grouraudshading, lighting, zbuffer, zwriteenable, backfaceculling and fog enabling. + virtual void setBasicRenderStates(const SMaterial& material, + const SMaterial& lastMaterial, + bool resetAllRenderstates) = 0; + + //! Sets a constant for the vertex shader based on a name. This can be used if you used + //! a high level shader language like GLSL or HLSL to create a shader. Example: If you + //! created a shader which has variables named 'mWorldViewProj' (containing the + //! WorldViewProjection matrix) and another one named 'fTime' containing one float, + //! you can set them in your IShaderConstantSetCallBack derived class like this: + //! \code + //! virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + //! { + //! video::IVideoDriver* driver = services->getVideoDriver(); + //! + //! f32 time = (f32)os::Timer::getTime()/100000.0f; + //! services->setVertexShaderConstant("fTime", &time, 1); + //! + //! core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + //! worldViewProj *= driver->getTransform(video::ETS_VIEW); + //! worldViewProj *= driver->getTransform(video::ETS_WORLD); + //! services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); + //! } + //! \endcode + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + //! \return: Returns true if successful. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count) = 0; + + //! Sets a vertex shader constant. Can be used if you created a shader using + //! pixel/vertex shader assembler or ARB_fragment_program or ARB_vertex_program. + //! \param data: Data to be set in the constants + //! \param startRegister: First register to be set + //! \param constantAmount: Amount of registers to be set. One register consists of 4 floats. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; + + //! Sets a constant for the pixel shader based on a name. This can be used if you used + //! a high level shader language like GLSL or HLSL to create a shader. See + //! setVertexShaderConstant() for an example on how to use this. + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + //! \return: Returns true if successful. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count) = 0; + + //! Sets a pixel shader constant. Can be used if you created a shader using + //! pixel/vertex shader assembler or ARB_fragment_program or ARB_vertex_program. + //! \param data: Data to be set in the constants + //! \param startRegister: First register to be set. + //! \param constantAmount: Amount of registers to be set. One register consists of 4 floats. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0; + + //! Returns a pointer to the IVideoDriver interface + virtual IVideoDriver* getVideoDriver() = 0; +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMesh.h b/src/dep/include/irrlicht/IMesh.h new file mode 100644 index 0000000..cfb0da9 --- /dev/null +++ b/src/dep/include/irrlicht/IMesh.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_H_INCLUDED__ +#define __I_MESH_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" + +namespace irr +{ +namespace scene +{ + class IMeshBuffer; + + //! Class for accessing a mesh with multiple mesh buffers. + /** An IMesh is nothing more than a collection of some mesh buffers (IMeshBuffer). + SMesh is a simple implementation of an IMesh. + */ + class IMesh : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IMesh() { } + + //! Returns the amount of mesh buffers. + /** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ + virtual u32 getMeshBufferCount() const = 0; + + //! Returns pointer to a mesh buffer. + /** \param nr: Zero based index of the mesh buffer. The maximum value is + getMeshBufferCount() - 1; + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer(u32 nr) const = 0; + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const = 0; + + //! Returns an axis aligned bounding box of the mesh. + /** \return A bounding box of this mesh is returned. */ + virtual const core::aabbox3d& getBoundingBox() const = 0; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) = 0; + + //! Sets a flag of all contained materials to a new value. + /** \param flag: Flag to set in all materials. + \param newvalue: New value to set in all materials. */ + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMeshBuffer.h b/src/dep/include/irrlicht/IMeshBuffer.h new file mode 100644 index 0000000..60b60b0 --- /dev/null +++ b/src/dep/include/irrlicht/IMeshBuffer.h @@ -0,0 +1,117 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_BUFFER_H_INCLUDED__ +#define __I_MESH_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SMaterial.h" +#include "aabbox3d.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + + //! Enumeration for all primitive types there are. + enum E_PRIMITIVE_TYPE + { + //! All vertices are non-connected points. + EPT_POINTS=0, + + //! All vertices form a single connected line. + EPT_LINE_STRIP, + + //! Just as LINE_STRIP, but the last and the first vertex is also connected. + EPT_LINE_LOOP, + + //! Every two vertices are connected creating n/2 lines. + EPT_LINES, + + //! After the first two vertices each vertex defines a new triangle. + //! Always the two last and the new one form a new triangle. + EPT_TRIANGLE_STRIP, + + //! After the first two vertices each vertex defines a new triangle. + //! All around the common first vertex. + EPT_TRIANGLE_FAN, + + //! Explicitly set all vertices for each triangle. + EPT_TRIANGLES, + + //! After the first two vertices each further tw vetices create a quad with the preceding two. + EPT_QUAD_STRIP, + + //! Every four vertices create a quad. + EPT_QUADS, + + //! Just as LINE_LOOP, but filled. + EPT_POLYGON, + + //! The single vertices are expanded to quad billboards on the GPU. + EPT_POINT_SPRITES + }; + + + + //! Struct for holding a mesh with a single material + /** SMeshBuffer is a simple implementation of a MeshBuffer. */ + class IMeshBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IMeshBuffer() { } + + //! returns the material of this meshbuffer + virtual video::SMaterial& getMaterial() = 0; + + //! returns the material of this meshbuffer + virtual const video::SMaterial& getMaterial() const = 0; + + //! returns which type of vertex data is stored. + virtual video::E_VERTEX_TYPE getVertexType() const = 0; + + //! returns pointer to vertex data. The data is an array of vertices. Which vertex + //! type is used can be determined with getVertexType(). + virtual const void* getVertices() const = 0; + + //! returns pointer to vertex data. The data is an array of vertices. Which vertex + //! type is used can be determined with getVertexType(). + virtual void* getVertices() = 0; + + //! returns amount of vertices + virtual u32 getVertexCount() const = 0; + + //! returns pointer to Indices + virtual const u16* getIndices() const = 0; + + //! returns pointer to Indices + virtual u16* getIndices() = 0; + + //! returns amount of indices + virtual u32 getIndexCount() const = 0; + + //! returns an axis aligned bounding box + virtual const core::aabbox3df& getBoundingBox() const = 0; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) = 0; + + //! recalculates the bounding box. should be called if the mesh changed. + virtual void recalculateBoundingBox() = 0; + + //! append the vertices and indices to the current buffer + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0; + + //! append the meshbuffer to the current buffer + virtual void append(const IMeshBuffer* const other) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMeshCache.h b/src/dep/include/irrlicht/IMeshCache.h new file mode 100644 index 0000000..1953e59 --- /dev/null +++ b/src/dep/include/irrlicht/IMeshCache.h @@ -0,0 +1,131 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_CACHE_H_INCLUDED__ +#define __I_MESH_CACHE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrString.h" + +namespace irr +{ + +namespace scene +{ + class IMesh; + class IAnimatedMesh; + class IAnimatedMeshSceneNode; + class IMeshLoader; + + //! The mesh cache stores already loaded meshes and provides an interface to them. + /** You can access it using ISceneManager::getMeshCache(). All existing scene managers + will return a pointer to the same mesh cache, because it is shared between them. With + this interface, it is possible to manually add new loaded meshes (if + ISceneManager::getMesh() is not sufficient), to remove them and to iterate through + already loaded meshes. */ + class IMeshCache : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IMeshCache() {} + + //! Adds a mesh to the internal list of loaded meshes. + /** Usually, ISceneManager::getMesh() is called to load a mesh from a file. + That method searches the list of loaded meshes if a mesh has already been loaded and + returns a pointer to if it is in that list and already in memory. Otherwise it loads + the mesh. With IMeshCache::addMesh(), it is possible to pretend that a mesh already + has been loaded. This method can be used for example by mesh loaders who need to + load more than one mesh with one call. They can add additional meshes with this + method to the scene manager. The COLLADA loader for example uses this method. + \param filename: Filename of the mesh. When called ISceneManager::getMesh() with this + parameter, the method will return the mesh parameter given with this method. + \param mesh: Pointer to a mesh which will now be referenced by this name. */ + virtual void addMesh(const c8* filename, IAnimatedMesh* mesh) = 0; + + //! Removes a mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be removed from the cache + using this method, freeing a lot of memory. */ + virtual void removeMesh(const IAnimatedMesh* const mesh) = 0; + + //! Removes a mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be removed from the cache + using this method, freeing a lot of memory. */ + virtual void removeMesh(const IMesh* const mesh) = 0; + + //! Returns amount of loaded meshes in the cache. + /** You can load new meshes into the cache using getMesh() and addMesh(). + If you ever need to access the internal mesh cache, you can do this using + removeMesh(), getMeshNumber(), getMeshByIndex() and getMeshFilename() */ + virtual u32 getMeshCount() const = 0; + + //! Returns current index number of the mesh, and -1 if it is not in the cache. + virtual s32 getMeshIndex(const IAnimatedMesh* const mesh) const = 0; + + //! Returns current index number of the mesh, and -1 if it is not in the cache. + virtual s32 getMeshIndex(const IMesh* const mesh) const = 0; + + //! Returns a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + Note that this number is only valid until a new mesh is loaded or removed * + \return Returns pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByIndex(u32 index) = 0; + + //! Returns a mesh based on its file name. + /** \return Returns pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByFilename(const c8* filename) = 0; + + //! Returns name of a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + Note that this is only valid until a new mesh is loaded */ + virtual const c8* getMeshFilename(u32 index) const = 0; + + //! Returns the filename of a loaded mesh, if there is any. + /** Returns 0 if there is none. */ + virtual const c8* getMeshFilename(const IAnimatedMesh* const mesh) const = 0; + + //! Returns the filename of a loaded mesh, if there is any. + /* Returns 0 if there is none.*/ + virtual const c8* getMeshFilename(const IMesh* const mesh) const = 0; + + //! Renames a loaded mesh, if possible. + /** Returns true if sucessful. Note that renaming meshes might change + the ordering of the meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. */ + virtual bool setMeshFilename(u32 index, const c8* filename) = 0; + + //! Renames a loaded mesh, if possible. + /** Returns true if sucessful. Note that renaming meshes might change + the ordering of the meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. */ + virtual bool setMeshFilename(const IAnimatedMesh* const mesh, const c8* filename) = 0; + + //! Renames a loaded mesh, if possible. + /** Returns true if sucessful. Note that renaming meshes might change + the ordering of the meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. */ + virtual bool setMeshFilename(const IMesh* const mesh, const c8* filename) = 0; + + //! returns if a mesh already was loaded + virtual bool isMeshLoaded(const c8* filename) = 0; + + //! Clears the whole mesh cache, removing all meshes. + /** All meshes will be reloaded completely when using ISceneManager::getMesh() + after calling this method. + Warning: If you have pointers to meshes that were loaded with ISceneManager::getMesh() + and you did not grab them, then they may become invalid. */ + virtual void clear() = 0; + + //! Clears all meshes that are held in the mesh cache but not used anywhere else. + /** Warning: If you have pointers to meshes that were loaded with ISceneManager::getMesh() + and you did not grab them, then they may become invalid. */ + virtual void clearUnusedMeshes() = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMeshLoader.h b/src/dep/include/irrlicht/IMeshLoader.h new file mode 100644 index 0000000..bfbdd8d --- /dev/null +++ b/src/dep/include/irrlicht/IMeshLoader.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_LOADER_H_INCLUDED__ +#define __I_MESH_LOADER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace scene +{ + class IAnimatedMesh; + +//! Class which is able to load an animated mesh from a file. +/** If you want the Irrlicht Engine be able to load meshes of +currently unsupported file formats (e.g .cob), then implement +this and add your new Surface loader with +ISceneManager::addExternalMeshLoader() to the engine. */ +class IMeshLoader : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IMeshLoader() {} + + //! Returns true if the file maybe is able to be loaded by this class. + /** This decision should be based only on the file extension (e.g. ".cob") */ + virtual bool isALoadableFileExtension(const c8* fileName) const = 0; + + //! Creates/loads an animated mesh from the file. + /** \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* createMesh(io::IReadFile* file) = 0; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IMeshManipulator.h b/src/dep/include/irrlicht/IMeshManipulator.h new file mode 100644 index 0000000..45f4e41 --- /dev/null +++ b/src/dep/include/irrlicht/IMeshManipulator.h @@ -0,0 +1,121 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_MANIPULATOR_H_INCLUDED__ +#define __I_MESH_MANIPULATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "IAnimatedMesh.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + + class IMesh; + class IMeshBuffer; + struct SMesh; + + //! An interface for easily manipulate meshes. + /** Scale, set alpha value, flip surfaces, and so on. This exists for fixing problems + with wrong imported or exported meshes quickly after loading. It is not intended for doing mesh + modifications and/or animations during runtime. + */ + class IMeshManipulator : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IMeshManipulator() {} + + //! Flips the direction of surfaces. + /** Changes backfacing triangles to frontfacing + triangles and vice versa. + \param mesh: Mesh on which the operation is performed. */ + virtual void flipSurfaces(IMesh* mesh) const = 0; + + //! Sets the alpha vertex color value of the whole mesh to a new value. + /** \param mesh: Mesh on which the operation is performed. + \param alpha: New alpha value. Must be a value between 0 and 255. */ + virtual void setVertexColorAlpha(IMesh* mesh, s32 alpha) const = 0; + + //! Sets the colors of all vertices to one color + virtual void setVertexColors(IMesh* mesh, video::SColor color) const = 0; + + //! Recalculates all normals of the mesh. + /** \param mesh: Mesh on which the operation is performed. + \param smooth: If the normals shall be smoothed. */ + virtual void recalculateNormals(IMesh* mesh, bool smooth = false) const = 0; + + //! Recalculates all normals of the mesh buffer. + /** \param buffer: Mesh buffer on which the operation is performed. + \param smooth: If the normals shall be smoothed. */ + virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false) const = 0; + + //! Scales the whole mesh. + /** \param mesh: Mesh on which the operation is performed. + \param scale: Scale factor. */ + virtual void scaleMesh(IMesh* mesh, const core::vector3df& scale) const = 0; + + //! Applies a transformation + /** \param mesh: Mesh on which the operation is performed. + \param m: transformation matrix. */ + virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const = 0; + + //! Clones a static IMesh into a modifyable SMesh. + /** All meshbuffers in the returned SMesh + are of type SMeshBuffer or SMeshBufferLightMap. + \param mesh: Mesh to copy. + \return Returns the cloned mesh. + If you no longer need the cloned mesh, you should call SMesh::drop(). + See IReferenceCounted::drop() for more information. */ + virtual SMesh* createMeshCopy(IMesh* mesh) const = 0; + + + //! Creates a planar texture mapping on the mesh + /** \param mesh: Mesh on which the operation is performed. + \param resolution: resolution of the planar mapping. This is the value + specifying which is the relation between world space and + texture coordinate space. */ + virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const = 0; + + //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. + /** This is useful if you want to draw tangent space normal mapped geometry because + it calculates the tangent and binormal data which is needed there. + \param mesh: Input mesh + \return Mesh consiting only of S3DVertexTangents vertices. + If you no longer need the cloned mesh, you should call IMesh::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IMesh* createMeshWithTangents(IMesh* mesh) const = 0; + + //! Creates a copy of the mesh, which will only consist of S3DVertex2TCoord vertices. + virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0; + //! Creates a copy of a mesh with all vertices unwelded + virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0; + + //! Creates a copy of a mesh with vertices welded + virtual IMesh* createMeshWelded(IMesh* mesh, f32 tolerance=core::ROUNDING_ERROR_32) const = 0; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(IMesh* mesh) const = 0; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(IAnimatedMesh* mesh) const = 0; + + //! create a new AnimatedMesh and adds the mesh to it + virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh, + scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0; + + }; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IMeshSceneNode.h b/src/dep/include/irrlicht/IMeshSceneNode.h new file mode 100644 index 0000000..8c0de7d --- /dev/null +++ b/src/dep/include/irrlicht/IMeshSceneNode.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_MESH_SCENE_NODE_H_INCLUDED__ +#define __I_MESH_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +class IMesh; + + +//! A scene node displaying a static mesh +class IMeshSceneNode : public ISceneNode +{ +public: + + //! constructor + IMeshSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Sets a new mesh to display + virtual void setMesh(IMesh* mesh) = 0; + + //! Returns the current mesh + virtual IMesh* getMesh(void) = 0; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly) = 0; + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IMeshWriter.h b/src/dep/include/irrlicht/IMeshWriter.h new file mode 100644 index 0000000..fefde4e --- /dev/null +++ b/src/dep/include/irrlicht/IMeshWriter.h @@ -0,0 +1,48 @@ +#ifndef __IRR_I_MESH_WRITER_H_INCLUDED__ +#define __IRR_I_MESH_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "EMeshWriterEnums.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; +} // end namespace io + +namespace scene +{ + class IMesh; + + // interface for writing meshes + class IMeshWriter : public virtual IReferenceCounted + { + public: + + virtual ~IMeshWriter() {} + + //! Returns the type of the mesh writer + /** For own implementations, use MAKE_IRR_ID as shown in the EMESH_WRITER_TYPE + enumeration to return your own unique mesh type id.*/ + virtual EMESH_WRITER_TYPE getType() const = 0; + + //! writes a static mesh + /** \return Returns true if sucessful */ + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, + s32 flags=EMWF_NONE) = 0; + + // writes an animated mesh + // for future use, no writer is able to write animated meshes currently + /* \return Returns true if sucessful */ + //virtual bool writeAnimatedMesh(io::IWriteFile* file, + // scene::IAnimatedMesh* mesh, + // s32 flags=EMWF_NONE) = 0; + }; + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/include/irrlicht/IMetaTriangleSelector.h b/src/dep/include/irrlicht/IMetaTriangleSelector.h new file mode 100644 index 0000000..d3afaba --- /dev/null +++ b/src/dep/include/irrlicht/IMetaTriangleSelector.h @@ -0,0 +1,44 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_META_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __I_META_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "ITriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! Interface for making multiple triangle selectors work as one big selector. +/** This is nothing more than a collection of one or more triangle selectors +providing together the interface of one triangle selector. In this way, +collision tests can be done with different triangle soups in one pass. +*/ +class IMetaTriangleSelector : public ITriangleSelector +{ +public: + + //! Adds a triangle selector to the collection of triangle selectors + //! in this metaTriangleSelector. + //! \param toAdd: Pointer to an triangle selector to add to the list. + virtual void addTriangleSelector(ITriangleSelector* toAdd) = 0; + + //! Removes a specific triangle selector which was added before from the collection. + //! \param toRemove: Pointer to an triangle selector which is in the list + //! but will be removed. + //! \return Returns true if successful, false if not. + virtual bool removeTriangleSelector(ITriangleSelector* toRemove) = 0; + + //! Removes all triangle selectors from the collection. + virtual void removeAllTriangleSelectors() = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IOSOperator.h b/src/dep/include/irrlicht/IOSOperator.h new file mode 100644 index 0000000..2cb72dc --- /dev/null +++ b/src/dep/include/irrlicht/IOSOperator.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_OS_OPERATOR_H_INCLUDED__ +#define __I_OS_OPERATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +//! The Operating system operator provides operation system specific methods and informations. +class IOSOperator : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~IOSOperator() {} + + //! returns the current operation system version as string. + virtual const wchar_t* getOperationSystemVersion() const = 0; + + //! copies text to the clipboard + virtual void copyToClipboard(const c8* text) const = 0; + + //! gets text from the clipboard + //! \return Returns 0 if no string is in there. + virtual c8* getTextFromClipboard() const = 0; + + //! gets the processor speed in megahertz + //! \param MHz: The integer variable to store the speed in. + //! \return Returns true if successful, false if not + virtual bool getProcessorSpeedMHz(u32* MHz) const = 0; + + //! gets the total and available system RAM + //! \param Total: will contain the total system memory + //! \param Avail: will contain the available memory + //! \return Returns true if successful, false if not + virtual bool getSystemMemory(u32* Total, u32* Avail) const = 0; + +}; + +} // end namespace + +#endif + diff --git a/src/dep/include/irrlicht/IParticleAffector.h b/src/dep/include/irrlicht/IParticleAffector.h new file mode 100644 index 0000000..9a69c17 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleAffector.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_AFFECTOR_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "SParticle.h" + +namespace irr +{ +namespace scene +{ + +//! Types of built in particle affectors +enum E_PARTICLE_AFFECTOR_TYPE +{ + EPAT_NONE = 0, + EPAT_ATTRACT, + EPAT_FADE_OUT, + EPAT_GRAVITY, + EPAT_ROTATE, + EPAT_COUNT +}; + +//! Names for built in particle affectors +const c8* const ParticleAffectorTypeNames[] = +{ + "None", + "Attract", + "FadeOut", + "Gravity", + "Rotate", + 0 +}; + +//! A particle affector modifies particles. +class IParticleAffector : public virtual io::IAttributeExchangingObject +{ +public: + + //! constructor + IParticleAffector() : Enabled(true) {} + + //! Affects an array of particles. + //! \param now: Current time. (Same as ITimer::getTime() would return) + //! \param particlearray: Array of particles. + //! \param count: Amount of particles in array. + virtual void affect(u32 now, SParticle* particlearray, u32 count) = 0; + + //! Sets whether or not the affector is currently enabled. + virtual void setEnabled(bool enabled) { Enabled = enabled; } + + //! Gets whether or not the affector is currently enabled. + virtual bool getEnabled() const { return Enabled; } + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {} + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \param in: The attributes to work with. + //! \param options: Additional options. + //! \return: returns last index of an attribute read by this affector + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) { return 0; } + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const = 0; + +protected: + bool Enabled; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleAnimatedMeshSceneNodeEmitter.h b/src/dep/include/irrlicht/IParticleAnimatedMeshSceneNodeEmitter.h new file mode 100644 index 0000000..65898a1 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleAnimatedMeshSceneNodeEmitter.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "IAnimatedMeshSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles from mesh vertices. +class IParticleAnimatedMeshSceneNodeEmitter : public IParticleEmitter +{ +public: + + //! Set Mesh to emit particles from + virtual void setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ) = 0; + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection = true ) = 0; + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) = 0; + + //! Sets whether to emit min<->max particles for every vertex per + //! second, or to pick min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex = true ) = 0; + + //! Get Mesh we're emitting particles from + virtual const IAnimatedMeshSceneNode* getAnimatedMeshSceneNode() const = 0; + + //! Get whether to use vertex normal for direction, or direction specified + virtual bool isUsingNormalDirection() const = 0; + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const = 0; + + //! Gets whether to emit min<->max particles for every vertex per + //! second, or to pick min<->max vertices every second + virtual bool getEveryMeshVertex() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_ANIMATED_MESH; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IParticleAttractionAffector.h b/src/dep/include/irrlicht/IParticleAttractionAffector.h new file mode 100644 index 0000000..137b3d1 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleAttractionAffector.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which attracts or detracts particles. +class IParticleAttractionAffector : public IParticleAffector +{ +public: + + //! Set the point that particles will attract to + virtual void setPoint( const core::vector3df& point ) = 0; + + //! Set whether or not the particles are attracting or detracting + virtual void setAttract( bool attract ) = 0; + + //! Set whether or not this will affect particles in the X direction + virtual void setAffectX( bool affect ) = 0; + + //! Set whether or not this will affect particles in the Y direction + virtual void setAffectY( bool affect ) = 0; + + //! Set whether or not this will affect particles in the Z direction + virtual void setAffectZ( bool affect ) = 0; + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPoint() const = 0; + + //! Get whether or not the particles are attracting or detracting + virtual bool getAttract() const = 0; + + //! Get whether or not the particles X position are affected + virtual bool getAffectX() const = 0; + + //! Get whether or not the particles Y position are affected + virtual bool getAffectY() const = 0; + + //! Get whether or not the particles Z position are affected + virtual bool getAffectZ() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_ATTRACT; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IParticleBoxEmitter.h b/src/dep/include/irrlicht/IParticleBoxEmitter.h new file mode 100644 index 0000000..7e6acd2 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleBoxEmitter.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_BOX_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_BOX_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles from a box shaped space +class IParticleBoxEmitter : public IParticleEmitter +{ +public: + + //! Set the box shape + virtual void setBox( const core::aabbox3df& box ) = 0; + + //! Get the box shape set + virtual const core::aabbox3df& getBox() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_BOX; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleCylinderEmitter.h b/src/dep/include/irrlicht/IParticleCylinderEmitter.h new file mode 100644 index 0000000..f155897 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleCylinderEmitter.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from a cylindrically shaped space. +class IParticleCylinderEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the radius for the cylinder, at one end of the cylinder + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the normal of the cylinder + virtual void setNormal( const core::vector3df& normal ) = 0; + + //! Set the radius of the cylinder + virtual void setRadius( f32 radius ) = 0; + + //! Set the length of the cylinder + virtual void setLength( f32 length ) = 0; + + //! Set whether or not to draw points inside the cylinder + virtual void setOutlineOnly( bool outlineOnly = true ) = 0; + + //! Get the center of the cylinder + virtual const core::vector3df& getCenter() const = 0; + + //! Get the normal of the cylinder + virtual const core::vector3df& getNormal() const = 0; + + //! Get the radius of the cylinder + virtual f32 getRadius() const = 0; + + //! Get the center of the cylinder + virtual f32 getLength() const = 0; + + //! Get whether or not to draw points inside the cylinder + virtual bool getOutlineOnly() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_CYLINDER; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleEmitter.h b/src/dep/include/irrlicht/IParticleEmitter.h new file mode 100644 index 0000000..b87ff5c --- /dev/null +++ b/src/dep/include/irrlicht/IParticleEmitter.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_EMITTER_H_INCLUDED__ + +#include "IAttributeExchangingObject.h" +#include "SParticle.h" + +namespace irr +{ +namespace scene +{ + +//! Types of built in particle emitters +enum E_PARTICLE_EMITTER_TYPE +{ + EPET_POINT = 0, + EPET_ANIMATED_MESH, + EPET_BOX, + EPET_CYLINDER, + EPET_MESH, + EPET_RING, + EPET_SPHERE, + EPET_COUNT +}; + +//! Names for built in particle emitters +const c8* const ParticleEmitterTypeNames[] = +{ + "Point", + "AnimatedMesh", + "Box", + "Cylinder", + "Mesh", + "Ring", + "Sphere", + 0 +}; + +//! A particle emitter for using with particle systems. +/** A Particle emitter emitts new particles into a particle system. +*/ +class IParticleEmitter : public virtual io::IAttributeExchangingObject +{ +public: + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + //! \param now: Current time. + //! \param timeSinceLastCall: Time elapsed since last call, in milliseconds. + //! \param outArray: Pointer which will point to the array with the new + //! particles to add into the system. + //! \return Returns amount of new particles in the array. Can be 0. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) = 0; + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) = 0; + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) = 0; + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) = 0; + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) = 0; + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) = 0; + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const = 0; + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const = 0; + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const = 0; + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const = 0; + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const = 0; + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {} + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \param in: The attributes to work with. + //! \param options: Additional options. + //! \return: returns last index of an attribute read by this affector + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) { return 0; } + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_POINT; } +}; + +typedef IParticleEmitter IParticlePointEmitter; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleFadeOutAffector.h b/src/dep/include/irrlicht/IParticleFadeOutAffector.h new file mode 100644 index 0000000..15cf84f --- /dev/null +++ b/src/dep/include/irrlicht/IParticleFadeOutAffector.h @@ -0,0 +1,43 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which fades out the particles. +class IParticleFadeOutAffector : public IParticleAffector +{ +public: + + //! Sets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual void setTargetColor( const video::SColor& targetColor ) = 0; + + //! Sets the amount of time it takes for each particle to fade out. + virtual void setFadeOutTime( f32 fadeOutTime ) = 0; + + //! Gets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual const video::SColor& getTargetColor() const = 0; + + //! Gets the amount of time it takes for each particle to fade out. + virtual f32 getFadeOutTime() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_FADE_OUT; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IParticleGravityAffector.h b/src/dep/include/irrlicht/IParticleGravityAffector.h new file mode 100644 index 0000000..8851fef --- /dev/null +++ b/src/dep/include/irrlicht/IParticleGravityAffector.h @@ -0,0 +1,43 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which applies gravity to particles. +class IParticleGravityAffector : public IParticleAffector +{ +public: + + //! Set the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual void setTimeForceLost( f32 timeForceLost ) = 0; + + //! Set the direction and force of gravity in all 3 dimensions. + virtual void setGravity( const core::vector3df& gravity ) = 0; + + //! Get the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual f32 getTimeForceLost() const = 0; + + //! Get the direction and force of gravity. + virtual const core::vector3df& getGravity() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_GRAVITY; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IParticleMeshEmitter.h b/src/dep/include/irrlicht/IParticleMeshEmitter.h new file mode 100644 index 0000000..99f72a9 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleMeshEmitter.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_MESH_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_MESH_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from vertices of a mesh +class IParticleMeshEmitter : public IParticleEmitter +{ +public: + + //! Set Mesh to emit particles from + virtual void setMesh( IMesh* mesh ) = 0; + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection = true ) = 0; + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) = 0; + + //! Sets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex = true ) = 0; + + //! Get Mesh we're emitting particles from + virtual const IMesh* getMesh() const = 0; + + //! Get whether to use vertex normal for direction, or direction specified + virtual bool isUsingNormalDirection() const = 0; + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const = 0; + + //! Gets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual bool getEveryMeshVertex() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_MESH; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleRingEmitter.h b/src/dep/include/irrlicht/IParticleRingEmitter.h new file mode 100644 index 0000000..eaf4de4 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleRingEmitter.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_RING_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_RING_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits particles along a ring shaped area. +class IParticleRingEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the ring + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the radius of the ring + virtual void setRadius( f32 radius ) = 0; + + //! Set the thickness of the ring + virtual void setRingThickness( f32 ringThickness ) = 0; + + //! Get the center of the ring + virtual const core::vector3df& getCenter() const = 0; + + //! Get the radius of the ring + virtual f32 getRadius() const = 0; + + //! Get the thickness of the ring + virtual f32 getRingThickness() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_RING; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleRotationAffector.h b/src/dep/include/irrlicht/IParticleRotationAffector.h new file mode 100644 index 0000000..9646a28 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleRotationAffector.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ +#define __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + +#include "IParticleAffector.h" + +namespace irr +{ +namespace scene +{ + +//! A particle affector which rotates the particle system. +class IParticleRotationAffector : public IParticleAffector +{ +public: + + //! Set the point that particles will rotate around + virtual void setPivotPoint( const core::vector3df& point ) = 0; + + //! Set the speed in degrees per second in all 3 dimensions + virtual void setSpeed( const core::vector3df& speed ) = 0; + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPivotPoint() const = 0; + + //! Get the speed in degrees per second in all 3 dimensions + virtual const core::vector3df& getSpeed() const = 0; + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const { return EPAT_ROTATE; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IParticleSphereEmitter.h b/src/dep/include/irrlicht/IParticleSphereEmitter.h new file mode 100644 index 0000000..319f308 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleSphereEmitter.h @@ -0,0 +1,41 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ +#define __I_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" + +namespace irr +{ +namespace scene +{ + +//! A particle emitter which emits from a spherical space. +class IParticleSphereEmitter : public IParticleEmitter +{ +public: + + //! Set the center of the sphere for particle emissions + virtual void setCenter( const core::vector3df& center ) = 0; + + //! Set the radius of the sphere for particle emissions + virtual void setRadius( f32 radius ) = 0; + + //! Get the center of the sphere for particle emissions + virtual const core::vector3df& getCenter() const = 0; + + //! Get the radius of the sphere for particle emissions + virtual f32 getRadius() const = 0; + + //! Get emitter type + virtual E_PARTICLE_EMITTER_TYPE getType() const { return EPET_SPHERE; } +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IParticleSystemSceneNode.h b/src/dep/include/irrlicht/IParticleSystemSceneNode.h new file mode 100644 index 0000000..e3de6d2 --- /dev/null +++ b/src/dep/include/irrlicht/IParticleSystemSceneNode.h @@ -0,0 +1,416 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ +#define __I_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IParticleAnimatedMeshSceneNodeEmitter.h" +#include "IParticleBoxEmitter.h" +#include "IParticleCylinderEmitter.h" +#include "IParticleMeshEmitter.h" +#include "IParticleRingEmitter.h" +#include "IParticleSphereEmitter.h" +#include "IParticleAttractionAffector.h" +#include "IParticleFadeOutAffector.h" +#include "IParticleGravityAffector.h" +#include "IParticleRotationAffector.h" +#include "dimension2d.h" + +namespace irr +{ +namespace scene +{ + +//! A particle system scene node for creating snow, fire, exlosions, smoke... +/** A scene node controlling a particle System. The behavior of the particles +can be controlling by setting the right particle emitters and effectors. +You can for example easily a campfire by doing this: + +\code + scene::IParticleSystemSceneNode* p = scenemgr->addParticleSystemSceneNode(); + p->setParticleSize(core::dimension2d(20.0f, 10.0f)); + scene::IParticleEmitter* em = p->createBoxEmitter( + core::aabbox3d(-5,0,-5,5,1,5), + core::vector3df(0.0f,0.03f,0.0f), + 40,80, video::SColor(0,255,255,255),video::SColor(0,255,255,255), 1100,2000); + p->setEmitter(em); + em->drop(); + scene::IParticleAffector* paf = p->createFadeOutParticleAffector(); + p->addAffector(paf); + paf->drop(); +\endcode + +*/ +class IParticleSystemSceneNode : public ISceneNode +{ +public: + + //! constructor + IParticleSystemSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : ISceneNode(parent, mgr, id, position, rotation, scale) {} + + //! Sets the size of all particles. + virtual void setParticleSize( + const core::dimension2d &size = core::dimension2d(5.0f, 5.0f)) = 0; + + //! Sets if the particles should be global. If it is, the particles are affected by + //! the movement of the particle system scene node too, otherwise they completely + //! ignore it. Default is true. + virtual void setParticlesAreGlobal(bool global) = 0; + + //! Sets the particle emitter, which creates the particles. + //! A particle emitter can be created using one of the + //! methods. For example to create and use a simple PointEmitter, + //! call IParticleEmitter* p = createPointEmitter(); setEmitter(p); p->drop(); + //! \param emitter: Sets the particle emitter. You can set this to 0 + //! for removing the current emitter and stopping the particle system + //! emitting new particles. + virtual void setEmitter(IParticleEmitter* emitter) = 0; + + //! Adds new particle effector to the particle system. A particle + //! affector modifies the particles. For example, the FadeOut + //! affector lets all particles fade out after some time. It is created + //! and used in this way: IParticleAffector* p = createFadeOutParticleAffector(); + //! addAffector(p); p->drop(); + //! Please note that a affector is not necessary for the particle + //! system to work. + //! \param affector: New affector. + virtual void addAffector(IParticleAffector* affector) = 0; + + //! Removes all particle affectors in the particle system. + virtual void removeAllAffectors() = 0; + + //! Creates a particle emitter for an animated mesh scene node + //! \param node: Pointer to the animated mesh scene node to emit particles from + //! \param useNormalDirection: If true, the direction of each particle created will + //! be the normal of the vertex that it's emitting from. The normal is divided by the + //! normalDirectionModifier parameter, which defaults to 100.0f. + //! \param direction: Direction and speed of particle emission. + //! \param normalDirectionModifier: If the emitter is using the normal direction + //! then the normal of the vertex that is being emitted from is divided by this number. + //! \param mbNumber: This allows you to specify a specific meshBuffer for the IMesh* + //! to emit particles from. The default value is -1, which means a random meshBuffer + //! picked from all of the meshes meshBuffers will be selected to pick a random vertex from. + //! If the value is 0 or greater, it will only pick random vertices from the meshBuffer + //! specified by this value. + //! \param everyMeshVertex: If true, the emitter will emit between min/max particles every second, + //! for every vertex in the mesh, if false, it will emit between min/max particles from random vertices + //! in the mesh. + //! \param minParticlesPerSecond: Minimal amount of particles emitted + //! per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted + //! per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleAnimatedMeshSceneNodeEmitter* createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ) = 0; + + //! Creates a box particle emitter. + //! \param box: The box for the emitter. + //! \param direction: Direction and speed of particle emission. + //! \param minParticlesPerSecond: Minimal amount of particles emitted + //! per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted + //! per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleBoxEmitter* createBoxEmitter( + const core::aabbox3df& box = core::aabbox3df(-10,28,-10,10,30,10), + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0) = 0; + + //! Creates a particle emitter for emitting from a cylinder + //! \param center: The center of the circle at the base of the cylinder + //! \param radius: The thickness of the cylinder + //! \param normal: Direction of the length of the cylinder + //! \param length: The length of the the cylinder + //! \param outlineOnly: Whether or not to put points inside the cylinder or on the outline only + //! \param direction: Direction and speed of particle emission. + //! \param minParticlesPerSecond: Minimal amount of particles emitted per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleCylinderEmitter* createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly = false, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ) = 0; + + //! Creates a mesh particle emitter. + //! \param mesh: Pointer to mesh to emit particles from + //! \param useNormalDirection: If true, the direction of each particle created will + //! be the normal of the vertex that it's emitting from. The normal is divided by the + //! normalDirectionModifier parameter, which defaults to 100.0f. + //! \param direction: Direction and speed of particle emission. + //! \param normalDirectionModifier: If the emitter is using the normal direction + //! then the normal of the vertex that is being emitted from is divided by this number. + //! \param mbNumber: This allows you to specify a specific meshBuffer for the IMesh* + //! to emit particles from. The default value is -1, which means a random meshBuffer + //! picked from all of the meshes meshBuffers will be selected to pick a random vertex from. + //! If the value is 0 or greater, it will only pick random vertices from the meshBuffer + //! specified by this value. + //! \param everyMeshVertex: If true, the emitter will emit between min/max particles every second, + //! for every vertex in the mesh, if false, it will emit between min/max particles from random vertices + //! in the mesh. + //! \param minParticlesPerSecond: Minimal amount of particles emitted per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleMeshEmitter* createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ) = 0; + + //! Creates a point particle emitter. + //! \param direction: Direction and speed of particle emission. + //! \param minParticlesPerSecond: Minimal amount of particles emitted + //! per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted + //! per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticlePointEmitter* createPointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0) = 0; + + //! Creates a ring particle emitter. + //! \param center: Center of ring + //! \param radius: Distance of points from center, points will be rotated around the + //! Y axis at a random 360 degrees and will then be shifted by the provided ringThickness + //! values in each axis. + //! \param ringThickness : thickness of the ring or how wide the ring is + //! \param direction: Direction and speed of particle emission. + //! \param minParticlesPerSecond: Minimal amount of particles emitted + //! per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted + //! per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleRingEmitter* createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0) = 0; + + //! Creates a sphere particle emitter. + //! \param center: Center of sphere + //! \param radius: Radius of sphere + //! \param direction: Direction and speed of particle emission. + //! \param minParticlesPerSecond: Minimal amount of particles emitted + //! per second. + //! \param maxParticlesPerSecond: Maximal amount of particles emitted + //! per second. + //! \param minStartColor: Minimal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param maxStartColor: Maximal initial start color of a particle. + //! The real color of every particle is calculated as random interpolation + //! between minStartColor and maxStartColor. + //! \param lifeTimeMin: Minimal lifetime of a particle, in milliseconds. + //! \param lifeTimeMax: Maximal lifetime of a particle, in milliseconds. + //! \param maxAngleDegrees: Maximal angle in degrees, the emitting direction + //! of the particle will differ from the orignial direction. + //! \return Returns a pointer to the created particle emitter. + //! To set this emitter as new emitter of this particle system, + //! just call setEmitter(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleSphereEmitter* createSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0) = 0; + + //! Creates a point attraction affector. This affector modifies the positions of the + //! particles and attracts them to a specified point at a specified speed per second. + //! \param point: Point to attract particles to. + //! \param speed: Speed in units per second, to attract to the specified point. + //! \param attract: Whether the particles attract or detract from this point. + //! \param affectX: Whether or not this will affect the X position of the particle. + //! \param affectY: Whether or not this will affect the Y position of the particle. + //! \param affectZ: Whether or not this will affect the Z position of the particle. + //! \return Returns a pointer to the created particle affector. + //! To add this affector as new affector of this particle system, + //! just call addAffector(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleAttractionAffector* createAttractionAffector( + const core::vector3df& point, f32 speed = 1.0f, bool attract = true, + bool affectX = true, bool affectY = true, bool affectZ = true) = 0; + + //! Creates a fade out particle affector. This affector modifies + //! the color of every particle and and reaches the final color + //! when the particle dies. + //! This affector looks really good, if the EMT_TRANSPARENT_VERTEX_ALPHA + //! material is used and the targetColor is video::SColor(0,0,0,0): + //! Particles are fading out into void with this setting. + //! \param targetColor: Color whereto the color of the particle is changed. + //! \param timeNeededToFadeOut: How much time in milli seconds + //! should the affector need to change the color to the targetColor. + //! \return Returns a pointer to the created particle affector. + //! To add this affector as new affector of this particle system, + //! just call addAffector(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleFadeOutAffector* createFadeOutParticleAffector( + const video::SColor& targetColor = video::SColor(0,0,0,0), + u32 timeNeededToFadeOut = 1000) = 0; + + //! Creates a gravity affector. This affector modifies the direction + //! of the particle. It assumes that the particle is fired out of the + //! emitter with huge force, but is loosing this after some time + //! and is catched by the gravity then. This affector is ideal for + //! creating things like fountains. + //! \param gravity: Direction and force of gravity. + //! \param timeForceLost: Time in milli seconds when the force + //! of the emitter is totally lost and the particle does not move any more. + //! This is the time where gravity fully affects the particle. + //! \return Returns a pointer to the created particle affector. + //! To add this affector as new affector of this particle system, + //! just call addAffector(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleGravityAffector* createGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000) = 0; + + //! Creates a rotation affector. This affector modifies the positions of the + //! particles and attracts them to a specified point at a specified speed per second. + //! \param speed: Rotation in degrees per second + //! \param pivotPoint: Point to rotate the particles around + //! \return Returns a pointer to the created particle affector. + //! To add this affector as new affector of this particle system, + //! just call addAffector(). Note that you'll have to drop() the + //! returned pointer, after you don't need it any more, see + //! IReferenceCounted::drop() for more informations. + virtual IParticleRotationAffector* createRotationAffector( + const core::vector3df& speed = core::vector3df(5.0f,5.0f,5.0f), + const core::vector3df& pivotPoint = core::vector3df(0.0f,0.0f,0.0f) ) = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IQ3LevelMesh.h b/src/dep/include/irrlicht/IQ3LevelMesh.h new file mode 100644 index 0000000..e0abafb --- /dev/null +++ b/src/dep/include/irrlicht/IQ3LevelMesh.h @@ -0,0 +1,42 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Q3_LEVEL_MESH_H_INCLUDED__ +#define __I_Q3_LEVEL_MESH_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + //! Interface for a Mesh which can be loaded directly from a Quake3 .bsp-file. + /** The Mesh tries to load all textures of the map. There are currently + no additional methods in this class, but maybe there will be some in later + releases if there are feature requests. */ + class IQ3LevelMesh : public IAnimatedMesh + { + public: + + //! releases a Mesh from the Q3 Loader + virtual void releaseMesh ( s32 index ) = 0; + + //! loads the shader definition + // either from file ( we assume /scripts on fileNameIsValid == 0 ) + virtual const quake3::SShader * getShader ( const c8 * filename, s32 fileNameIsValid ) = 0; + + //! returns a already loaded Shader + virtual const quake3::SShader * getShader ( u32 index ) const = 0; + + //! get's an interface to the entities + virtual const quake3::tQ3EntityList & getEntityList () = 0; + + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IQ3Shader.h b/src/dep/include/irrlicht/IQ3Shader.h new file mode 100644 index 0000000..35b052c --- /dev/null +++ b/src/dep/include/irrlicht/IQ3Shader.h @@ -0,0 +1,609 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Q3_LEVEL_SHADER_H_INCLUDED__ +#define __I_Q3_LEVEL_SHADER_H_INCLUDED__ + +#include "irrArray.h" +#include "fast_atof.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "coreutil.h" + +namespace irr +{ +namespace scene +{ +namespace quake3 +{ + + static const core::stringc irrEmptyStringc(""); + + //! Hold the different Mesh Types used for getMesh + enum eQ3MeshIndex + { + E_Q3_MESH_GEOMETRY = 0, + E_Q3_MESH_ITEMS, + E_Q3_MESH_BILLBOARD, + E_Q3_MESH_SIZE + }; + + // we are not using gamma, so quake3 is very dark. + // define the standard multiplication for lightmaps and vertex colors + const video::E_MATERIAL_TYPE defaultLightMap = video::EMT_LIGHTMAP_M2; + const video::E_MODULATE_FUNC defaultModulate = video::EMFN_MODULATE_2X; + + // some useful typedefs + typedef core::array< core::stringc > tStringList; + typedef core::array< video::ITexture* > tTexArray; + + // name = "a b c .." + struct SVariable + { + core::stringc name; + core::stringc content; + + void clear () + { + name = ""; + content = ""; + } + + s32 isValid () const + { + return name.size(); + } + + bool operator == ( const SVariable &other ) const + { + return name == other.name; + } + }; + + // string helper.. TODO: move to generic files + inline s32 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u32 listSize ) + { + const char * in = string.c_str () + pos; + + for ( u32 i = 0; i != listSize; ++i ) + { + if (string.size() < pos) + return -2; + u32 len = (u32) strlen ( list[i] ); + if (string.size() < pos+len) + continue; + if ( in [len] != 0 && in [len] != ' ' ) + continue; + if ( strncmp ( in, list[i], len ) ) + continue; + + pos += len + 1; + return (s32) i; + } + return -2; + } + + inline f32 getAsFloat ( const core::stringc &string, u32 &pos ) + { + const char * in = string.c_str () + pos; + + f32 value = 0.f; + pos += (u32) ( core::fast_atof_move ( in, value ) - in ) + 1; + return value; + } + + inline core::vector3df getAsVector3df ( const core::stringc &string, u32 &pos ) + { + core::vector3df v; + + v.X = getAsFloat ( string, pos ); + v.Z = getAsFloat ( string, pos ); + v.Y = getAsFloat ( string, pos ); + + return v; + } + + /* + extract substrings + */ + inline void getAsStringList ( tStringList &list, s32 max, const core::stringc &string, u32 &startPos ) + { + list.clear (); + + s32 finish = 0; + s32 endPos; + do + { + endPos = string.findNext ( ' ', startPos ); + if ( endPos == -1 ) + { + finish = 1; + endPos = string.size(); + } + + list.push_back ( string.subString ( startPos, endPos - startPos ) ); + startPos = endPos + 1; + + if ( list.size() >= (u32) max ) + finish = 1; + + } while ( !finish ); + + } + + struct SBlendFunc + { + SBlendFunc () : type ( video::EMT_SOLID ), param ( 0.f ) {} + + video::E_MATERIAL_TYPE type; + f32 param; + }; + + // parses the content of Variable cull + inline bool getBackfaceCulling ( const core::stringc &string ) + { + if ( string.size() == 0 ) + return true; + + bool ret = true; + static const c8 * funclist[] = { "none", "disable" }; + + u32 pos = 0; + switch ( isEqual ( string, pos, funclist, 2 ) ) + { + case 0: + case 1: + ret = false; + break; + } + return ret; + } + + // parses the content of Variable depthfunc + // return a z-test + inline u32 getDepthFunction ( const core::stringc &string ) + { + if ( string.size() == 0 ) + return 1; + + u32 ret = 1; + static const c8 * funclist[] = { "lequal","equal" }; + + u32 pos = 0; + switch ( isEqual ( string, pos, funclist, 2 ) ) + { + case 0: + ret = 1; + case 1: + ret = 2; + break; + } + return ret; + } + + + + // parses the content of Variable blendfunc,alphafunc + inline static void getBlendFunc ( const core::stringc &string, SBlendFunc &blendfunc ) + { + if ( string.size() == 0 ) + return; + + // maps to E_BLEND_FACTOR + static const c8 * funclist[] = + { + "gl_zero", + "gl_one", + "gl_dst_color", + "gl_one_minus_dst_color", + "gl_src_color", + "gl_one_minus_src_color", + "gl_src_alpha", + "gl_one_minus_src_alpha", + "gl_dst_alpha", + "gl_one_minus_dst_alpha", + "gl_src_alpha_sat", + + "add", + "filter", + "blend", + + "ge128", + "gt0" + }; + + + u32 pos = 0; + s32 srcFact = isEqual ( string, pos, funclist, 16 ); + + if ( srcFact < 0 ) + return; + + u32 resolved = 0; + s32 dstFact = isEqual ( string, pos, funclist, 16 ); + + switch ( srcFact ) + { + case video::EBF_ONE: + switch ( dstFact ) + { + // gl_one gl_zero + case video::EBF_ZERO: + blendfunc.type = video::EMT_SOLID; + resolved = 1; + break; + + // gl_one gl_one + case video::EBF_ONE: + blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR; + resolved = 1; + break; + } break; + + case video::EBF_SRC_ALPHA: + switch ( dstFact ) + { + // gl_src_alpha gl_one_minus_src_alpha + case video::EBF_ONE_MINUS_SRC_ALPHA: + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param = 1.f / 255.f; + resolved = 1; + break; + } break; + + case 11: + // add + blendfunc.type = video::EMT_TRANSPARENT_ADD_COLOR; + resolved = 1; + break; + case 12: + // filter = gl_dst_color gl_zero + blendfunc.type = video::EMT_ONETEXTURE_BLEND; + blendfunc.param = video::pack_texureBlendFunc ( video::EBF_DST_COLOR, video::EBF_ZERO, defaultModulate ); + resolved = 1; + break; + case 13: + // blend + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param = 1.f / 255.f; + resolved = 1; + break; + case 14: + // alphafunc ge128 + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + blendfunc.param = 0.5f; + resolved = 1; + break; + case 15: + // alphafunc gt0 + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + blendfunc.param = 1.f / 255.f; + resolved = 1; + break; + } + + // use the generic blender + if ( 0 == resolved ) + { + blendfunc.type = video::EMT_ONETEXTURE_BLEND; + blendfunc.param = video::pack_texureBlendFunc ( + (video::E_BLEND_FACTOR) srcFact, + (video::E_BLEND_FACTOR) dstFact, + defaultModulate); + } + } + + struct SModifierFunction + { + SModifierFunction () + : masterfunc0 ( 0 ), masterfunc1(0), func ( 0 ), + tcgen( 8 ), base ( 0 ), amp ( 1 ), phase ( 0 ), freq ( 1 ), wave(1) {} + + // "tcmod","deformvertexes","rgbgen", "tcgen" + s32 masterfunc0; + // depends + s32 masterfunc1; + // depends + s32 func; + + s32 tcgen; + + union + { + f32 base; + f32 bulgewidth; + }; + + union + { + f32 amp; + f32 bulgeheight; + }; + + f32 phase; + + union + { + f32 freq; + f32 bulgespeed; + }; + + f32 wave; + + f32 evaluate ( f32 dt ) const + { + // phase in 0 and 1.. + f32 x = core::fract( (dt + phase ) * freq ); + f32 y = 0.f; + + switch ( func ) + { + // sin + case 0: + y = (f32) sin ( x * core::PI64 * 2.0 ); + break; + // cos + case 1: + y = (f32) cos ( x * core::PI64 * 2.0 ); + break; + // square + case 2: + y = x < 0.5f ? 1.f : -1.f; + break; + // triangle + case 3: + y = x < 0.5f ? ( 2.f * x ) - 1.f : ( -2.f * x ) + 2.f; + break; + // sawtooth: + case 4: + y = x; + break; + // inverse sawtooth: + case 5: + y = 1.f - x; + break; + } + + return base + ( y * amp ); + } + + + }; + + // + inline void getModifierFunc ( SModifierFunction& fill, const core::stringc &string, u32 &pos ) + { + if ( string.size() == 0 ) + return; + + static const c8 * funclist[] = + { + "sin","cos","square", "triangle", "sawtooth","inversesawtooth" + }; + + fill.func = quake3::isEqual ( string,pos, funclist,6 ); + if ( fill.func == -2 ) + fill.func = 0; + + fill.base = quake3::getAsFloat ( string, pos ); + fill.amp = quake3::getAsFloat ( string, pos ); + fill.phase = quake3::getAsFloat ( string, pos ); + fill.freq = quake3::getAsFloat ( string, pos ); + } + + + + struct SVarGroup + { + // simple assoziative array + s32 getIndex( const c8 * name ) const + { + SVariable search; + search.name = name; + + return Variable.linear_search ( search ); + } + + // searches for Variable name and returns is content + // if Variable is not found a reference to an Empty String is returned + const core::stringc &get( const c8 * name ) const + { + s32 index = getIndex ( name ); + if ( index < 0 ) + return irrEmptyStringc; + + return Variable [ index ].content; + } + + bool isDefined ( const c8 * name, const c8 * content = 0 ) const + { + for ( u32 i = 0; i != Variable.size (); ++i ) + { + if ( 0 == strcmp ( Variable[i].name.c_str(), name ) ) + { + if ( 0 == content ) + return true; + if ( 0 == strcmp ( Variable[i].content.c_str(), content ) ) + return true; + } + } + return false; + } + + core::array < SVariable > Variable; + }; + + struct SVarGroupList: public IReferenceCounted + { + SVarGroupList () {} + virtual ~SVarGroupList () {} + + core::array < SVarGroup > VariableGroup; + }; + + //! A Parsed Shader Holding Variables ordered in Groups + class SShader + { + public: + bool operator == (const SShader &other ) const + { + return name == other.name; + } + + bool operator < (const SShader &other ) const + { + return name < other.name; + } + + const SVarGroup * getGroup ( u32 stage ) const + { + if ( 0 == VarGroup || stage >= VarGroup->VariableGroup.size () ) + return 0; + + return &VarGroup->VariableGroup [ stage ]; + } + + // id + s32 id; + + // Shader: shader name ( also first variable in first Vargroup ) + // Entity: classname ( variable in Group(1) ) + core::stringc name; + SVarGroupList *VarGroup; // reference + }; + + typedef SShader SEntity; + + typedef core::array < SEntity > tQ3EntityList; + + /* + dump shader like original layout, regardless of internal data holding + no recursive folding.. + */ + inline void dumpVarGroup ( core::stringc &dest, const SVarGroup * group, s32 stack ) + { + core::stringc buf; + s32 i; + + + if ( stack > 0 ) + { + buf = ""; + for ( i = 0; i < stack - 1; ++i ) + buf += '\t'; + + buf += "{\n"; + dest.append ( buf ); + } + + for ( u32 g = 0; g != group->Variable.size(); ++g ) + { + buf = ""; + for ( i = 0; i < stack; ++i ) + buf += '\t'; + + buf += group->Variable[g].name; + buf += " "; + buf += group->Variable[g].content; + buf += "\n"; + dest.append ( buf ); + } + + if ( stack > 1 ) + { + buf = ""; + for ( i = 0; i < stack - 1; ++i ) + buf += '\t'; + + buf += "}\n"; + dest.append ( buf ); + } + + } + + inline core::stringc & dumpShader ( core::stringc &dest, const SShader * shader ) + { + dest = ""; + if ( 0 == shader ) + return dest; + + const SVarGroup * group; + + const u32 size = shader->VarGroup->VariableGroup.size (); + + for ( u32 i = 0; i != size; ++i ) + { + group = &shader->VarGroup->VariableGroup[ i ]; + dumpVarGroup ( dest, group, core::clamp ( (s32) i, 0, 2 ) ); + } + + if ( size <= 1 ) + { + dest.append ( "{\n" ); + } + + dest.append ( "}\n" ); + return dest; + } + + + + /* + quake3 doesn't care much about tga & jpg + load one or multiple files stored in name started at startPos to the texture array textures + if texture is not loaded 0 will be added ( to find missing textures easier) + */ + inline void getTextures ( tTexArray &textures , + const core::stringc &name, u32 &startPos, + io::IFileSystem *fileSystem, + video::IVideoDriver* driver + ) + { + static const char * extension[2] = + { + ".jpg", + ".tga" + }; + + tStringList stringList; + getAsStringList ( stringList, -1, name, startPos ); + + textures.clear(); + + core::stringc loadFile; + for ( u32 i = 0; i!= stringList.size (); ++i ) + { + video::ITexture* texture = 0; + for ( u32 g = 0; g != 2 ; ++g ) + { + core::cutFilenameExtension ( loadFile, stringList[i] ).append ( extension[g] ); + + if ( fileSystem->existFile ( loadFile.c_str() ) ) + { + texture = driver->getTexture( loadFile.c_str () ); + if ( texture ) + { + break; + } + } + } + // take 0 Texture + textures.push_back(texture); + } + } + + + /*! + Manages various Quake3 Shader Styles + */ + class IShaderManager : public IReferenceCounted + { + }; + +} // end namespace quake3 +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IReadFile.h b/src/dep/include/irrlicht/IReadFile.h new file mode 100644 index 0000000..ce4edd5 --- /dev/null +++ b/src/dep/include/irrlicht/IReadFile.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_READ_FILE_H_INCLUDED__ +#define __I_READ_FILE_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing read acess to a file. + class IReadFile : public virtual IReferenceCounted + { + public: + + virtual ~IReadFile() {} + + //! Reads an amount of bytes from the file. + //! \param buffer: Pointer to buffer where to read bytes will be written to. + //! \param sizeToRead: Amount of bytes to read from the file. + //! \return Returns how much bytes were read. + virtual s32 read(void* buffer, u32 sizeToRead) = 0; + + //! Changes position in file, returns true if successful. + //! \param finalPos: Destination position in the file. + //! \param relativeMovement: If set to true, the position in the file is + //! changed relative to current position. Otherwise the position is changed + //! from beginning of file. + //! \return Returns true if successful, otherwise false. + virtual bool seek(long finalPos, bool relativeMovement = false) = 0; + + //! Returns size of file. + //! \return Returns the size of the file in bytes. + virtual long getSize() const = 0; + + //! Returns the current position in the file. + //! \return Returns the current position in the file in bytes. + virtual long getPos() const = 0; + + //! Returns name of file. + //! \return Returns the file name as zero terminated character string. + virtual const c8* getFileName() const = 0; + }; + + //! Internal function, please do not use. + IReadFile* createReadFile(const c8* fileName); + //! Internal function, please do not use. + IReadFile* createLimitReadFile(const c8* fileName, IReadFile* alreadyOpenedFile, long areaSize); + //! Internal function, please do not use. + IReadFile* createMemoryReadFile(void* memory, long size, const c8* fileName, bool deleteMemoryWhenDropped); + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IReferenceCounted.h b/src/dep/include/irrlicht/IReferenceCounted.h new file mode 100644 index 0000000..0c7098e --- /dev/null +++ b/src/dep/include/irrlicht/IReferenceCounted.h @@ -0,0 +1,159 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IREFERENCE_COUNTED_H_INCLUDED__ +#define __I_IREFERENCE_COUNTED_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ + + //! Base class of most objects of the Irrlicht Engine. + /** This class provides reference counting through the methods grab() and drop(). + It also is able to store a debug string for every instance of an object. + Most objects of the Irrlicht + Engine are derived from IReferenceCounted, and so they are reference counted. + + When you create an object in the Irrlicht engine, calling a method + which starts with 'create', an object is created, and you get a pointer + to the new object. If you no longer need the object, you have + to call drop(). This will destroy the object, if grab() was not called + in another part of you program, because this part still needs the object. + Note, that you only need to call drop() to the object, if you created it, + and the method had a 'create' in it. + + A simple example: + + If you want to create a texture, you may want to call an imaginable method + IDriver::createTexture. You call + ITexture* texture = driver->createTexture(dimension2d(128, 128)); + If you no longer need the texture, call texture->drop(). + + If you want to load a texture, you may want to call imaginable method + IDriver::loadTexture. You do this like + ITexture* texture = driver->loadTexture("example.jpg"); + You will not have to drop the pointer to the loaded texture, because + the name of the method does not start with 'create'. The texture + is stored somewhere by the driver. + */ + class IReferenceCounted + { + public: + + //! Constructor. + IReferenceCounted() + : ReferenceCounter(1), DebugName(0) + { + } + + //! Destructor. + virtual ~IReferenceCounted() + { + } + + //! Grabs the object. Increments the reference counter by one. + //! Someone who calls grab() to an object, should later also call + //! drop() to it. If an object never gets as much drop() as grab() + //! calls, it will never be destroyed. + //! The IReferenceCounted class provides a basic reference counting mechanism + //! with its methods grab() and drop(). Most objects of the Irrlicht + //! Engine are derived from IReferenceCounted, and so they are reference counted. + //! + //! When you create an object in the Irrlicht engine, calling a method + //! which starts with 'create', an object is created, and you get a pointer + //! to the new object. If you no longer need the object, you have + //! to call drop(). This will destroy the object, if grab() was not called + //! in another part of you program, because this part still needs the object. + //! Note, that you only need to call drop() to the object, if you created it, + //! and the method had a 'create' in it. + //! + //! A simple example: + //! + //! If you want to create a texture, you may want to call an imaginable method + //! IDriver::createTexture. You call + //! ITexture* texture = driver->createTexture(dimension2d(128, 128)); + //! If you no longer need the texture, call texture->drop(). + //! If you want to load a texture, you may want to call imaginable method + //! IDriver::loadTexture. You do this like + //! ITexture* texture = driver->loadTexture("example.jpg"); + //! You will not have to drop the pointer to the loaded texture, because + //! the name of the method does not start with 'create'. The texture + //! is stored somewhere by the driver. + void grab() const { ++ReferenceCounter; } + + //! Drops the object. Decrements the reference counter by one. + //! Returns true, if the object was deleted. + //! The IReferenceCounted class provides a basic reference counting mechanism + //! with its methods grab() and drop(). Most objects of the Irrlicht + //! Engine are derived from IReferenceCounted, and so they are reference counted. + //! + //! When you create an object in the Irrlicht engine, calling a method + //! which starts with 'create', an object is created, and you get a pointer + //! to the new object. If you no longer need the object, you have + //! to call drop(). This will destroy the object, if grab() was not called + //! in another part of you program, because this part still needs the object. + //! Note, that you only need to call drop() to the object, if you created it, + //! and the method had a 'create' in it. + //! + //! A simple example: + //! + //! If you want to create a texture, you may want to call an imaginable method + //! IDriver::createTexture. You call + //! ITexture* texture = driver->createTexture(dimension2d(128, 128)); + //! If you no longer need the texture, call texture->drop(). + //! If you want to load a texture, you may want to call imaginable method + //! IDriver::loadTexture. You do this like + //! ITexture* texture = driver->loadTexture("example.jpg"); + //! You will not have to drop the pointer to the loaded texture, because + //! the name of the method does not start with 'create'. The texture + //! is stored somewhere by the driver. + bool drop() const + { + _IRR_DEBUG_BREAK_IF(ReferenceCounter <= 0) // someone is doing bad reference counting. + + --ReferenceCounter; + if (!ReferenceCounter) + { + delete this; + return true; + } + + return false; + } + + //! Returns the reference counter. + s32 getReferenceCount() const + { + return ReferenceCounter; + } + + //! Returns the debug name of the object. The Debugname may only be set and + //! changed by the object itself. This method should only be used in Debug mode. + //! \return Returns a string, previously set by setDebugName(); + const c8* getDebugName() const + { + return DebugName; + } + + protected: + + //! Sets the debug name of the object. The Debugname may only be set and + //! changed by the object itself. This method should only be used in Debug mode. + //! \param newName: New debug name to set. + void setDebugName(const c8* newName) + { + DebugName = newName; + } + + private: + + mutable s32 ReferenceCounter; + const c8* DebugName; + }; + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneCollisionManager.h b/src/dep/include/irrlicht/ISceneCollisionManager.h new file mode 100644 index 0000000..433630a --- /dev/null +++ b/src/dep/include/irrlicht/ISceneCollisionManager.h @@ -0,0 +1,151 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_COLLISION_MANAGER_H_INCLUDED__ +#define __I_SCENE_COLLISION_MANAGER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "line3d.h" + +namespace irr +{ + + +namespace scene +{ + class ISceneNode; + class ICameraSceneNode; + class ITriangleSelector; + + //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes. + class ISceneCollisionManager : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~ISceneCollisionManager() {} + + //! Finds the collision point of a line and lots of triangles, if there is one. + //! \param ray: Line with witch collisions are tested. + //! \param selector: TriangleSelector containing the triangles. It can + //! be created for example using ISceneManager::createTriangleSelector() or + //! ISceneManager::createTriangleOctTreeSelector(). + //! \param outCollisionPoint: If a collision is detected, this will contain the + //! position of the nearest collision. + //! \param outTriangle: If a collision is detected, this will contain the triangle + //! with which the ray collided. + //! \return Returns true if a collision was detected and false if not. + virtual bool getCollisionPoint(const core::line3d& ray, + ITriangleSelector* selector, core::vector3df& outCollisionPoint, + core::triangle3df& outTriangle) = 0; + + //! Collides a moving ellipsoid with a 3d world with gravity and returns + //! the resulting new position of the ellipsoid. This can be used for moving + //! a character in a 3d world: The character will slide at walls and is able + //! to walk up stairs. The method used how to calculate the collision result + //! position is based on the paper "Improved Collision detection and Response" + //! by Kasper Fauerby. + //! \param selector: TriangleSelector containing the triangles of the world. + //! It can be created for example using ISceneManager::createTriangleSelector() or + //! ISceneManager::createTriangleOctTreeSelector(). + //! \param ellipsoidPosition: Position of the ellipsoid. + //! \param ellipsoidRadius: Radius of the ellipsoid. + //! \param ellipsoidDirectionAndSpeed: Direction and speed of + //! the movement of the ellipsoid. + //! \param triout: Optional parameter where the last triangle causing a + //! collision is stored, if there is a collision. + //! \param outFalling: Is set to true if the ellipsoid is falling down, caused + //! by gravity. + //! \param slidingSpeed: DOCUMENTATION NEEDED. + //! \param gravityDirectionAndSpeed: Direction and force of gravity. + //! \return Returns the new position of the ellipsoid. + virtual core::vector3df getCollisionResultPosition( + ITriangleSelector* selector, + const core::vector3df &ellipsoidPosition, + const core::vector3df& ellipsoidRadius, + const core::vector3df& ellipsoidDirectionAndSpeed, + core::triangle3df& triout, + bool& outFalling, + f32 slidingSpeed = 0.0005f, + const core::vector3df& gravityDirectionAndSpeed + = core::vector3df(0.0f, 0.0f, 0.0f)) = 0; + + //! Returns a 3d ray which would go through the 2d screen coodinates. + //! \param pos: Screen coordinates in pixels. + //! \param camera: Camera from which the ray starts. If null, the + //! active camera is used. + //! \return Returns a ray starting from the position of the camera + //! and ending at a length of the far value of the camera at a position + //! which would be behind the 2d screen coodinates. + virtual core::line3d getRayFromScreenCoordinates( + core::position2d pos, ICameraSceneNode* camera = 0) = 0; + + //! Calculates 2d screen position from a 3d position. + //! \param pos: 3D position in world space to be transformed into + //! 2d. + //! \param camera: Camera to be used. If null, the currently active + //! camera is used. + //! \return Returns the 2d screen coordinates which a object in the + //! 3d world would have if it would be rendered to the screen. If the + //! 3d position is behind the camera, it is set to (-10000,-10000). In + //! most cases you can ignore this fact, because if you use this method + //! for drawing a decorator over a 3d object, it will be clipped by the + //! screen borders. + virtual core::position2d getScreenCoordinatesFrom3DPosition( + core::vector3df pos, ICameraSceneNode* camera=0) = 0; + + //! Returns the scene node, which is currently visible under the overgiven + //! screencoordinates, viewed from the currently active camera. The collision + //! tests are done using a bounding box for each scene node. + //! \param pos: Position in pixel screen coordinates, under which the returned + //! scene node will be. + //! \param idBitMask: Only scene nodes with an id with bits set like in this mask + //! will be tested. If the BitMask is 0, this feature is disabled. + //! \param bNoDebugObjects: Doesn't take debug objects into account when true. These + // are scene nodes with IsDebugObject() = true. + //! \return Returns the visible scene node under screen coordinates with matching + //! bits in its id. If there is no scene node under this position, 0 is returned. + virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(core::position2d pos, + s32 idBitMask=0, bool bNoDebugObjects = false) = 0; + + //! Returns the nearest scene node which collides with a 3d ray and + //! which id matches a bitmask. The collision tests are done using a bounding + //! box for each scene node. + //! \param ray: Line with witch collisions are tested. + //! \param idBitMask: Only scene nodes with an id with bits set like in this mask + //! will be tested. If the BitMask is 0, this feature is disabled. + //! \param bNoDebugObjects: Doesn't take debug objects into account when true. These + // are scene nodes with IsDebugObject() = true. + //! \return Returns the scene node nearest to ray.start, which collides with the + //! ray and matches the idBitMask, if the mask is not null. If no scene + //! node is found, 0 is returned. + virtual ISceneNode* getSceneNodeFromRayBB(core::line3d ray, + s32 idBitMask=0, bool bNoDebugObjects = false) = 0; + + //! Returns the scene node, at which the overgiven camera is looking at and + //! which id matches the bitmask. A ray is simply casted from the position + //! of the camera to the view target position, and all scene nodes are tested + //! against this ray. The collision tests are done using a bounding + //! box for each scene node. + //! \param camera: Camera from which the ray is casted. + //! \param idBitMask: Only scene nodes with an id with bits set like in this mask + //! will be tested. If the BitMask is 0, this feature is disabled. + //! \param bNoDebugObjects: Doesn't take debug objects into account when true. These + // are scene nodes with IsDebugObject() = true. + //! \return Returns the scene node nearest to the camera, which collides with the + //! ray and matches the idBitMask, if the mask is not null. If no scene + //! node is found, 0 is returned. + virtual ISceneNode* getSceneNodeFromCameraBB(ICameraSceneNode* camera, + s32 idBitMask=0, bool bNoDebugObjects = false) = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneManager.h b/src/dep/include/irrlicht/ISceneManager.h new file mode 100644 index 0000000..f64ae5c --- /dev/null +++ b/src/dep/include/irrlicht/ISceneManager.h @@ -0,0 +1,1238 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_MANAGER_H_INCLUDED__ +#define __I_SCENE_MANAGER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "vector3d.h" +#include "dimension2d.h" +#include "SColor.h" +#include "ETerrainElements.h" +#include "ESceneNodeTypes.h" +#include "EMeshWriterEnums.h" +#include "SceneParameters.h" + +namespace irr +{ + struct SKeyMap; + struct SEvent; + +namespace io +{ + class IReadFile; + class IAttributes; + class IWriteFile; +} // end namespace io + +namespace gui +{ + class IGUIFont; + class IGUIEnvironment; +} // end namespace gui + +namespace video +{ + class IVideoDriver; + class SMaterial; + class IImage; + class ITexture; +} // end namespace video + +namespace scene +{ + class IMeshWriter; + + //! Enumeration for render passes. + /** A parameter passed to the registerNodeForRendering() method of the ISceneManager, + specifying when the mode wants to be drawn in relation to the other nodes. */ + enum E_SCENE_NODE_RENDER_PASS + { + //! Camera pass. The active view is set up here. + //! The very first pass. + ESNRP_CAMERA, + + //! In this pass, lights are transformed into camera space and added to the driver + ESNRP_LIGHT, + + //! This is used for sky boxes. + ESNRP_SKY_BOX, + + //! All normal objects can use this for registering themselves. + //! This value will never be returned by ISceneManager::getSceneNodeRenderPass(). + //! The scene manager will determine by itself if an object is + //! transparent or solid and register the object as SNRT_TRANSPARENT or + //! SNRT_SOLD automatically if you call registerNodeForRendering with this + //! value (which is default). Note that it will register the node only as ONE type. + //! If your scene node has both solid and transparent material types register + //! it twice (one time as SNRT_SOLID, the other time as SNRT_TRANSPARENT) and + //! in the render() method call getSceneNodeRenderPass() to find out the current + //! render pass and render only the corresponding parts of the node. + ESNRP_AUTOMATIC, + + //! Solid scene nodes or special scene nodes without materials. + ESNRP_SOLID, + + //! Drawn after the transparent nodes, the time for drawing shadow volumes + ESNRP_SHADOW, + + //! Transparent scene nodes, drawn after shadow nodes. They are sorted from back + //! to front and drawn in that order. + ESNRP_TRANSPARENT, + + //! Scene Nodes with special support + ESNRP_SHADER_0, + ESNRP_SHADER_1, + ESNRP_SHADER_2, + ESNRP_SHADER_3, + ESNRP_SHADER_4, + ESNRP_SHADER_5, + ESNRP_SHADER_6, + ESNRP_SHADER_7, + ESNRP_SHADER_8, + ESNRP_SHADER_9, + ESNRP_SHADER_10, + + //! Never used, value specifing how much parameters there are. + ESNRP_COUNT + }; + + class IMesh; + class IMeshBuffer; + class IAnimatedMesh; + class IMeshCache; + class ISceneNode; + class ICameraSceneNode; + class IAnimatedMeshSceneNode; + class ISceneNodeAnimator; + class ISceneNodeAnimatorCollisionResponse; + class ILightSceneNode; + class IBillboardSceneNode; + class ITerrainSceneNode; + class IMeshSceneNode; + class IMeshLoader; + class ISceneCollisionManager; + class IParticleSystemSceneNode; + class IDummyTransformationSceneNode; + class ITriangleSelector; + class IMetaTriangleSelector; + class IMeshManipulator; + class ITextSceneNode; + class ISceneNodeFactory; + class ISceneNodeAnimatorFactory; + class ISceneUserDataSerializer; + + namespace quake3 + { + class SShader; + } // end namespace quake3 + + //! The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff. + /** All Scene nodes can be created only here. There is a always growing list of scene + nodes for lots of purposes: Indoor rendering scene nodes like the Octree + (addOctTreeSceneNode()) or the terrain renderer (addTerrainSceneNode()), + different Camera scene nodes (addCameraSceneNode(), addCameraSceneNodeMaya()), + scene nodes for Light (addLightSceneNode()), Billboards (addBillboardSceneNode()) + and so on. + A scene node is a node in the hierachical scene graph. Every scene node may have children, + which are other scene nodes. Children move relative the their parents position. If the parent of a node is not + visible, its children won't be visible, too. In this way, it is for example easily possible + to attach a light to a moving car or to place a walking character on a moving platform + on a moving ship. + The SceneManager is also able to load 3d mesh files of different formats. Take a look + at getMesh() to find out what formats are supported. And if these formats are not enough + use addExternalMeshLoader() to add new formats to the engine. + */ + class ISceneManager : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~ISceneManager() {} + + //! Returns pointer to an animateable mesh. Loads the file if not loaded already. + /** + * If you want to remove a loaded mesh from the cache again, use removeMesh(). + * Currently there are the following mesh formats supported: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FormatDescription
3D Studio (.3ds)Loader for 3D-Studio files which lots of 3D packages are able to export. + * Only static meshes are currently supported by this importer.
Bliz Basic B3D (.b3d)Loader for blitz basic files, developed by Mark Sibly, also supports animations.
Cartography shop 4 (.csm)Cartography Shop is a modeling program for creating architecture and calculating + * lighting. Irrlicht can directly import .csm files thanks to the IrrCSM library + * created by Saurav Mohapatra which is now integrated directly in Irrlicht. + * If you are using this loader, please note that you'll have to set the path + * of the textures before loading .csm files. You can do this using SceneManager->getParameters()->setParameter(scene::CSM_TEXTURE_PATH, + * "path/to/your/textures");
COLLADA (.dae, .xml)COLLADA is an open Digital Asset Exchange Schema for the interactive 3D industry. There are + * exporters and importers for this format available for most of the big 3d packages + * at http://collada.org. Irrlicht can import COLLADA files by using the + * ISceneManager::getMesh() method. COLLADA files need not contain only one single mesh + * but multiple meshes and a whole scene setup with lights, cameras and mesh instances, + * this loader can set up a scene as described by the COLLADA file instead of loading + * and returning one single mesh. By default, this loader behaves like the other loaders + * and does not create instances, but it can be switched into this mode by using + * SceneManager->getParameters()->setParameter(COLLADA_CREATE_SCENE_INSTANCES, true); + * Created scene nodes will be named as the names of the nodes in the + * COLLADA file. The returned mesh is just a dummy object in this mode. Meshes included in + * the scene will be added into the scene manager with the following naming scheme: + * path/to/file/file.dea#meshname. The loading of such meshes is logged. + * Currently, this loader is able to create meshes (made of only polygons), lights, + * and cameras. Materials and animations are currently not supported but this will + * change with future releases. + *
Delgine DeleD (.dmf)DeleD (delgine.com) is a 3D editor and level-editor combined into one and is specifically + * designed for 3D game-development. With this loader, it is possible to directly load + * all geometry is as well as textures and lightmaps from .dmf files. To set texture and + * material paths, see scene::DMF_USE_MATERIALS_DIRS and scene::DMF_TEXTURE_PATH. It is also + * possible to flip the alpha texture by setting scene::DMF_FLIP_ALPHA_TEXTURES to true and + * to set the material transparent reference value by setting scene::DMF_ALPHA_CHANNEL_REF to + * a float between 0 and 1. The loader is + * based on Salvatore Russo's .dmf loader, I just changed some parts of it. Thanks to + * Salvatore for his work and for allowing me to use his code in Irrlicht and put it under Irrlicht's + * license. For newer and more enchanced versions of the loader, take a look at delgine.com. + *
DirectX (.x)Platform independent importer (so not D3D-only) for .x files. Most 3D + * packages can export these natively and there are several tools for them + * available. (e.g. the Maya exporter included in the DX SDK) .x files can + * include skeletal animations and Irrlicht is able to play and display them. + * Currently, Irrlicht only supports uncompressed .x files.
Maya (.obj)Most 3D software can create .obj files which contain static geometry without + * material data. The material files .mtl are also supported. This importer + * for Irrlicht can load them directly.
Milkshape (.ms3d).MS3D files contain models and sometimes skeletal animations from the + * Milkshape 3D modeling and animation software. This importer for Irrlicht + * can display and/or animate these files.
My3D (.my3d).my3D is a flexible 3D file format. The My3DTools contains plug-ins to + * export .my3D files from several 3D packages. With this built-in importer, + * Irrlicht can read and display those files directly. This loader was written + * by Zhuck Dimitry who also created the whole My3DTools package. If you are using this loader, please + * note that you can set the path of the textures before loading .my3d files. + * You can do this using SceneManager->getParameters()->setParameter(scene::MY3D_TEXTURE_PATH, + * "path/to/your/textures");
OCT (.oct)The oct file format contains 3D geometry and lightmaps and can be loaded + * directly by Irrlicht. OCT files
+ * can be created by FSRad, Paul Nette's radiosity processor or exported from + * Blender using OCTTools which can be found in the exporters/OCTTools directory + * of the SDK. Thanks to Murphy McCauley for creating all this.
OGRE Meshes (.mesh)Ogre .mesh files contain 3D data for the OGRE 3D engine. Irrlicht can read and + * display them directly with this importer. To define materials for the mesh, + * copy a .material file named like the corresponding .mesh file where the .mesh + * file is. (For example ogrehead.material for ogrehead.mesh). Thanks to Christian Stehno + * who wrote and contributed this loader.
Pulsar LMTools (.lmts)LMTools is a set of tools (Windows & Linux) for creating lightmaps. + * Irrlicht can directly read .lmts files thanks to
+ * the importer created by Jonas Petersen. If you are using this loader, please + * note that you can set the path of the textures before loading .lmts files. + * You can do this using SceneManager->getParameters()->setParameter(scene::LMTS_TEXTURE_PATH, + * "path/to/your/textures"); Notes for
+ * this version of the loader:
+ * - It does not recognice/support user data in the *.lmts files.
+ * - The TGAs generated by LMTools don't work in Irrlicht for some reason (the + * textures are upside down). Opening and resaving them in a graphics app will + * solve the problem.
Quake 3 levels (.bsp)Quake 3 is a popular game by IDSoftware, and .pk3 files contain .bsp files + * and textures/lightmaps describing huge
+ * prelighted levels. Irrlicht can read .pk3 and .bsp files directly and thus + * render Quake 3 levels directly. Written by Nikolaus Gebhardt enhanced by + * Dean P. Macri with the curved surfaces feature.
Quake 2 models (.md2)Quake 2 models are characters with morph target animation. Irrlicht can + * read, display and animate them directly with this importer.
+ * + * To load and display a mesh quickly, just do this: + * \code + * SceneManager->addAnimatedMeshSceneNode( + * SceneManager->getMesh("yourmesh.3ds")); + * \endcode + * If you would like to implement and add your own file format loader to Irrlicht, + * see addExternalMeshLoader(). + * \param filename: Filename of the mesh to load. + * \return Returns NULL if failed and the pointer to the mesh if + * successful. + * This pointer should not be dropped. See IReferenceCounted::drop() for more information. + **/ + virtual IAnimatedMesh* getMesh(const c8* filename) = 0; + + //! Returns an interface to the mesh cache which is shared beween all existing scene managers. + /** With this interface, it is possible to manually add new loaded + meshes (if ISceneManager::getMesh() is not sufficient), to remove them and to iterate + through already loaded meshes. */ + virtual IMeshCache* getMeshCache() = 0; + + //! Returns the video driver. + /** \return Returns pointer to the video Driver. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual video::IVideoDriver* getVideoDriver() = 0; + + //! Returns the active GUIEnvironment + /** \return Returns pointer to the GUIEnvironment + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual gui::IGUIEnvironment* getGUIEnvironment() = 0; + + //! Adds a test scene node for test purposes to the scene. + /** It is a simple cube of (1,1,1) size. + \param size: Size of the cube. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Returns pointer to the created test scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a sphere scene node for test purposes to the scene. + /** It is a simple sphere. + \param radius: Radius of the sphere. + \param polyCount: Polycount of the sphere. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Returns pointer to the created test scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a scene node for rendering an animated mesh model. + /** \param mesh: Pointer to the loaded animated mesh to be displayed. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering a static mesh. + /** \param mesh: Pointer to the loaded static mesh to be displayed. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering a animated water surface mesh. + /** Looks really good when the Material type EMT_TRANSPARENT_REFLECTION + is used. + \param waveHeight: Height of the water waves. + \param waveSpeed: Speed of the water waves. + \param waveLength: Lenght of a water wave. + \param mesh: Pointer to the loaded static mesh to be displayed with water waves on it. + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh, + f32 waveHeight=2.0f, f32 waveSpeed=300.0f, f32 waveLength=10.0f, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + + //! Adds a scene node for rendering using a octtree to the scene graph. + /** This a good method for rendering + scenes with lots of geometry. The Octree is built on the fly from the mesh. + \param mesh: The mesh containing all geometry from which the octtree will be build. + If this animated mesh has more than one frames in it, the first frame is taken. + \param parent: Parent node of the octtree node. + \param id: id of the node. This id can be used to identify the node. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys than this value it will not be split into + smaller nodes. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Returns the pointer to the OctTree if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a scene node for rendering using a octtree to the scene graph. + /** This a good method for rendering + scenes with lots of geometry. The Octree is built on the fly from the mesh, much + faster then a bsp tree. + \param mesh: The mesh containing all geometry from which the octtree will be build. + \param parent: Parent node of the octtree node. + \param id: id of the node. This id can be used to identify the node. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys than this value it will not be split into + smaller nodes. + \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed. + \return Returns the pointer to the octtree if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0; + + //! Adds a camera scene node to the scene graph and sets it as active camera. + /** This camera does not react on user input like for example the one created with + addCameraSceneNodeFPS(). If you want to move or animate it, use animators or the + ISceneNode::setPosition(), ICameraSceneNode::setTarget() etc methods. + \param position: Position of the space relative to its parent where the camera will be placed. + \param lookat: Position where the camera will look at. Also known as target. + \param parent: Parent scene node of the camera. Can be null. If the parent moves, + the camera will move too. + \param id: id of the camera. This id can be used to identify the camera. + \return Returns pointer to interface to camera if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,100), s32 id=-1) = 0; + + //! Adds a maya style user controlled camera scene node to the scene graph. + /** The maya camera is able to be controlled with the mouse similar + like in the 3D Software Maya by Alias Wavefront. + \param parent: Parent scene node of the camera. Can be null. + \param rotateSpeed: Rotation speed of the camera. + \param zoomSpeed: Zoom speed of the camera. + \param translationSpeed: TranslationSpeed of the camera. + \param id: id of the camera. This id can be used to identify the camera. + \return Returns a pointer to the interface of the camera if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent = 0, + f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f, f32 translationSpeed = 1500.0f, s32 id=-1) = 0; + + //! Adds a camera scene node which is able to be controlled with the mouse and keys like in most first person shooters (FPS). + /** Look with the mouse, move with cursor keys. If you do not like the default + key layout, you may want to specify your own. For example to make the camera + be controlled by the cursor keys AND the keys W,A,S, and D, do something + like this: + \code + SKeyMap keyMap[8]; + keyMap[0].Action = EKA_MOVE_FORWARD; + keyMap[0].KeyCode = KEY_UP; + keyMap[1].Action = EKA_MOVE_FORWARD; + keyMap[1].KeyCode = KEY_KEY_W; + + keyMap[2].Action = EKA_MOVE_BACKWARD; + keyMap[2].KeyCode = KEY_DOWN; + keyMap[3].Action = EKA_MOVE_BACKWARD; + keyMap[3].KeyCode = KEY_KEY_S; + + keyMap[4].Action = EKA_STRAFE_LEFT; + keyMap[4].KeyCode = KEY_LEFT; + keyMap[5].Action = EKA_STRAFE_LEFT; + keyMap[5].KeyCode = KEY_KEY_A; + + keyMap[6].Action = EKA_STRAFE_RIGHT; + keyMap[6].KeyCode = KEY_RIGHT; + keyMap[7].Action = EKA_STRAFE_RIGHT; + keyMap[7].KeyCode = KEY_KEY_D; + + camera = sceneManager->addCameraSceneNodeFPS(0, 100, 500, -1, keyMap, 8); + \endcode + \param parent: Parent scene node of the camera. Can be null. + \param rotateSpeed: Speed with which the camera is rotated. This can be done + only with the mouse. + \param moveSpeed: Speed with which the camera is moved. Movement is done with + the cursor keys. + \param id: id of the camera. This id can be used to identify the camera. + \param keyMapArray: Optional pointer to an array of a keymap, specifying what + keys should be used to move the camera. If this is null, the default keymap + is used. You can define actions more then one time in the array, to bind + multiple keys to the same action. + \param keyMapSize: Amount of items in the keymap array. + \param noVerticalMovement: Setting this to true makes the camera only move within a + horizontal plane, and disables vertical movement as known from most ego shooters. Default + is 'false', with which it is possible to fly around in space, if no gravity is there. + \param jumpSpeed: Speed with which the camera is moved when jumping. + \return Returns a pointer to the interface of the camera if successful, otherwise 0. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0, + f32 rotateSpeed = 100.0f, f32 moveSpeed = 500.0f, s32 id=-1, + SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false, + f32 jumpSpeed = 0.f) = 0; + + //! Adds a dynamic light scene node to the scene graph. + /** The light will cast dynamic light on all + other scene nodes in the scene, which have the material flag video::MTF_LIGHTING + turned on. (This is the default setting in most scene nodes). + \param parent: Parent scene node of the light. Can be null. If the parent moves, + the light will move too. + \param position: Position of the space relative to its parent where the light will be placed. + \param color: Diffuse color of the light. Ambient or Specular colors can be set manually with + the ILightSceneNode::getLightData() method. + \param radius: Radius of the light. + \param id: id of the node. This id can be used to identify the node. + \return Returns pointer to the interface of the light if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), + f32 radius=100.0f, s32 id=-1) = 0; + + //! Adds a billboard scene node to the scene graph. + /** A billboard is like a 3d sprite: A 2d element, + which always looks to the camera. It is usually used for things like explosions, fire, + lensflares and things like that. + \param parent: Parent scene node of the billboard. Can be null. If the parent moves, + the billboard will move too. + \param position: Position of the space relative to its parent where the billboard will be placed. + \param size: Size of the billboard. This size is 2 dimensional because a billboard only has + width and height. + \param id: An id of the node. This id can be used to identify the node. + \param shade_top: vertex color top + \param shade_down: vertex color down + \return Returns pointer to the billboard if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0; + + //! Adds a skybox scene node to the scene graph. + /** A skybox is a big cube with 6 textures on it and + is drawn around the camera position. + \param top: Texture for the top plane of the box. + \param bottom: Texture for the bottom plane of the box. + \param left: Texture for the left plane of the box. + \param right: Texture for the right plane of the box. + \param front: Texture for the front plane of the box. + \param back: Texture for the back plane of the box. + \param parent: Parent scene node of the skybox. A skybox usually has no parent, + so this should be null. Note: If a parent is set to the skybox, the box will not + change how it is drawn. + \param id: An id of the node. This id can be used to identify the node. + \return Returns a pointer to the sky box if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent = 0, s32 id=-1) = 0; + + //! Adds a skydome scene node to the scene graph. + /** A skydome is a large (half-) sphere with a panoramic texture + on the inside and is drawn around the camera position. + \param texture: Texture for the dome. + \param horiRes: Number of vertices of a horizontal layer of the sphere. + \param vertRes: Number of vertices of a vertical layer of the sphere. + \param texturePercentage: How much of the height of the texture is used. Should be between 0 and 1. + \param spherePercentage: How much of the sphere is drawn. Value should be between 0 and 2, where 1 is an exact half-sphere and 2 is a full sphere. + \param parent: Parent scene node of the dome. A dome usually has no parent, + so this should be null. Note: If a parent is set, the dome will not + change how it is drawn. + \param id: An id of the node. This id can be used to identify the node. + \return Returns a pointer to the sky dome if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes, u32 vertRes, f64 texturePercentage, f64 spherePercentage, + ISceneNode* parent = 0, s32 id=-1) = 0; + + //! Adds a particle system scene node to the scene graph. + /** \param withDefaultEmitter: Creates a default working point emitter + which emitts some particles. Set this to true to see a particle system + in action. If set to false, you'll have to set the emitter you want by + calling IParticleSystemSceneNode::setEmitter(). + \param parent: Parent of the scene node. Can be NULL if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: Position of the space relative to its parent where the + scene node will be placed. + \param rotation: Initital rotation of the scene node. + \param scale: Initial scale of the scene node. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IParticleSystemSceneNode* addParticleSystemSceneNode( + bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0; + + //! Adds a terrain scene node to the scene graph. + /** This node implements is a simple terrain renderer which uses + a technique known as geo mip mapping + for reducing the detail of triangle blocks which are far away. + The code for the TerrainSceneNode is based on the terrain + renderer by Soconne and the GeoMipMapSceneNode developed by + Spintz. They made their code available for Irrlicht and allowed + it to be distributed under this licence. I only modified some + parts. A lot of thanks go to them. + + This scene node is capable of loading terrains and updating + the indices at runtime to enable viewing very large terrains + very quickly. It uses a CLOD (Continuous Level of Detail) + algorithm which updates the indices for each patch based on + a LOD (Level of Detail) which is determined based on a patch's + distance from the camera. + + The patch size of the terrain must always be a size of ( 2^N+1, i.e. 8+1(9), 16+1(17), etc. ). + The MaxLOD available is directly dependent on the patch size of the terrain. LOD 0 contains all + of the indices to draw all the triangles at the max detail for a patch. As each LOD goes up by 1 + the step taken, in generating indices increases by - 2^LOD, so for LOD 1, the step taken is 2, for + LOD 2, the step taken is 4, LOD 3 - 8, etc. The step can be no larger than the size of the patch, + so having a LOD of 8, with a patch size of 17, is asking the algoritm to generate indices every + 2^8 ( 256 ) vertices, which is not possible with a patch size of 17. The maximum LOD for a patch + size of 17 is 2^4 ( 16 ). So, with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( every + 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every 8 vertices ) and LOD 4 ( every 16 vertices ). + \param heightMapFileName: The name of the file on disk, to read vertex data from. This should + be a gray scale bitmap. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: The absolute position of this node. + \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like + your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ). + If you use a Y scaling factor of 0.0f, then your terrain will be flat. + \param vertexColor: The default color of all the vertices. If no texture is associated + with the scene node, then all vertices will be this color. Defaults to white. + \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you + know what you are doing, this might lead to strange behaviour. + \param patchSize: patch size of the terrain. Only change if you + know what you are doing, this might lead to strange behaviour. + \param smoothFactor: The number of times the vertices are smoothed. + \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap. + \return Returns pointer to the created scene node. Can be null if the + terrain could not be created, for example because the heightmap could not be loaded. + The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ITerrainSceneNode* addTerrainSceneNode( + const c8* heightMapFileName, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false) = 0; + + //! Adds a terrain scene node to the scene graph. + /** Just like the other addTerrainSceneNode() method, but takes an IReadFile + pointer as parameter for the heightmap. For more informations take a look + at the other function. + \param heightMapFile: The file handle to read vertex data from. This should + be a gray scale bitmap. + \param parent: Parent of the scene node. Can be 0 if no parent. + \param id: Id of the node. This id can be used to identify the scene node. + \param position: The absolute position of this node. + \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like + your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ). + If you use a Y scaling factor of 0.0f, then your terrain will be flat. + \param vertexColor: The default color of all the vertices. If no texture is associated + with the scene node, then all vertices will be this color. Defaults to white. + \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you + know what you are doing, this might lead to strange behaviour. + \param patchSize: patch size of the terrain. Only change if you + know what you are doing, this might lead to strange behaviour. + \param smoothFactor: The number of times the vertices are smoothed. + \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap. + \return Returns pointer to the created scene node. Can be null if the + terrain could not be created, for example because the heightmap could not be loaded. + The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ITerrainSceneNode* addTerrainSceneNode( + io::IReadFile* heightMapFile, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false) = 0; + + //! Adds a quake3 scene node to the scene graph. + /** A Quake3 Scene renders multiple meshes for a specific HighLanguage Shader (Quake3 Style ) + \return Returns a pointer to the quake3 scene node if successful, otherwise NULL. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addQuake3SceneNode(IMeshBuffer* meshBuffer, const quake3::SShader * shader, + ISceneNode* parent=0, s32 id=-1 + ) = 0; + + + //! Adds an empty scene node to the scene graph. + /** Can be used for doing advanced transformations + or structuring the scene graph. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ISceneNode* addEmptySceneNode(ISceneNode* parent=0, s32 id=-1) = 0; + + //! Adds a dummy transformation scene node to the scene graph. + /** This scene node does not render itself, and does not respond to set/getPosition, + set/getRotation and set/getScale. Its just a simple scene node that takes a + matrix as relative transformation, making it possible to insert any transformation + anywhere into the scene graph. + \return Returns pointer to the created scene node. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode( + ISceneNode* parent=0, s32 id=-1) = 0; + + //! Adds a text scene node, which is able to display 2d text at a position in three dimensional space + virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + video::SColor color=video::SColor(100,255,255,255), + ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0), + s32 id=-1) = 0; + + //! Adds a text scene node, which uses billboards + virtual ITextSceneNode* addBillboardTextSceneNode( gui::IGUIFont* font, const wchar_t* text, + ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0; + + //! Adds a Hill Plane mesh to the mesh pool. + /** The mesh is generated on the fly + and looks like a plane with some hills on it. It is uses mostly for quick + tests of the engine only. You can specify how many hills there should be + on the plane and how high they should be. Also you must specify a name for + the mesh, because the mesh is added to the mesh pool, and can be retrieved + again using ISceneManager::getMesh() with the name as parameter. + \param name: The name of this mesh which must be specified in order + to be able to retrieve the mesh later with ISceneManager::getMesh(). + \param tileSize: Size of a tile of the mesh. (10.0f, 10.0f) would be a + good value to start, for example. + \param tileCount: Specifies how much tiles there will be. If you specifiy + for example that a tile has the size (10.0f, 10.0f) and the tileCount is + (10,10), than you get a field of 100 tiles which has the dimension 100.0fx100.0f. + \param material: Material of the hill mesh. + \param hillHeight: Height of the hills. If you specify a negative value + you will get holes instead of hills. If the height is 0, no hills will be + created. + \param countHills: Amount of hills on the plane. There will be countHills.X + hills along the X axis and countHills.Y along the Y axis. So in total there + will be countHills.X * countHills.Y hills. + \param textureRepeatCount: Defines how often the texture will be repeated in + x and y direction. + \return Returns null if the creation failed. The reason could be that you + specified some invalid parameters or that a mesh with that name already + exists. If successful, a pointer to the mesh is returned. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addHillPlaneMesh(const c8* name, + const core::dimension2d& tileSize, const core::dimension2d& tileCount, + video::SMaterial* material = 0, f32 hillHeight = 0.0f, + const core::dimension2d& countHills = core::dimension2d(0.0f, 0.0f), + const core::dimension2d& textureRepeatCount = core::dimension2d(1.0f, 1.0f)) = 0; + + //! Adds a static terrain mesh to the mesh pool. + /** The mesh is generated on the fly + from a texture file and a height map file. Both files may be huge + (8000x8000 pixels would be no problem) because the generator splits the + files into smaller textures if necessary. + You must specify a name for the mesh, because the mesh is added to the mesh pool, + and can be retrieved again using ISceneManager::getMesh() with the name as parameter. + \param meshname: The name of this mesh which must be specified in order + to be able to retrieve the mesh later with ISceneManager::getMesh(). + \param texture: Texture for the terrain. Please note that this is not a + hardware texture as usual (ITexture), but an IImage software texture. + You can load this texture with IVideoDriver::createImageFromFile(). + \param heightmap: A grayscaled heightmap image. Like the texture, + it can be created with IVideoDriver::createImageFromFile(). The amount + of triangles created depends on the size of this texture, so use a small + heightmap to increase rendering speed. + \param stretchSize: Parameter defining how big a is pixel on the heightmap. + \param maxHeight: Defines how height a white pixel on the heighmap is. + \param defaultVertexBlockSize: Defines the initial dimension between vertices. + \return Returns null if the creation failed. The reason could be that you + specified some invalid parameters, that a mesh with that name already + exists, or that a texture could not be found. If successful, a pointer to the mesh is returned. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual IAnimatedMesh* addTerrainMesh(const c8* meshname, + video::IImage* texture, video::IImage* heightmap, + const core::dimension2d& stretchSize = core::dimension2d(10.0f,10.0f), + f32 maxHeight=200.0f, + const core::dimension2d& defaultVertexBlockSize = core::dimension2d(64,64)) = 0; + + //! add a static arrow mesh to the meshpool + virtual IAnimatedMesh* addArrowMesh(const c8* name, + video::SColor vtxColor0=0xFFFFFFFF, + video::SColor vtxColor1=0xFFFFFFFF, + u32 tesselationCylinder=4, u32 tesselationCone=8, + f32 height=1.f, f32 cylinderHeight=0.6f, + f32 width0=0.05f, f32 width1=0.3f) = 0; + + //! add a static sphere mesh to the meshpool + virtual IAnimatedMesh* addSphereMesh(const c8* name, + f32 radius=5.f, u32 polyCountX = 16, + u32 polyCountY = 16) = 0; + + //! Returns the root scene node. + /** This is the scene node which is parent + of all scene nodes. The root scene node is a special scene node which + only exists to manage all scene nodes. It will not be rendered and cannot + be removed from the scene. + \return Returns a pointer to the root scene node. */ + virtual ISceneNode* getRootSceneNode() = 0; + + //! Returns the first scene node with the specified id. + /** \param id: The id to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Returns pointer to the first scene node with this id, + and null if no scene node could be found. */ + virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0) = 0; + + //! Returns the first scene node with the specified name. + /** \param name: The name to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Returns pointer to the first scene node with this id, + and null if no scene node could be found. */ + virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0) = 0; + + //! Returns the first scene node with the specified type. + /** \param type: The type to search for + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. + \return Returns pointer to the first scene node with this type, + and null if no scene node could be found. */ + virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0) = 0; + + //! returns scene nodes by type. + /** \param type: Type of scene node to find. + \param outNodes: array to be filled with results. + \param start: Scene node to start from. All children of this scene + node are searched. If null is specified, the root scene node is + taken. */ + virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start=0) = 0; + + //! Returns the current active camera. + /** \return The active camera is returned. Note that this can be NULL, if there + was no camera created yet. */ + virtual ICameraSceneNode* getActiveCamera() = 0; + + //! Sets the currently active camera. + /** The previous active camera will be deactivated. + \param camera: The new camera which should be active. */ + virtual void setActiveCamera(ICameraSceneNode* camera) = 0; + + //! Sets the color of stencil buffers shadows drawn by the scene manager. + virtual void setShadowColor(video::SColor color = video::SColor(150,0,0,0)) = 0; + + //! Returns the current color of shadows. + virtual video::SColor getShadowColor() const = 0; + + //! Registers a node for rendering it at a specific time. + /** This method should only be used by SceneNodes when they get a + ISceneNode::OnRegisterSceneNode() call. + \param node: Node to register for drawing. Usually scene nodes would set 'this' + as parameter here because they want to be drawn. + \param pass: Specifies when the mode wants to be drawn in relation to the other nodes. + For example, if the node is a shadow, it usually wants to be drawn after all other nodes + and will use ESNRP_SHADOW for this. See E_SCENE_NODE_RENDER_PASS for details. + \return scene will be rendered ( passed culling ) */ + virtual u32 registerNodeForRendering(ISceneNode* node, + E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC) = 0; + + //! Draws all the scene nodes. + /** This can only be invoked between + IVideoDriver::beginScene() and IVideoDriver::endScene(). Please note that + the scene is not only drawn when calling this, but also animated + by existing scene node animators, culling of scene nodes is done, etc. */ + virtual void drawAll() = 0; + + //! Creates a rotation animator, which rotates the attached scene node around itself. + /** \param rotationPerSecond: Specifies the speed of the animation + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationPerSecond) = 0; + + //! Creates a fly circle animator, which lets the attached scene node fly around a center. + /** \param center: Center of the circle. + \param radius: Radius of the circle. + \param speed: Specifies the speed of the flight. + \param direction: Specifies the upvector used for alignment of the mesh. + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createFlyCircleAnimator(const core::vector3df& center, + f32 radius, f32 speed=0.001f, const core::vector3df& direction= core::vector3df ( 0.f, 1.f, 0.f ) ) = 0; + + //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points. + /** \param startPoint: Start point of the line. + \param endPoint: End point of the line. + \param timeForWay: Time in milli seconds how long the node should need to + move from the start point to the end point. + \param loop: If set to false, the node stops when the end point is reached. + If loop is true, the node begins again at the start. + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop=false) = 0; + + //! Creates a texture animator, which switches the textures of the target scene node based on a list of textures. + /** \param textures: List of textures to use. + \param timePerFrame: Time in milliseconds, how long any texture in the list + should be visible. + \param loop: If set to to false, the last texture remains set, and the animation + stops. If set to true, the animation restarts with the first texture. + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createTextureAnimator(const core::array& textures, + s32 timePerFrame, bool loop=true) = 0; + + //! Creates a scene node animator, which deletes the scene node after some time automatically. + /** \param timeMs: Time in milliseconds, after when the node will be deleted. + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will animate it. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMs) = 0; + + //! Creates a special scene node animator for doing automatic collision detection and response. + /** See ISceneNodeAnimatorCollisionResponse for details. + \param world: Triangle selector holding all triangles of the world with which + the scene node may collide. You can create a triangle selector with + ISceneManager::createTriangleSelector(); + \param sceneNode: SceneNode which should be manipulated. After you added this animator + to the scene node, the scene node will not be able to move through walls and is + affected by gravity. + \param ellipsoidRadius: Radius of the ellipsoid with which collision detection and + response is done. If you have got a scene node, and you are unsure about + how big the radius should be, you could use the following code to determine + it: + \code + const core::aabbox& box = yourSceneNode->getBoundingBox(); + core::vector3df radius = box.MaxEdge - box.getCenter(); + \endcode + \param gravityPerSecond: Sets the gravity of the environment. A good example value would be + core::vector3df(0,-100.0f,0) for letting gravity affect all object to + fall down. For bigger gravity, make increase the length of the vector. + You can disable gravity by setting it to core::vector3df(0,0,0). + \param ellipsoidTranslation: By default, the ellipsoid for collision detection is created around + the center of the scene node, which means that the ellipsoid surrounds + it completely. If this is not what you want, you may specify a translation + for the ellipsoid. + \param slidingValue: DOCUMENTATION NEEDED. + \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + and the animator will cause it to do collision detection and response. + If you no longer need the animator, you should call ISceneNodeAnimator::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingValue = 0.0005f) = 0; + + //! Creates a follow spline animator. + /** The animator modifies the position of + the attached scene node to make it follow a hermite spline. + The code of the is based on a scene node + Matthias Gall sent in. Thanks! I adapted the code just a little bit. Matthias + wrote: + Uses a subset of hermite splines: either cardinal splines (tightness != 0.5) or catmull-rom-splines (tightness == 0.5) + but this is just my understanding of this stuff, I'm not a mathematician, so this might be wrong ;) */ + virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed = 1.0f, f32 tightness = 0.5f) = 0; + + //! Creates a simple ITriangleSelector, based on a mesh. + /** Triangle selectors + can be used for doing collision detection. Don't use this selector + for a huge amount of triangles like in Quake3 maps. + Instead, use for example ISceneManager::createOctTreeTriangleSelector(). + Please note that the created triangle selector is not automaticly attached + to the scene node. You will have to call ISceneNode::setTriangleSelector() + for this. To create and attach a triangle selector is done like this: + \code + ITriangleSelector* s = sceneManager->createTriangleSelector(yourMesh, + yourSceneNode); + yourSceneNode->setTriangleSelector(s); + s->drop(); + \endcode + \param mesh: Mesh of which the triangles are taken. + \param node: Scene node of which visibility and transformation is used. + \return Returns the selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) = 0; + + //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. + /** Triangle selectors + can be used for doing collision detection. Every time when triangles are + queried, the triangle selector gets the bounding box of the scene node, + an creates new triangles. In this way, it works good with animated scene nodes. + \param node: Scene node of which the bounding box, visibility and transformation is used. + \return Returns the selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(ISceneNode* node) = 0; + + //! Creates a Triangle Selector, optimized by an octtree. + /** Triangle selectors + can be used for doing collision detection. This triangle selector is + optimized for huge amounts of triangle, it organizes them in an octtree. + Please note that the created triangle selector is not automaticly attached + to the scene node. You will have to call ISceneNode::setTriangleSelector() + for this. To create and attach a triangle selector is done like this: + \code + ITriangleSelector* s = sceneManager->createOctTreeTriangleSelector(yourMesh, + yourSceneNode); + yourSceneNode->setTriangleSelector(s); + s->drop(); + \endcode + For more informations and examples on this, take a look at the collision + tutorial in the SDK. + \param mesh: Mesh of which the triangles are taken. + \param node: Scene node of which visibility and transformation is used. + \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node. + If a node gets less polys the this value, it will not be splitted into + smaller nodes. + \return Returns the selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode=32) = 0; + + //! Creates a meta triangle selector. + /** A meta triangle selector is nothing more than a + collection of one or more triangle selectors providing together + the interface of one triangle selector. In this way, + collision tests can be done with different triangle soups in one pass. + \return Returns the selector, or null if not successful. + If you no longer need the selector, you should call ITriangleSelector::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IMetaTriangleSelector* createMetaTriangleSelector() = 0; + + //! Creates a triangle selector which can select triangles from a terrain scene node. + /** \param node: Pointer to the created terrain scene node + \param LOD: Level of detail, 0 for highest detail. */ + virtual ITriangleSelector* createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD=0) = 0; + + //! Adds an external mesh loader for extending the engine with new file formats. + /** If you want the engine to be extended with + file formats it currently is not able to load (e.g. .cob), just implement + the IMeshLoader interface in your loading class and add it with this method. + Using this method it is also possible to override built-in mesh loaders with + newer or updated versions without the need of recompiling the engine. + \param externalLoader: Implementation of a new mesh loader. */ + virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0; + + //! Returns a pointer to the scene collision manager. + virtual ISceneCollisionManager* getSceneCollisionManager() = 0; + + //! Returns a pointer to the mesh manipulator. + virtual IMeshManipulator* getMeshManipulator() = 0; + + //! Adds a scene node to the deletion queue. + /** The scene node is immediatly + deleted when it's secure. Which means when the scene node does not + execute animators and things like that. This method is for example + used for deleting scene nodes by their scene node animators. In + most other cases, a ISceneNode::remove() call is enough, using this + deletion queue is not necessary. + See ISceneManager::createDeleteAnimator() for details. + \param node: Node to detete. */ + virtual void addToDeletionQueue(ISceneNode* node) = 0; + + //! Posts an input event to the environment. + /** Usually you do not have to + use this method, it is used by the internal engine. */ + virtual bool postEventFromUser(const SEvent& event) = 0; + + //! Clears the whole scene. + /** All scene nodes are removed. */ + virtual void clear() = 0; + + //! Returns interface to the parameters set in this scene. + /** String parameters can be used by plugins and mesh loaders. + For example the CMS and LMTS loader want a parameter named 'CSM_TexturePath' + and 'LMTS_TexturePath' set to the path were attached textures can be found. See + CSM_TEXTURE_PATH, LMTS_TEXTURE_PATH, MY3D_TEXTURE_PATH, + COLLADA_CREATE_SCENE_INSTANCES, DMF_TEXTURE_PATH and DMF_USE_MATERIALS_DIRS*/ + virtual io::IAttributes* getParameters() = 0; + + //! Returns current render pass. + /** All scene nodes are being rendered in a specific order. + First lights, cameras, sky boxes, solid geometry, and then transparent + stuff. During the rendering process, scene nodes may want to know what the scene + manager is rendering currently, because for example they registered for rendering + twice, once for transparent geometry and once for solid. When knowing what rendering + pass currently is active they can render the correct part of their geometry. */ + virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const = 0; + + //! Returns the default scene node factory which can create all built in scene nodes + virtual ISceneNodeFactory* getDefaultSceneNodeFactory() = 0; + + //! Adds a scene node factory to the scene manager. + /** Use this to extend the scene manager with new scene node types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) = 0; + + //! Returns amount of registered scene node factories. + virtual u32 getRegisteredSceneNodeFactoryCount() const = 0; + + //! Returns a scene node factory by index + virtual ISceneNodeFactory* getSceneNodeFactory(u32 index) = 0; + + //! Returns the default scene node animator factory which can create all built-in scene node animators + virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory() = 0; + + //! Adds a scene node animator factory to the scene manager. + /** Use this to extend the scene manager with new scene node animator types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd) = 0; + + //! Returns amount of registered scene node animator factories. + virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const = 0; + + //! Returns a scene node animator factory by index + virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index) = 0; + + //! Returns a typename from a scene node type or null if not found + virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type) = 0; + + //! Adds a scene node to the scene by name + virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent) = 0; + + //! Creates a new scene manager. + /** This can be used to easily draw and/or store two independent scenes at the same time. + The mesh cache will be shared between all existing scene managers, which means if you load + a mesh in the original scene manager using for example getMesh(), the mesh will be available + in all other scene managers too, without loading. + The original/main scene manager will still be there and accessible via IrrlichtDevice::getSceneManager(). + If you need input event in this new scene manager, for example for FPS cameras, you'll need + to forward input to this manually: Just implement an IEventReceiver and call + yourNewSceneManager->postEventFromUser(), and return true so that the original scene manager + doesn't get the event. Otherwise, all input will go automaticly to the main scene manager. + If you no longer need the new scene manager, you should call ISceneManager::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ISceneManager* createNewSceneManager(bool cloneContent=false) = 0; + + //! Saves the current scene into a file. + /** Scene nodes with the option isDebugObject set to true are not being saved. + The scene is usually written to an .irr file, an xml based format. .irr files can + Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org). + To load .irr files again, see ISceneManager::loadScene(). + \param filename: Name of the file. + \param userDataSerializer: If you want to save some user data for every scene node into the + file, implement the ISceneUserDataSerializer interface and provide it as parameter here. + Otherwise, simply specify 0 as this parameter. + \return Returns true if successful. */ + virtual bool saveScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0; + + //! Saves the current scene into a file. + /** Scene nodes with the option isDebugObject set to true are not being saved. + The scene is usually written to an .irr file, an xml based format. .irr files can + Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org). + To load .irr files again, see ISceneManager::loadScene(). + \param file: File where the scene is saved into. + \param userDataSerializer: If you want to save some user data for every scene node into the + file, implement the ISceneUserDataSerializer interface and provide it as parameter here. + Otherwise, simply specify 0 as this parameter. + \return Returns true if successful. */ + virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0; + + //! Loads a scene. Note that the current scene is not cleared before. + /** The scene is usually load from an .irr file, an xml based format. .irr files can + Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or + saved directly by the engine using ISceneManager::saveScene(). + \param filename: Name of the file. + \param userDataSerializer: If you want to load user data possibily saved in that file for + some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here. + Otherwise, simply specify 0 as this parameter. + \return Returns true if successful. */ + virtual bool loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0; + + //! Loads a scene. Note that the current scene is not cleared before. + /** The scene is usually load from an .irr file, an xml based format. .irr files can + Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or + saved directly by the engine using ISceneManager::saveScene(). + \param file: File where the scene is going to be saved into. + \param userDataSerializer: If you want to load user data possibily saved in that file for + some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here. + Otherwise, simply specify 0 as this parameter. + \return Returns true if successful. */ + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0; + + //! Returns a mesh writer implementation if available + /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop() + for details. */ + virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type) = 0; + + //! Sets ambient color of the scene + virtual void setAmbientLight(const video::SColorf &ambientColor) = 0; + + //! Returns ambient color of the scene + virtual const video::SColorf& getAmbientLight() const = 0; + + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneNode.h b/src/dep/include/irrlicht/ISceneNode.h new file mode 100644 index 0000000..6eca6a8 --- /dev/null +++ b/src/dep/include/irrlicht/ISceneNode.h @@ -0,0 +1,710 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_H_INCLUDED__ +#define __I_SCENE_NODE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "ESceneNodeTypes.h" +#include "ECullingTypes.h" +#include "EDebugSceneTypes.h" +#include "ISceneManager.h" +#include "ISceneNodeAnimator.h" +#include "ITriangleSelector.h" +#include "SMaterial.h" +#include "irrString.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "irrList.h" +#include "IAttributes.h" +#include "IAttributeExchangingObject.h" + +namespace irr +{ +namespace scene +{ + //! Scene node interface. + /** A scene node is a node in the hirachical scene graph. Every scene node may have children, + which are other scene nodes. Children move relative the their parents position. If the parent of a node is not + visible, its children won't be visible too. In this way, it is for example easily possible + to attach a light to a moving car, or to place a walking character on a moving platform + on a moving ship. */ + class ISceneNode : public io::IAttributeExchangingObject + { + public: + + //! Constructor + ISceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) + : RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale), + Parent(parent), ID(id), SceneManager(mgr), TriangleSelector(0), + AutomaticCullingState(EAC_BOX), IsVisible(true), + DebugDataVisible(EDS_OFF), IsDebugObject(false) + { + if (Parent) + Parent->addChild(this); + + updateAbsolutePosition(); + } + + + //! Destructor + virtual ~ISceneNode() + { + // delete all children + removeAll(); + + // delete all animators + core::list::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->drop(); + + if (TriangleSelector) + TriangleSelector->drop(); + } + + + //! This method is called just before the rendering process of the whole scene. + /** Nodes may register themselves in the render pipeline during this call, + precalculate the geometry which should be renderered, and prevent their + children from being able to register them selfes if they are clipped by simply + not calling their OnRegisterSceneNode-Method. + If you are implementing your own scene node, you should overwrite this method + with an implementtion code looking like this: + \code + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); + \endcode + */ + virtual void OnRegisterSceneNode() + { + if (IsVisible) + { + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnRegisterSceneNode(); + } + } + + + //! OnAnimate() is called just before rendering the whole scene. + //! Nodes may calculate or store animations here, and may do other useful things, + //! dependent on what they are. Also, OnAnimate() should be called for all + //! child scene nodes here. This method will called once per frame, independent + //! of if the scene node is visible or not. + //! \param timeMs: Current time in milli seconds. + virtual void OnAnimate(u32 timeMs) + { + if (IsVisible) + { + // animate this node with all animators + + core::list::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->animateNode(this, timeMs); + + // update absolute position + updateAbsolutePosition(); + + // perform the post render process on all children + + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnAnimate(timeMs); + } + } + + + //! Renders the node. + virtual void render() = 0; + + + //! Returns the name of the node. + //! \return Returns name as wide character string. + virtual const c8* getName() const + { + return Name.c_str(); + } + + + //! Sets the name of the node. + //! \param name: New name of the scene node. + virtual void setName(const c8* name) + { + Name = name; + } + + + //! Returns the axis aligned, not transformed bounding box of this node. + //! This means that if this node is a animated 3d character, moving in a room, + //! the bounding box will always be around the origin. To get the box in + //! real world coordinates, just transform it with the matrix you receive with + //! getAbsoluteTransformation() or simply use getTransformedBoundingBox(), + //! which does the same. + virtual const core::aabbox3d& getBoundingBox() const = 0; + + + //! Returns the axis aligned, transformed and animated absolute bounding box + //! of this node. + virtual const core::aabbox3d getTransformedBoundingBox() const + { + core::aabbox3d box = getBoundingBox(); + AbsoluteTransformation.transformBox(box); + return box; + } + + + //! returns the absolute transformation of the node. Is recalculated every OnAnimate()-call. + const core::matrix4& getAbsoluteTransformation() const + { + return AbsoluteTransformation; + } + + + //! Returns the relative transformation of the scene node. + //! The relative transformation is stored internally as 3 vectors: + //! translation, rotation and scale. To get the relative transformation + //! matrix, it is calculated from these values. + //! \return Returns the relative transformation matrix. + virtual core::matrix4 getRelativeTransformation() const + { + core::matrix4 mat; + mat.setRotationDegrees(RelativeRotation); + mat.setTranslation(RelativeTranslation); + + if (RelativeScale != core::vector3df(1,1,1)) + { + core::matrix4 smat; + smat.setScale(RelativeScale); + mat *= smat; + } + + return mat; + } + + + //! Returns true if the node is visible. This is only an option, set by the user and has + //! nothing to do with geometry culling + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + + //! Sets if the node should be visible or not. All children of this node won't be visible too. + virtual void setVisible(bool isVisible) + { + IsVisible = isVisible; + } + + + //! Returns the id of the scene node. This id can be used to identify the node. + virtual s32 getID() const + { + return ID; + } + + + //! sets the id of the scene node. This id can be used to identify the node. + virtual void setID(s32 id) + { + ID = id; + } + + + //! Adds a child to this scene node. If the scene node already + //! has got a parent, it is removed from there as child. + virtual void addChild(ISceneNode* child) + { + if (child) + { + child->grab(); + child->remove(); // remove from old parent + Children.push_back(child); + child->Parent = this; + } + } + + + //! Removes a child from this scene node. + //! \return Returns true if the child could be removed, and false if not. + virtual bool removeChild(ISceneNode* child) + { + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + if ((*it) == child) + { + (*it)->Parent = 0; + (*it)->drop(); + Children.erase(it); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Removes all children of this scene node + virtual void removeAll() + { + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + (*it)->Parent = 0; + (*it)->drop(); + } + + Children.clear(); + } + + + //! Removes this scene node from the scene, deleting it. + virtual void remove() + { + if (Parent) + Parent->removeChild(this); + } + + + //! Adds an animator which should animate this node. + virtual void addAnimator(ISceneNodeAnimator* animator) + { + if (animator) + { + Animators.push_back(animator); + animator->grab(); + } + } + + + //! Returns a const reference to the list of all scene node animators. + const core::list& getAnimators() const + { + return Animators; + } + + + //! Removes an animator from this scene node. + virtual void removeAnimator(ISceneNodeAnimator* animator) + { + core::list::Iterator it = Animators.begin(); + for (; it != Animators.end(); ++it) + if ((*it) == animator) + { + (*it)->drop(); + Animators.erase(it); + return; + } + } + + + //! Removes all animators from this scene node. + virtual void removeAnimators() + { + core::list::Iterator it = Animators.begin(); + for (; it != Animators.end(); ++it) + (*it)->drop(); + + Animators.clear(); + } + + + //! Returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + //! \param num: Zero based index. The maximal value is getMaterialCount() - 1. + //! \return Returns the material of that index. + virtual video::SMaterial& getMaterial(u32 num) + { + return *((video::SMaterial*)0); + } + + + //! Returns amount of materials used by this scene node. + //! \return Returns current count of materials used by this scene node. + virtual u32 getMaterialCount() const + { + return 0; + } + + + //! Sets all material flags at once to a new value. Helpful for + //! example, if you want to be the the whole mesh to be lighted by + //! \param flag: Which flag of all materials to be set. + //! \param newvalue: New value of the flag. + void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + for (u32 i=0; i= video::MATERIAL_MAX_TEXTURES) + return; + + for (u32 i=0; i& getChildren() const + { + return Children; + } + + + //! Changes the parent of the scene node. + virtual void setParent(ISceneNode* newParent) + { + grab(); + remove(); + + Parent = newParent; + + if (Parent) + Parent->addChild(this); + + drop(); + } + + + //! Returns the triangle selector attached to this scene node. + //! The Selector can be used by the engine for doing collision + //! detection. You can create a TriangleSelector with + //! ISceneManager::createTriangleSelector() or + //! ISceneManager::createOctTreeTriangleSelector and set it with + //! ISceneNode::setTriangleSelector(). If a scene node got no triangle + //! selector, but collision tests should be done with it, a triangle + //! selector is created using the bounding box of the scene node. + //! \return Returns a pointer to the TriangleSelector or NULL, if there + //! is none. + virtual ITriangleSelector* getTriangleSelector() const + { + return TriangleSelector; + } + + + //! Sets the triangle selector of the scene node. The Selector can be + //! used by the engine for doing collision detection. You can create a + //! TriangleSelector with ISceneManager::createTriangleSelector() or + //! ISceneManager::createOctTreeTriangleSelector(). Some nodes may + //! create their own selector by default, so it would be good to + //! check if there is already a selector in this node by calling + //! ISceneNode::getTriangleSelector(). + //! \param selector: New triangle selector for this scene node. + virtual void setTriangleSelector(ITriangleSelector* selector) + { + if (TriangleSelector) + TriangleSelector->drop(); + + TriangleSelector = selector; + if (TriangleSelector) + TriangleSelector->grab(); + } + + + //! updates the absolute position based on the relative and the parents position + virtual void updateAbsolutePosition() + { + if (Parent ) + { + AbsoluteTransformation = + Parent->getAbsoluteTransformation() * getRelativeTransformation(); + } + else + AbsoluteTransformation = getRelativeTransformation(); + } + + //! Returns the parent of this scene node + scene::ISceneNode* getParent() const + { + return Parent; + } + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const + { + return ESNT_UNKNOWN; + } + + //! Writes attributes of the scene node. + //! Implement this to expose the attributes of your scene node for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const + { + out->addString ("Name", Name.c_str()); + out->addInt ("Id", ID ); + + out->addVector3d("Position", getPosition() ); + out->addVector3d("Rotation", getRotation() ); + out->addVector3d("Scale", getScale() ); + + out->addBool ("Visible", IsVisible ); + out->addEnum ("AutomaticCulling", AutomaticCullingState, AutomaticCullingNames); + out->addInt ("DebugDataVisible", DebugDataVisible ); + out->addBool ("IsDebugObject", IsDebugObject ); + } + + //! Reads attributes of the scene node. + //! Implement this to set the attributes of your scene node for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) + { + Name = in->getAttributeAsString("Name"); + ID = in->getAttributeAsInt("Id"); + + setPosition(in->getAttributeAsVector3d("Position")); + setRotation(in->getAttributeAsVector3d("Rotation")); + setScale(in->getAttributeAsVector3d("Scale")); + + IsVisible = in->getAttributeAsBool("Visible"); + AutomaticCullingState = (scene::E_CULLING_TYPE ) in->getAttributeAsEnumeration("AutomaticCulling", scene::AutomaticCullingNames); + + DebugDataVisible = (scene::E_DEBUG_SCENE_TYPE ) in->getAttributeAsInt("DebugDataVisible"); + IsDebugObject = in->getAttributeAsBool("IsDebugObject"); + + updateAbsolutePosition(); + } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) + { + return 0; // to be implemented by derived classes + } + + protected: + + //! this method can be used by clone() implementations of derived classes + void cloneMembers(ISceneNode* toCopyFrom, ISceneManager* newManager) + { + Name = toCopyFrom->Name; + AbsoluteTransformation = toCopyFrom->AbsoluteTransformation; + RelativeTranslation = toCopyFrom->RelativeTranslation; + RelativeRotation = toCopyFrom->RelativeRotation; + RelativeScale = toCopyFrom->RelativeScale; + ID = toCopyFrom->ID; + setTriangleSelector(toCopyFrom->TriangleSelector); + AutomaticCullingState = toCopyFrom->AutomaticCullingState; + DebugDataVisible = toCopyFrom->DebugDataVisible; + IsVisible = toCopyFrom->IsVisible; + IsDebugObject = toCopyFrom->IsDebugObject; + + if (newManager) + SceneManager = newManager; + else + SceneManager = toCopyFrom->SceneManager; + + // clone children + + core::list::Iterator it = toCopyFrom->Children.begin(); + for (; it != toCopyFrom->Children.end(); ++it) + (*it)->clone(this, newManager); + + // clone animators + + core::list::Iterator ait = toCopyFrom->Animators.begin(); + for (; ait != toCopyFrom->Animators.end(); ++ait) + { + ISceneNodeAnimator* anim = (*ait)->createClone(this, SceneManager); + if (anim) + { + addAnimator(anim); + anim->drop(); + } + } + } + + //! name of the scene node. + core::stringc Name; + + //! absolute transformation of the node. + core::matrix4 AbsoluteTransformation; + + //! relative translation of the scene node. + core::vector3df RelativeTranslation; + + //! relative rotation of the scene node. + core::vector3df RelativeRotation; + + //! relative scale of the scene node. + core::vector3df RelativeScale; + + //! Pointer to the parent + ISceneNode* Parent; + + //! List of all children of this node + core::list Children; + + //! List of all animator nodes + core::list Animators; + + //! id of the node. + s32 ID; + + //! pointer to the scene manager + ISceneManager* SceneManager; + + //! pointer to the triangle selector + ITriangleSelector* TriangleSelector; + + //! automatic culling + E_CULLING_TYPE AutomaticCullingState; + + //! is the node visible? + bool IsVisible; + + //! flag if debug data should be drawn, such as Bounding Boxes. + E_DEBUG_SCENE_TYPE DebugDataVisible; + + //! is debug object? + bool IsDebugObject; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneNodeAnimator.h b/src/dep/include/irrlicht/ISceneNodeAnimator.h new file mode 100644 index 0000000..8b8e6ec --- /dev/null +++ b/src/dep/include/irrlicht/ISceneNodeAnimator.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "vector3d.h" +#include "ESceneNodeAnimatorTypes.h" +#include "IAttributeExchangingObject.h" + +namespace irr +{ +namespace io +{ + class IAttributes; +} // end namespace io +namespace scene +{ + class ISceneNode; + class ISceneManager; + + //! Animates a scene node. Can animate position, rotation, material, and so on. + /** A scene node animator is able to animate a scene node in a very simple way. It may + change its position, rotation, scale and/or material. There are lots of animators + to choose from. You can create scene node animators with the ISceneManager interface. + */ + class ISceneNodeAnimator : public io::IAttributeExchangingObject + { + public: + + //! destructor + virtual ~ISceneNodeAnimator() {} + + //! Animates a scene node. + //! \param node: Node to animate. + //! \param timeMs: Current time in milli seconds. + virtual void animateNode(ISceneNode* node, u32 timeMs) = 0; + + //! Creates a clone of this animator. + /** Please note that you will have to drop (IReferenceCounted::drop()) + the returned pointer after calling this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) + { + return 0; // to be implemented by derived classes. + } + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_UNKNOWN; + } + }; +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneNodeAnimatorCollisionResponse.h b/src/dep/include/irrlicht/ISceneNodeAnimatorCollisionResponse.h new file mode 100644 index 0000000..e295425 --- /dev/null +++ b/src/dep/include/irrlicht/ISceneNodeAnimatorCollisionResponse.h @@ -0,0 +1,93 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + //! Special scene node animator for doing automatic collision detection and response. + /** This scene node animator can be attached to any scene node modifying it in that + way, that it cannot move through walls of the world, is influenced by gravity and + acceleration. This animator is useful for example for first person shooter + games. Attach it for example to a first person shooter camera, and the camera will + behave as the player control in a first person shooter game: The camera stops and + slides at walls, walks up stairs, falls down if there is no floor under it, and so on. + */ + class ISceneNodeAnimatorCollisionResponse : public ISceneNodeAnimator + { + public: + + //! destructor + virtual ~ISceneNodeAnimatorCollisionResponse() {} + + //! Returns if the attached scene node is falling, which means that + //! there is no blocking wall from the scene node in the direction of + //! the gravity. The implementation of this method is very fast, + //! no collision detection is done when invoking it. + //! \return Returns true if the scene node is falling, false if not. + virtual bool isFalling() const = 0; + + //! Sets the radius of the ellipsoid with which collision detection and + //! response is done. If you have got a scene node, and you are unsure about + //! how big the radius should be, you could use the following code to determine + //! it: + //! \code + //! core::aabbox box = yourSceneNode->getBoundingBox(); + //! core::vector3df radius = box.MaxEdge - box.getCenter(); + //! \endcode + //! \param radius: New radius of the ellipsoid. + virtual void setEllipsoidRadius(const core::vector3df& radius) = 0; + + //! Returns the radius of the ellipsoid with which the collision detection and + //! response is done. + //! \return Radius of the ellipsoid. + virtual core::vector3df getEllipsoidRadius() const = 0; + + //! Sets the gravity of the environment. A good example value would be + //! core::vector3df(0,-100.0f,0) for letting gravity affect all object to + //! fall down. For bigger gravity, make increase the length of the vector. + //! You can disable gravity by setting it to core::vector3df(0,0,0); + //! \param gravity: New gravity vector. + virtual void setGravity(const core::vector3df& gravity) = 0; + + //! Returns current vector of gravity. + //! \return Returns the gravity vector. + virtual core::vector3df getGravity() const = 0; + + //! By default, the ellipsoid for collision detection is created around + //! the center of the scene node, which means that the ellipsoid surrounds + //! it completely. If this is not what you want, you may specify a translation + //! for the ellipsoid. + //! \param translation: Translation of the ellipsoid relative + //! to the position of the scene node. + virtual void setEllipsoidTranslation(const core::vector3df &translation) = 0; + + //! Returns the translation of the ellipsoid for collision detection. See + //! ISceneNodeAnimatorCollisionResponse::setEllipsoidTranslation() for + //! more details. + //! \return Returns the tranlation of the ellipsoid relative to the position + //! of the scene node. + virtual core::vector3df getEllipsoidTranslation() const = 0; + + //! Sets a triangle selector holding all triangles of the world with which + //! the scene node may collide. + //! \param newWorld: New triangle selector containing triangles to let the + //! scene node collide with. + virtual void setWorld(ITriangleSelector* newWorld) = 0; + + //! Returns the current triangle selector containing all triangles for + //! collision detection. + virtual ITriangleSelector* getWorld() const = 0; + }; +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneNodeAnimatorFactory.h b/src/dep/include/irrlicht/ISceneNodeAnimatorFactory.h new file mode 100644 index 0000000..7fe086b --- /dev/null +++ b/src/dep/include/irrlicht/ISceneNodeAnimatorFactory.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_FACTORY_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "ESceneNodeAnimatorTypes.h" + +namespace irr +{ +namespace scene +{ + class ISceneNode; + class ISceneNodeAnimator; + + //! Interface making it possible to dynamicly create scene nodes animators + /** To be able to add custom scene node animators to Irrlicht and to make it possible for the + scene manager to save and load those external animators, simply implement this + interface and register it in you scene manager via ISceneManager::registerSceneNodeAnimatorFactory. + Note: When implementing your own scene node factory, don't call ISceneNodeManager::grab() to + increase the reference counter of the scene node manager. This is not necessary because the + scene node manager will grab() the factory anyway, and otherwise cyclic references will + be created and the scene manager and all its nodes won't get deallocated. + */ + class ISceneNodeAnimatorFactory : public virtual IReferenceCounted + { + public: + + virtual ~ISceneNodeAnimatorFactory() {} + + //! creates a scene node animator based on its type id + /** \param type: Type of the scene node animator to add. + \param target: Target scene node of the new animator. + \return Returns pointer to the new scene node animator or null if not successful. You need to + drop this pointer after calling this, see IReferenceCounted::drop() for details. */ + virtual ISceneNodeAnimator* createSceneNodeAnimator(ESCENE_NODE_ANIMATOR_TYPE type, ISceneNode* target) = 0; + + //! creates a scene node animator based on its type name + /** \param typeName: Type of the scene node animator to add. + \param target: Target scene node of the new animator. + \return Returns pointer to the new scene node animator or null if not successful. You need to + drop this pointer after calling this, see IReferenceCounted::drop() for details. */ + virtual ISceneNodeAnimator* createSceneNodeAnimator(const c8* typeName, ISceneNode* target) = 0; + + //! returns amount of scene node animator types this factory is able to create + virtual u32 getCreatableSceneNodeAnimatorTypeCount() const = 0; + + //! returns type of a createable scene node animator type + /** \param idx: Index of scene node animator type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual ESCENE_NODE_ANIMATOR_TYPE getCreateableSceneNodeAnimatorType(u32 idx) const = 0; + + //! returns type name of a createable scene node animator type + /** \param idx: Index of scene node animator type in this factory. Must be a value between 0 and + getCreatableSceneNodeAnimatorTypeCount() */ + virtual const c8* getCreateableSceneNodeAnimatorTypeName(u32 idx) const = 0; + + //! returns type name of a createable scene node animator type + /** \param type: Type of scene node animator. + \return: Returns name of scene node animator type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableSceneNodeAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneNodeFactory.h b/src/dep/include/irrlicht/ISceneNodeFactory.h new file mode 100644 index 0000000..eaaf497 --- /dev/null +++ b/src/dep/include/irrlicht/ISceneNodeFactory.h @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_FACTORY_H_INCLUDED__ +#define __I_SCENE_NODE_FACTORY_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "ESceneNodeTypes.h" + +namespace irr +{ + + +namespace scene +{ + class ISceneNode; + + //! Interface making it possible to dynamicly create scene nodes + /** To be able to add custom scene nodes to Irrlicht and to make it possible for the + scene manager to save and load those external scene nodes, simply implement this + interface and register it in you scene manager via ISceneManager::registerSceneNodeFactory. + Note: When implementing your own scene node factory, don't call ISceneNodeManager::grab() to + increase the reference counter of the scene node manager. This is not necessary because the + scene node manager will grab() the factory anyway, and otherwise cyclic references will + be created and the scene manager and all its nodes won't get deallocated. + */ + class ISceneNodeFactory : public virtual IReferenceCounted + { + public: + + virtual ~ISceneNodeFactory() {} + + //! adds a scene node to the scene graph based on its type id + /** \param type: Type of the scene node to add. + \param parent: Parent scene node of the new node, can be null to add the scene node to the root. + \return Returns pointer to the new scene node or null if not successful. */ + virtual ISceneNode* addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent=0) = 0; + + //! adds a scene node to the scene graph based on its type name + /** \param typeName: Type name of the scene node to add. + \param parent: Parent scene node of the new node, can be null to add the scene node to the root. + \return Returns pointer to the new scene node or null if not successful. */ + virtual ISceneNode* addSceneNode(const c8* typeName, ISceneNode* parent=0) = 0; + + //! returns amount of scene node types this factory is able to create + virtual u32 getCreatableSceneNodeTypeCount() const = 0; + + //! returns type of a createable scene node type + /** \param idx: Index of scene node type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual ESCENE_NODE_TYPE getCreateableSceneNodeType(u32 idx) const = 0; + + //! returns type name of a createable scene node type by index + /** \param idx: Index of scene node type in this factory. Must be a value between 0 and + getCreatableSceneNodeTypeCount() */ + virtual const c8* getCreateableSceneNodeTypeName(u32 idx) const = 0; + + //! returns type name of a createable scene node type + /** \param type: Type of scene node. + \return: Returns name of scene node type if this factory can create the type, otherwise 0. */ + virtual const c8* getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const = 0; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISceneUserDataSerializer.h b/src/dep/include/irrlicht/ISceneUserDataSerializer.h new file mode 100644 index 0000000..468c244 --- /dev/null +++ b/src/dep/include/irrlicht/ISceneUserDataSerializer.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_USER_DATA_SERIALIZER_H_INCLUDED__ +#define __I_SCENE_USER_DATA_SERIALIZER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + class IAttributes; +} // end namespace io +namespace scene +{ + class ISceneNode; + +//! Interface to read and write user data to and from .irr files. +/** This interface is to be imlpemented by the user, to make it possible to read +and write user data when reading or writing .irr files via ISceneManager. +To be used with ISceneManager::loadScene() and ISceneManager::saveScene() */ +class ISceneUserDataSerializer +{ +public: + + virtual ~ISceneUserDataSerializer() {} + + //! Called when the scene manager read a scene node while loading a file. + /** The userData pointer contains a list of attributes with userData which + were attached to the scene node in the read scene file.*/ + virtual void OnReadUserData(ISceneNode* forSceneNode, io::IAttributes* userData) = 0; + + //! Called when the scene manager is writing a scene node to an xml file for example. + /** Implement this method and return a list of attributes containing the user data + you want to be saved together with the scene node. Return 0 if no user data should + be added. Please note that the scene manager will call drop() to the returned pointer + after it no longer needs it, so if you didn't create a new object for the return value + and returning a longer existing IAttributes object, simply call grab() before returning it. */ + virtual io::IAttributes* createUserData(ISceneNode* forSceneNode) = 0; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IShaderConstantSetCallBack.h b/src/dep/include/irrlicht/IShaderConstantSetCallBack.h new file mode 100644 index 0000000..e8c7824 --- /dev/null +++ b/src/dep/include/irrlicht/IShaderConstantSetCallBack.h @@ -0,0 +1,66 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SHADER_CONSTANT_SET_CALLBACT_H_INCLUDED__ +#define __I_SHADER_CONSTANT_SET_CALLBACT_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace video +{ + class IMaterialRendererServices; + +//! Interface making it possible to set constants for gpu programs every frame. +/** Implement this interface in an own class and pass a pointer to it to one of the methods in + IGPUProgrammingServices when creating a shader. The OnSetConstants method will be called + every frame now. */ +class IShaderConstantSetCallBack : public virtual IReferenceCounted +{ +public: + + //! Destructor. + virtual ~IShaderConstantSetCallBack() {} + + //! Called by the engine when the vertex and/or pixel shader constants for an material renderer should be set. + /** + Implement the IShaderConstantSetCallBack in an own class and implement your own + OnSetConstants method using the given IMaterialRendererServices interface. + Pass a pointer to this class to one of the methods in IGPUProgrammingServices + when creating a shader. The OnSetConstants method will now be called every time + before geometry is being drawn using your shader material. A sample implementation + would look like this: + \code + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set clip matrix at register 4 + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4); + // for high level shading languages, this would be another solution: + //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16); + + // set some light color at register 9 + video::SColorf col(0.0f,1.0f,1.0f,0.0f); + services->setVertexShaderConstant(reinterpret_cast(&col), 9, 1); + // for high level shading languages, this would be another solution: + //services->setVertexShaderConstant("myColor", reinterpret_cast(&col), 4); + } + \endcode + \param services: Pointer to an interface providing methods to set the constants for the shader. + \param userData: Userdata int which can be specified when creating the shader. + */ + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) = 0; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IShadowVolumeSceneNode.h b/src/dep/include/irrlicht/IShadowVolumeSceneNode.h new file mode 100644 index 0000000..2143c18 --- /dev/null +++ b/src/dep/include/irrlicht/IShadowVolumeSceneNode.h @@ -0,0 +1,33 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ +#define __I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class IMesh; + + //! Scene node for rendering a shadow volume into a stencil buffer. + class IShadowVolumeSceneNode : public ISceneNode + { + public: + + //! constructor + IShadowVolumeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id) {} + + //! sets the mesh from which the shadow volume should be generated. + virtual void setMeshToRenderFrom(const IMesh* mesh) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ISkinnedMesh.h b/src/dep/include/irrlicht/ISkinnedMesh.h new file mode 100644 index 0000000..2c47165 --- /dev/null +++ b/src/dep/include/irrlicht/ISkinnedMesh.h @@ -0,0 +1,204 @@ +// Copyright (C) 2002-2006 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SKINNED_MESH_H_INCLUDED__ +#define __I_SKINNED_MESH_H_INCLUDED__ + +#include "irrArray.h" +#include "IBoneSceneNode.h" +#include "IAnimatedMesh.h" +#include "SSkinMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + + enum E_INTERPOLATION_MODE + { + // constant interpolation + EIM_CONSTANT = 0, + + // linear interpolation + EIM_LINEAR, + + //! count of all available interpolation modes + EIM_COUNT + }; + + + //! Interface for using some special functions of Skinned meshes + class ISkinnedMesh : public IAnimatedMesh + { + public: + + //! Gets joint count. + //! \return Returns amount of joints in the skeletal animated mesh. + virtual u32 getJointCount() const = 0; + + //! Gets the name of a joint. + //! \param number: Zero based index of joint. The last joint + //! has the number getJointCount()-1; + //! \return Returns name of joint and null if an error happened. + virtual const c8* getJointName(u32 number) const = 0; + + //! Gets a joint number from its name + //! \param name: Name of the joint. + //! \return Returns the number of the joint or -1 if not found. + virtual s32 getJointNumber(const c8* name) const = 0; + + //! uses animation from another mesh + //! the animation is linked (not copied) based on joint names (so make sure they are unique) + //! \return Returns true if all joints in this mesh were matched up (empty names will not be matched, and it's case sensitive) + //! unmatched joints will not be animated + virtual bool useAnimationFrom(const ISkinnedMesh *mesh) = 0; + + //!Update Normals when Animating + //!False= Don't animate, faster + //!True= Update normals + virtual void updateNormalsWhenAnimating(bool on) = 0; + + //!Sets Interpolation Mode + virtual void setInterpolationMode(E_INTERPOLATION_MODE mode) = 0; + + //! Animates this mesh's joints based on frame input + virtual void animateMesh(f32 frame, f32 blend)=0; + + //! Preforms a software skin on this mesh based of joint positions + virtual void skinMesh() = 0; + + virtual void convertMeshToTangents() = 0; + + //! A vertex weight + struct SWeight + { + //! Index of the mesh buffer + u16 buffer_id; //I doubt 32bits is needed + + //! Index of the vertex + u32 vertex_id; //Store global ID here + + //! Weight Strength/Percentage (0-1) + f32 strength; + + private: + //! Internal members used by CSkinnedMesh + friend class CSkinnedMesh; + bool *Moved; + core::vector3df StaticPos; + core::vector3df StaticNormal; + }; + + + //! Animation keyframe which describes a new position, scale or rotation + struct SPositionKey + { + f32 frame; + core::vector3df position; + }; + + struct SScaleKey + { + f32 frame; + core::vector3df scale; + }; + + struct SRotationKey + { + f32 frame; + core::quaternion rotation; + }; + + //! Joints + struct SJoint + { + SJoint() : UseAnimationFrom(0), LocalAnimatedMatrix_Animated(false), GlobalSkinningSpace(false), + positionHint(-1),scaleHint(-1),rotationHint(-1) + { + } + + //! The name of this joint + core::stringc Name; + + //! Local matrix of this joint + core::matrix4 LocalMatrix; + + //! List of child joints + core::array Children; + + //! List of attached meshes + core::array AttachedMeshes; + + //! Animation keys causing translation change + core::array PositionKeys; + + //! Animation keys causing scale change + core::array ScaleKeys; + + //! Animation keys causing rotation change + core::array RotationKeys; + + //! Skin weights + core::array Weights; + + //! Unnecessary for loaders, will be overwritten on finalize + core::matrix4 GlobalMatrix; + core::matrix4 GlobalAnimatedMatrix; + core::matrix4 LocalAnimatedMatrix; + core::vector3df Animatedposition; + core::vector3df Animatedscale; + core::quaternion Animatedrotation; + + + + core::matrix4 GlobalInversedMatrix; //the x format pre-calculates this + + private: + //! Internal members used by CSkinnedMesh + friend class CSkinnedMesh; + + SJoint *UseAnimationFrom; + bool LocalAnimatedMatrix_Animated; + + bool GlobalSkinningSpace; + + s32 positionHint; + s32 scaleHint; + s32 rotationHint; + }; + + + //Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_ + + //these functions will use the needed arrays, set values, etc to help the loaders + + //! exposed for loaders: to add mesh buffers + virtual core::array &getMeshBuffers() = 0; + + //! exposed for loaders: joints list + virtual core::array &getAllJoints() = 0; + + //! exposed for loaders: joints list + virtual const core::array &getAllJoints() const = 0; + + //! loaders should call this after populating the mesh + virtual void finalize() = 0; + + + virtual SSkinMeshBuffer *createBuffer() = 0; + + virtual SJoint *createJoint(SJoint *parent=0) = 0; + + virtual SPositionKey *createPositionKey(SJoint *joint) = 0; + virtual SScaleKey *createScaleKey(SJoint *joint) = 0; + virtual SRotationKey *createRotationKey(SJoint *joint) = 0; + + virtual SWeight *createWeight(SJoint *joint) = 0; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ITerrainSceneNode.h b/src/dep/include/irrlicht/ITerrainSceneNode.h new file mode 100644 index 0000000..1534761 --- /dev/null +++ b/src/dep/include/irrlicht/ITerrainSceneNode.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the terrain renderer by Soconne and +// the GeoMipMapSceneNode developed by Spintz. They made their code available for Irrlicht +// and allowed it to be distributed under this licence. I only modified some parts. +// A lot of thanks go to them. + +#ifndef __I_TERRAIN_SCENE_NODE_H__ +#define __I_TERRAIN_SCENE_NODE_H__ + +#include "ETerrainElements.h" +#include "ISceneNode.h" +#include "SMeshBufferLightMap.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + class IMesh; + + //! A scene node for displaying terrain using the geo mip map algorithm. + /** The code for the TerrainSceneNode is based on the Terrain renderer by Soconne and + * the GeoMipMapSceneNode developed by Spintz. They made their code available for Irrlicht + * and allowed it to be distributed under this licence. I only modified some parts. + * A lot of thanks go to them. + * + * This scene node is capable of very quickly loading + * terrains and updating the indices at runtime to enable viewing very large terrains. It uses a + * CLOD ( Continuous Level of Detail ) algorithm which updates the indices for each patch based on + * a LOD ( Level of Detail ) which is determined based on a patch's distance from the camera. + * + * The Patch Size of the terrain must always be a size of ( 2^N+1, i.e. 8+1(9), 16+1(17), etc. ). + * The MaxLOD available is directly dependent on the patch size of the terrain. LOD 0 contains all + * of the indices to draw all the triangles at the max detail for a patch. As each LOD goes up by 1 + * the step taken, in generating indices increases by - 2^LOD, so for LOD 1, the step taken is 2, for + * LOD 2, the step taken is 4, LOD 3 - 8, etc. The step can be no larger than the size of the patch, + * so having a LOD of 8, with a patch size of 17, is asking the algoritm to generate indices every + * 2^8 ( 256 ) vertices, which is not possible with a patch size of 17. The maximum LOD for a patch + * size of 17 is 2^4 ( 16 ). So, with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( every + * 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every 8 vertices ) and LOD 4 ( every 16 vertices ). + **/ + class ITerrainSceneNode : public ISceneNode + { + public: + + //! constructor + ITerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f) ) + : ISceneNode (parent, mgr, id, position, rotation, scale) {} + + //! destructor + virtual ~ITerrainSceneNode() {} + + //! \return: Returns the bounding box of the entire terrain. + virtual const core::aabbox3d& getBoundingBox ( ) const = 0; + + //! Returns the bounding box of a patch + virtual const core::aabbox3d& getBoundingBox (s32 patchX, s32 patchZ) const = 0; + + //! Returns the number of indices currently in the meshbuffer for this scene node. + virtual u32 getIndexCount() const = 0; + + //! Returns pointer to the mesh + virtual IMesh* getMesh() = 0; + + //! Gets the meshbuffer data based on a specified level of detail. + /** \param mb: A reference to an SMeshBuffer object + \param LOD: the level of detail you want the indices from. */ + virtual void getMeshBufferForLOD(SMeshBufferLightMap& mb, s32 LOD) const = 0; + + //! Gets the indices for a specified patch at a specified Level of Detail. + /** \param indices: A reference to an array of u32 indices. + \param patchX: Patch x coordinate. + \param patchZ: Patch z coordinate. + \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, + then it will retrieve the triangles at the highest LOD ( 0 ). + \return: Number if indices put into the buffer. */ + virtual s32 getIndicesForPatch(core::array& indices, + s32 patchX, s32 patchZ, s32 LOD = 0 ) = 0; + + //! Populates an array with the CurrentLOD of each patch. + /** \param LODs: A reference to a core::array to hold the values + \return: Returns the number of elements in the array */ + virtual s32 getCurrentLODOfPatches(core::array& LODs) const = 0; + + //! Manually sets the LOD of a patch + /** \param patchX: Patch x coordinate. + \param patchZ: Patch z coordinate. + \param LOD: The level of detail to set the patch to. */ + virtual void setLODOfPatch( s32 patchX, s32 patchZ, s32 LOD ) = 0; + + //! Returns center of terrain. + virtual const core::vector3df& getTerrainCenter() const = 0; + + //! Returns height of a point of the terrain. + virtual f32 getHeight( f32 x, f32 y ) const = 0; + + //! Sets the movement camera threshold. + /** It is used to determine when to recalculate + indices for the scene node. The default value is 10.0f. */ + virtual void setCameraMovementDelta(f32 delta) = 0; + + //! Sets the rotation camera threshold. + /** It is used to determine when to recalculate + indices for the scene node. The default value is 1.0f. */ + virtual void setCameraRotationDelta(f32 delta) = 0; + + //! Sets whether or not the node should dynamically update its associated selector when the geomipmap data changes. + /** \param bVal: Boolean value representing whether or not to update selector dynamically. */ + virtual void setDynamicSelectorUpdate(bool bVal) = 0; + + //! 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 + 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 + work best with your new terrain size. */ + virtual bool overrideLODDistance(s32 LOD, f64 newDistance) = 0; + + //! Scales the base texture, similar to makePlanarTextureMapping. + /** \param scale: The scaling amount. Values above 1.0 increase the number of time the + texture is drawn on the terrain. Values below 0 will decrease the number of times the + texture is drawn on the terrain. Using negative values will flip the texture, as + well as still scaling it. + \param scale2: If set to 0 (default value), this will set the second texture coordinate set + to the same values as in the first set. If this is another value than zero, it will scale + the second texture coordinate set by this value. */ + virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f) = 0; + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __IGEOMIPMAPSCENENODE_H__ diff --git a/src/dep/include/irrlicht/ITextSceneNode.h b/src/dep/include/irrlicht/ITextSceneNode.h new file mode 100644 index 0000000..30c86df --- /dev/null +++ b/src/dep/include/irrlicht/ITextSceneNode.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TEXT_SCENE_NODE_H_INCLUDED__ +#define __I_TEXT_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! A scene node for displaying 2d text at a position in three dimensional space +class ITextSceneNode : public ISceneNode +{ +public: + + //! constructor + ITextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0)) + : ISceneNode(parent, mgr, id, position) {} + + //! sets the text string + virtual void setText(const wchar_t* text) = 0; + + //! sets the color of the text + virtual void setTextColor(video::SColor color) = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/ITexture.h b/src/dep/include/irrlicht/ITexture.h new file mode 100644 index 0000000..ad35a98 --- /dev/null +++ b/src/dep/include/irrlicht/ITexture.h @@ -0,0 +1,180 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TEXTURE_H_INCLUDED__ +#define __I_TEXTURE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IImage.h" +#include "dimension2d.h" +#include "EDriverTypes.h" +#include "irrString.h" +#include "matrix4.h" + +namespace irr +{ +namespace video +{ + + +//! Enumeration flags telling the video driver in which format textures +//! should be created. +enum E_TEXTURE_CREATION_FLAG +{ + //! Forces the driver to create 16 bit textures always, independent of + //! which format the file on disk has. When choosing this you may loose + //! some color detail, but gain much speed and memory. 16 bit textures + //! can be transferred twice as fast as 32 bit textures and only use + //! half of the space in memory. + //! When using this flag, it does not make sense to use the flags + //! ETCF_ALWAYS_32_BIT, ETCF_OPTIMIZED_FOR_QUALITY, + //! or ETCF_OPTIMIZED_FOR_SPEED at the same time. + ETCF_ALWAYS_16_BIT = 0x00000001, + + //! Forces the driver to create 32 bit textures always, independent of + //! which format the file on disk has. Please note that some drivers + //! (like the software device) will ignore this, because they are only + //! able to create and use 16 bit textures. + //! When using this flag, it does not make sense to use the flags + //! ETCF_ALWAYS_16_BIT, ETCF_OPTIMIZED_FOR_QUALITY, + //! or ETCF_OPTIMIZED_FOR_SPEED at the same time. + ETCF_ALWAYS_32_BIT = 0x00000002, + + //! Lets the driver decide in which format the textures are created and + //! tries to make the textures look as good as possible. + //! Usually it simply chooses the format in which the texture was stored on disk. + //! When using this flag, it does not make sense to use the flags + //! ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, + //! or ETCF_OPTIMIZED_FOR_SPEED at the same time. + ETCF_OPTIMIZED_FOR_QUALITY = 0x00000004, + + //! Lets the driver decide in which format the textures are created and + //! tries to create them maximizing render speed. + //! When using this flag, it does not make sense to use the flags + //! ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, or ETCF_OPTIMIZED_FOR_QUALITY, + //! at the same time. + ETCF_OPTIMIZED_FOR_SPEED = 0x00000008, + + //! Automatically creates mip map levels for the textures. + ETCF_CREATE_MIP_MAPS = 0x00000010, + + //! Discard any alpha layer and use non-alpha color format. + ETCF_NO_ALPHA_CHANNEL = 0x00000020, + + //! This flag is never used, it only forces the compiler to + //! compile these enumeration values to 32 bit. + ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff +}; + + +//! Helper function, helps to get the desired texture creation format from the flags. +//! Returns either ETCF_ALWAYS_32_BIT, ETCF_ALWAYS_16_BIT, ETCF_OPTIMIZED_FOR_QUALITY, +//! or ETCF_OPTIMIZED_FOR_SPEED. +inline E_TEXTURE_CREATION_FLAG getTextureFormatFromFlags(u32 flags) +{ + if (flags & ETCF_OPTIMIZED_FOR_SPEED) + return ETCF_OPTIMIZED_FOR_SPEED; + if (flags & ETCF_ALWAYS_16_BIT) + return ETCF_ALWAYS_16_BIT; + if (flags & ETCF_ALWAYS_32_BIT) + return ETCF_ALWAYS_32_BIT; + if (flags & ETCF_OPTIMIZED_FOR_QUALITY) + return ETCF_OPTIMIZED_FOR_QUALITY; + return ETCF_OPTIMIZED_FOR_SPEED; +} + + +//! Interface of a Video Driver dependent Texture. +/** + An ITexture is created by an IVideoDriver by using IVideoDriver::addTexture or + IVideoDriver::getTexture. After that, the texture may only be used by this VideoDriver. + As you can imagine, textures of the DirectX and the OpenGL device will, e.g., not be compatible. + An exception is the Software device and the NULL device, their textures are compatible. + If you try to use a texture created by one device with an other device, the device + will refuse to do that and write a warning or an error message to the output buffer. +*/ +class ITexture : public virtual IReferenceCounted +{ +public: + + //! constructor + ITexture(const c8* name) : Name(name) + { + Name.make_lower(); + } + + //! destructor + virtual ~ITexture() {} + + //! Lock function. + /** Locks the Texture and returns a pointer to access the + pixels. After lock() has been called and all operations on the pixels + are done, you must call unlock(). + \return Returns a pointer to the pixel data. The format of the pixel can + be determinated by using getColorFormat(). NULL is returned, if + the texture cannot be locked. */ + virtual void* lock() = 0; + + //! Unlock function. Must be called after a lock() to the texture. + virtual void unlock() = 0; + + //! Returns original size of the texture. + /** The texture is usually + scaled, if it was created with an unoptimal size. For example if the size + of the texture file it was loaded from was not a power of two. This returns + the size of the texture, it had before it was scaled. Can be useful + when drawing 2d images on the screen, which should have the exact size + of the original texture. Use ITexture::getSize() if you want to know + the real size it has now stored in the system. + \return Returns the original size of the texture. */ + virtual const core::dimension2d& getOriginalSize() const = 0; + + //! Returns dimension (=size) of the texture. + /** \return Returns the size of the texture. */ + virtual const core::dimension2d& getSize() const = 0; + + //! Returns driver type of texture. + /** This is the driver, which created the texture. + This method is used internally by the video devices, to check, if they may + use a texture because textures may be incompatible between different + devices. + \return Returns driver type of texture. */ + virtual E_DRIVER_TYPE getDriverType() const = 0; + + //! Returns the color format of texture. + /** \return Returns the color format of texture. */ + virtual ECOLOR_FORMAT getColorFormat() const = 0; + + //! Returns pitch of texture (in bytes). + /** The pitch is the amount of bytes + used for a row of pixels in a texture. + \return Returns pitch of texture in bytes. */ + virtual u32 getPitch() const = 0; + + //! Returns whether the texture has MipMaps + /** \return Returns true if texture has MipMaps, else false. */ + virtual bool hasMipMaps() const { return false; } + + //! Regenerates the mip map levels of the texture. + /** Useful after locking and modifying the texture */ + virtual void regenerateMipMapLevels() = 0; + + //! Returns whether the texture is a render target + /** \return Returns true if this is a render target, otherwise false. */ + virtual bool isRenderTarget() const { return false; } + + //! Returns name of texture (in most cases this is the filename) + const core::stringc& getName() const { return Name; } + +protected: + + core::stringc Name; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ITimer.h b/src/dep/include/irrlicht/ITimer.h new file mode 100644 index 0000000..329aa04 --- /dev/null +++ b/src/dep/include/irrlicht/ITimer.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TIMER_H_INCLUDED__ +#define __I_TIMER_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ + +//! Interface for getting and manipulating the virtual time +class ITimer : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~ITimer() {} + + //! Returns current real time in milliseconds of the system. + /** This value does not start with 0 when the application starts. + For example in one implementation the value returned could be the + amount of milliseconds which have elapsed since the system was started. */ + virtual u32 getRealTime() const = 0; + + //! Returns current virtual time in milliseconds. + /** This value starts with 0 and can be manipulated using setTime(), stopTimer(), + startTimer(), etc. This value depends on the set speed of the timer if the timer + is stopped, etc. If you need the system time, use getRealTime() */ + virtual u32 getTime() const = 0; + + //! sets current virtual time + virtual void setTime(u32 time) = 0; + + //! Stops the virtual timer. + /** The timer is reference counted, which means everything which calls + stop() will also have to call start(), otherwise the timer may not start/stop + corretly again. */ + virtual void stop() = 0; + + //! Starts the virtual timer. + /** The timer is reference counted, which means everything which calls + stop() will also have to call start(), otherwise the timer may not start/stop + corretly again. */ + virtual void start() = 0; + + //! Sets the speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual void setSpeed(f32 speed = 1.0f) = 0; + + //! Returns current speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual f32 getSpeed() const = 0; + + //! Returns if the virtual timer is currently stopped + virtual bool isStopped() const = 0; + + //! Advances the virtual time + /** Makes the virtual timer update the time value based on the real + time. This is called automatically when calling IrrlichtDevice::run(), + but you can call it manually if you don't use this method. */ + virtual void tick() = 0; +}; + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/ITriangleSelector.h b/src/dep/include/irrlicht/ITriangleSelector.h new file mode 100644 index 0000000..bcc70af --- /dev/null +++ b/src/dep/include/irrlicht/ITriangleSelector.h @@ -0,0 +1,91 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __I_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "triangle3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "line3d.h" + +namespace irr +{ +namespace scene +{ + +//! Interface to return triangles with specific properties. +/** Every ISceneNode may have a triangle selector, available with + ISceneNode::getTriangleScelector() or ISceneManager::createTriangleSelector. + This is used for doing collision detection: For example if you know, that a + collision may have happened in the area between (1,1,1) and (10,10,10), you + can get all triangles of the scene node in this area with the + ITriangleSelector easily and check every triangle if it collided. */ +class ITriangleSelector : public virtual IReferenceCounted +{ +public: + + //! destructor + virtual ~ITriangleSelector() {} + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount() const = 0; + + //! Gets all triangles. + //! \param triangles: Array where the resulting triangles will be + //! written to. + //! \param arraySize: Size of the target array. + //! \param outTriangleCount: Amount of triangles which have been + //! written into the array. + //! \param transform: Pointer to matrix for transforming the triangles + //! before they are returned. Useful for example to scale all triangles + //! down into an ellipsoid space. If this pointer is null, no + //! transformation will be done. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform=0) const = 0; + + //! Gets all triangles which lie within a specific bounding box. + //! Please note that unoptimized triangle selectors also may return + //! triangles which are not in the specific box at all. + //! \param triangles: Array where the resulting triangles will be + //! written to. + //! \param arraySize: Size of the target array. + //! \param outTriangleCount: Amount of triangles which have been + //! written into the array. + //! \param box: Only triangles which are in this axis aligned bounding + //! box will be written into the array. + //! \param transform: Pointer to matrix for transforming the triangles + //! before they are returned. Useful for example to scale all triangles + //! down into an ellipsoid space. If this pointer is null, no + //! transformation will be done. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d& box, + const core::matrix4* transform=0) const = 0; + + //! Gets all triangles which have or may have contact with a 3d line. + //! Please note that unoptimized triangle selectors also may return + //! triangles which are not in contact at all with the 3d line. + //! \param triangles: Array where the resulting triangles will be + //! written to. + //! \param arraySize: Size of the target array. + //! \param outTriangleCount: Amount of triangles which have been + //! written into the array. + //! \param line: Only triangles which may be in contact with this 3d + //! line will be written into the array. + //! \param transform: Pointer to matrix for transforming the triangles + //! before they are returned. Useful for example to scale all triangles + //! down into an ellipsoid space. If this pointer is null, no + //! transformation will be done. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const = 0; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IVideoDriver.h b/src/dep/include/irrlicht/IVideoDriver.h new file mode 100644 index 0000000..7ca22c1 --- /dev/null +++ b/src/dep/include/irrlicht/IVideoDriver.h @@ -0,0 +1,811 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_VIDEO_DRIVER_H_INCLUDED__ +#define __IRR_I_VIDEO_DRIVER_H_INCLUDED__ + +#include "rect.h" +#include "SColor.h" +#include "ITexture.h" +#include "irrArray.h" +#include "matrix4.h" +#include "plane3d.h" +#include "dimension2d.h" +#include "position2d.h" +#include "SMaterial.h" +#include "IMeshBuffer.h" +#include "triangle3d.h" +#include "EDriverTypes.h" +#include "EDriverFeatures.h" + +namespace irr +{ +namespace io +{ + class IAttributes; + class IReadFile; +} // end namespace io +namespace scene +{ + class IMeshBuffer; +} // end namespace scene + +namespace video +{ + struct S3DVertex; + struct S3DVertex2TCoords; + struct S3DVertexTangents; + struct SLight; + struct SExposedVideoData; + class IImageLoader; + class IImageWriter; + class IMaterialRenderer; + class IGPUProgrammingServices; + + //! enumeration for geometry transformation states + enum E_TRANSFORMATION_STATE + { + //! View transformation + ETS_VIEW = 0, + //! World transformation + ETS_WORLD, + //! Projection transformation + ETS_PROJECTION, + //! Texture transformation + ETS_TEXTURE_0, + //! Texture transformation + ETS_TEXTURE_1, + //! Texture transformation + ETS_TEXTURE_2, + //! Texture transformation + ETS_TEXTURE_3, + //! Not used + ETS_COUNT + }; + + + //! Interface to driver which is able to perform 2d and 3d gfx functions. + /** The IVideoDriver interface is one of the most important interfaces of + the Irrlicht Engine: All rendering and texture manipulating is done with + this interface. You are able to use the Irrlicht Engine by only invoking methods + of this interface if you would like to, although the irr::scene::ISceneManager interface + provides a lot of powerful classes and methods to make the programmers life + easier. + */ + class IVideoDriver : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IVideoDriver() {} + + //! Applications must call this method before performing any rendering. + /** \param backBuffer: Specifies if the back buffer should be cleared, which + means that the screen is filled with the color specified. + If this parameter is false, the back buffer will not be cleared and the color + parameter is ignored. + \param zBuffer: Specifies if the depth or z buffer should be cleared. It is + not nesesarry to do so if only 2d drawing is used. + \param color: The color used for back buffer clearing + \return Returns false if failed. Begin Scene can clear the back- and the z-buffer. */ + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color) = 0; + + //! Presents the rendered image on the screen. + /** Applications must call this method after performing any rendering. + \param windowId: Handle of another window, if you want the bitmap to be displayed + on another window. If this is null, everything will be displayed in the default window. + Note: This does not work in fullscreen mode and is not implemented for all devices (only for + D3D8, D3D9, Software1 and Software2, and only for Windows). + \param sourceRect: Pointer to a rectangle defining the source rectangle of the area + to be presented. Set to null to present everything. Note: not implemented in all devices. + \return Returns false if failed and true if succeeded. */ + virtual bool endScene( s32 windowId = 0, core::rect* sourceRect=0 ) = 0; + + //! Queries the features of the driver. + /** Returns true if a feature is available + \param feature: A feature to query. + \return Returns true if the feature is available, false if not. */ + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const = 0; + + //! Sets the view, world or projection transformation. + /* \param state: Transformation type to be set. Can be view, world or projection. + \param mat: Matrix describing the transformation. */ + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) = 0; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const = 0; + + //! Sets a material. + /** All 3d drawing functions will draw geometry using this material. + \param material: Material to be used from now on. */ + virtual void setMaterial(const SMaterial& material) = 0; + + //! Returns a pointer to a texture. + /** Loads the texture from disk if it is not + already loaded and generates mipmap levels if desired. + Texture loading can be influenced using the setTextureCreationFlag() method. + The texture can be in BMP, JPG, TGA, PCX, PNG, and PSD format. + \param filename: Filename of the texture to be loaded. + \return Returns a pointer to the texture or 0 if the texture + could not be loaded. + This pointer should not be dropped. See IReferenceCounted::drop() for more information.*/ + virtual ITexture* getTexture(const c8* filename) = 0; + + //! Returns a pointer to a texture. + /** Loads the texture from disk if it is not + already loaded and generates mipmap levels if desired. + Texture loading can be influenced using the setTextureCreationFlag() method. + The texture can be in BMP, JPG, TGA, PCX, PNG, and PSD format. + \param file: Pointer to an already opened file. + \return Returns a pointer to the texture or 0 if the texture + could not be loaded. + This pointer should not be dropped. See IReferenceCounted::drop() for more information.*/ + virtual ITexture* getTexture(io::IReadFile* file) = 0; + + //! Returns a texture by index + /** \param index: Index of the texture, must be smaller than getTextureCount() + Please note that this index might change when adding or removing textures + */ + virtual ITexture* getTextureByIndex(u32 index) = 0; + + //! Returns amount of textures currently loaded + virtual u32 getTextureCount() const = 0; + + //! Renames a texture + virtual void renameTexture(ITexture* texture, const c8* newName) = 0; + + //! Creates an empty Texture of specified size. + /** \param size: Size of the texture. + \param name: A name for the texture. Later calls to getTexture() with this name + will return this texture + \param format: Desired color format of the texture. Please note that + the driver may choose to create the texture in another color format. + \return Returns a pointer to the newly created texture. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ITexture* addTexture(const core::dimension2d& size, + const c8* name, ECOLOR_FORMAT format = ECF_A8R8G8B8) = 0; + + //! Creates a texture from a loaded IImage. + /** \param name: A name for the texture. Later calls of getTexture() with this name + will return this texture + \param image: Image the texture is created from. + \return Returns a pointer to the newly created Texture. + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual ITexture* addTexture(const c8* name, IImage* image) = 0; + + //! Creates a render target texture. + /** \param size: Size of the texture, in pixels. Width and height should + be a power of two (for example 64, 128, 256, 512, ...) and it should not + be bigger than the backbuffer, because it shares the zbuffer with the + screen buffer. + \return Returns a pointer to the created texture or 0 if the texture could not + be created. If you no longer need the image, you should call ITexture::drop(). + See IReferenceCounted::drop() for more information. */ + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name = 0) = 0; + + //! Removes a texture from the texture cache and deletes it, freeing lot of memory. + /** Please note that after calling this, the pointer to the ITexture + may not be longer valid, if it was not grabbed before by other parts of + the engine for storing it longer. So it would be a good idea to set all + materials which are using this texture to 0 or another texture first. + \param texture: Texture to delete from the engine cache. */ + virtual void removeTexture(ITexture* texture) = 0; + + //! Removes all textures from the texture cache and deletes them, freeing lot of memory. + /** Please note that after calling this, the pointer to all ITextures + may not be longer valid, if they were not grabbed before by other parts of + the engine for storing them longer. So it would be a good idea to set all + materials which are using textures to 0 first. */ + virtual void removeAllTextures() = 0; + + //! Creates a 1bit alpha channel of the texture based of an color key. + /** This makes the texture transparent at the regions where this color + key can be found when using for example draw2DImage with useAlphachannel + = true. + \param texture: Texture whose alpha channel is modified. + \param color: Color key color. Every pixel with this color will become transparent + as described above. Please note that the colors of a texture may be + converted when loading it, so the color values may not be exactly the same + in the engine and for example in picture edit programs. To avoid this + problem, you could use the makeColorKeyTexture method, which takes the position + of a pixel instead a color value. */ + virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color) const = 0; + + //! Creates a 1bit alpha channel of the texture based of an color key position. + /** This makes the texture transparent at the regions where this color + key can be found when using for example draw2DImage with useAlphachannel=true. + \param texture: Texture whose alpha channel is modified. + \param colorKeyPixelPos: Position of a pixel with the color key color. + Every pixel with this color will become transparent as described above. */ + virtual void makeColorKeyTexture(video::ITexture* texture, + core::position2d colorKeyPixelPos) const = 0; + + //! Creates a normal map from a height map texture. + /** If the target texture + has 32 bit, the height value is stored in the alpha component of the texture as + addition. This value is used by the video::EMT_PARALLAX_MAP_SOLID + material and similar materials. + \param texture: Texture whose alpha channel is modified. + \param amplitude: Constant value by which the height information is multiplied.*/ + virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const = 0; + + //! Sets a new render target. + /** This will only work if the driver + supports the EVDF_RENDER_TO_TARGET feature, which can be + queried with queryFeature(). Usually, rendering to textures is done in this + way: + \code + // create render target + ITexture* target = driver->createRenderTargetTexture(core::dimension2d(128,128)); + + // ... + + driver->setRenderTarget(target); // set render target + // .. draw stuff here + driver->setRenderTarget(0); // set previous render target + Please note that you cannot render 3D or 2D geometry with a render target as texture + on it when you are rendering the scene into this render target at the same time. It is + usually only possible to render into a texture between the IVideoDriver::beginScene() and endScene() + method calls. And please also note that the scene will be rendered upside down into the texture + in some devices (e.g. OpenGL vs. D3D). A simple workaround for this is to flip the + texture coordinates of the geometry where the render target texture is displayed on. + \endcode + \param texture: New render target. Must be a texture created with + IVideoDriver::createRenderTargetTexture(). If set to 0, it sets the previous render + target which was set before the last setRenderTarget() call. + \param clearBackBuffer: Clears the backbuffer of the render target with the color parameter + \param clearZBuffer: Clears the zBuffer of the rendertarget. Note that, because the frame + buffer shares the zbuffer with the rendertarget, its zbuffer will be partially cleared + too with this. + \param color: The background color for the render target. + \return Returns true if sucessful and false if not. */ + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)) = 0; + + //! Sets a new viewport. + /** Every rendering operation is done into this new area. + \param area: Rectangle defining the new area of rendering operations. */ + virtual void setViewPort(const core::rect& area) = 0; + + //! Gets the area of the current viewport. + /** \return Returns rectangle of the current viewport. */ + virtual const core::rect& getViewPort() const = 0; + + //! draws a vertex primitive list + /** Note that there may be at maximum 65536 vertices, because the + index list is an array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. + \param vType: Vertex type, e.g. EVT_STANDARD for S3DVertex. + \param pType: Primitive type, e.g. EPT_TRIANGLE_FAN for a triangle fan. */ + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 triangleCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) = 0; + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because the + index list is a array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. Usually amount of indices / 3. */ + virtual void drawIndexedTriangleList(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) = 0; + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because the + index list is a array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. Usually amount of indices / 3.*/ + virtual void drawIndexedTriangleList(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) = 0; + + //! Draws an indexed triangle list. + /** Note that there may be at maximum 65536 vertices, because the + index list is a array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. Usually amount of indices / 3. */ + virtual void drawIndexedTriangleList(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) = 0; + + //! Draws an indexed triangle fan. + /** Note that there may be at maximum 65536 vertices, because the + index list is a array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + Please note that some of the implementation code for this method is based on + free code sent in by Mario Gruber, lots of thanks go to him! + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. Usually amount of indices - 2. */ + virtual void drawIndexedTriangleFan(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) = 0; + + //! Draws an indexed triangle fan. + /** Note that there may be at maximum 65536 vertices, because the + index list is a array of 16 bit values each with a maximum value + of 65536. If there are more than 65536 vertices in the list, + results of this operation are not defined. + Please note that some of the implementation code for this method is based on + free code sent in by Mario Gruber, lots of thanks go to him! + \param vertices: Pointer to array of vertices. + \param vertexCount: Amount of vertices in the array. + \param indexList: Pointer to array of indices. + \param triangleCount: amount of Triangles. Usually amount of indices - 2. */ + virtual void drawIndexedTriangleFan(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) = 0; + + //! Draws a 3d line. + /** For some implementations, this method simply calls + drawIndexedTriangles for some triangles. + Note that the line is drawn using the current transformation + matrix and material. So if you need to draw the 3D line + independently of the current transformation, use + \code + driver->setMaterial(unlitMaterial); + driver->setTransform(video::ETS_WORLD, core::matrix4()); + \endcode + for some properly set up material before drawing the line. + \param start: Start of the 3d line. + \param end: End of the 3d line. + \param color: Color of the line. */ + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)) = 0; + + //! Draws a 3d triangle. + /** This method calls drawIndexedTriangles for some triangles. + This method works with all drivers because it simply calls + drawIndexedTriangleList but is hence not very fast. + Note that the triangle is drawn using the current + transformation matrix and material. So if you need to draw it + independently of the current transformation, use + \code + driver->setMaterial(unlitMaterial); + driver->setTransform(video::ETS_WORLD, core::matrix4()); + \endcode + for some properly set up material before drawing the triangle. + \param triangle: The triangle to draw. + \param color: Color of the line. */ + virtual void draw3DTriangle(const core::triangle3df& triangle, + SColor color = SColor(255,255,255,255)) = 0; + + //! Draws a 3d axis aligned box. + /** This method simply calls drawIndexedTriangles for some + triangles. This method works with all drivers because it + simply calls drawIndexedTriangleList but is hence not very + fast. + Note that the box is drawn using the current transformation + matrix and material. So if you need to draw it independently of + the current transformation, use + \code + driver->setMaterial(unlitMaterial); + driver->setTransform(video::ETS_WORLD, core::matrix4()); + \endcode + for some properly set up material before drawing the box. + \param box: The axis aligned box to draw + \param color: Color to use while drawing the box. */ + virtual void draw3DBox(const core::aabbox3d& box, + SColor color = SColor(255,255,255,255)) = 0; + + //! Draws a 2d image without any special effects + /** \param texture: Pointer to texture to use. + \param destPos: upper left 2d destination position where the image will be drawn. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d& destPos) = 0; + + //! Draws a 2d image using a color + /** (if color is other than + Color(255,255,255,255)) and the alpha channel of the texture if wanted. + \param texture: Texture to be drawn. + \param destPos: Upper left 2d destination position where the image will be drawn. + \param sourceRect: Source rectangle in the image. + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be NULL. Then the image is not clipped. + \param color: Color with which the image is colored. If the color equals + Color(255,255,255,255), the color is ignored. Note that the alpha component + is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image.*/ + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) = 0; + + //! draws a set of 2d images, using a color and the alpha + /** channel of the texture if desired. The images are drawn + beginning at pos and concatenated in one line. All drawings + are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects + and are chosen by the indices given. + \param texture: Texture to be drawn. + \param pos: Upper left 2d destination position where the image will be drawn. + \param sourceRects: Source rectangles of the image. + \param indices: List of indices which choose the actual rectangle used each time. + \param kerningWidth: Offset to Position on X + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be 0. Then the image is not clipped. + \param color: Color with which the image is colored. + Note that the alpha component is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + s32 kerningWidth=0, + const core::rect* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false) = 0; + + //! Draws a part of the texture into the rectangle. + /** Suggested and first implemented by zola. + \param texture: the texture to draw from + \param destRect: the rectangle to draw into + \param sourceRect: the rectangle denoting a part of the texture + \param clipRect: clips the destination rectangle (may be 0) + \param colors: array of 4 colors denoting the color values of the corners of the destRect + \param useAlphaChannelOfTexture: true if alpha channel will be blended. */ + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + video::SColor* colors=0, bool useAlphaChannelOfTexture=false) = 0; + + //!Draws an 2d rectangle. + /** \param color: Color of the rectangle to draw. The alpha component will not + be ignored and specifies how transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0) = 0; + + //!Draws an 2d rectangle with a gradient. + /** \param colorLeftUp: Color of the left upper corner to draw. + The alpha component will not be ignored and specifies how transparent the rectangle will be. + \param colorRightUp: Color of the right upper corner to draw. + The alpha component will not be ignored and specifies how transparent the rectangle will be. + \param colorLeftDown: Color of the left lower corner to draw. + The alpha component will not be ignored and specifies how transparent the rectangle will be. + \param colorRightDown: Color of the right lower corner to draw. + The alpha component will not be ignored and specifies how transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0) = 0; + + //! Draws a 2d line. + /** \param start: Screen coordinates of the start of the line in pixels. + \param end: Screen coordinates of the start of the line in pixels. + \param color: Color of the line to draw. */ + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)) = 0; + + //! Draws a non filled concyclic regular 2d polyon. + /** This method can be used to draw + circles, but also triangles, tetragons, pentagons, hexagons, heptagons, octagons, + enneagons, decagons, hendecagons, dodecagon, triskaidecagons, etc. I think you'll + got it now. And all this by simply specifying the vertex count. Welcome to the + wonders of geometry. + \param center: Position of center of circle (pixels). + \param radius: Radius of circle in pixels. + \param color: Color of the circle. + \param vertexCount: Amount of vertices of the polygon. Specify 2 to draw a line, + 3 to draw a triangle, 4 for a tetragons and a lot (>10) for nearly a circle. */ + virtual void draw2DPolygon(core::position2d center, + f32 radius, video::SColor color=SColor(100,255,255,255), s32 vertexCount=10) = 0; + + //! 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 + volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + Please note that the code for the opengl version of the method is based on + free code sent in by Philipp Dortmann, lots of thanks go to him! + \param triangles: Pointer to array of 3d vectors, specifing the shadow volume. + \param count: Amount of triangles in the array. + \param zfail: If set to true, zfail method is used, otherwise zpass. */ + virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail=true) = 0; + + //! Fills the stencil shadow with color. + /** After the shadow volume has been drawn + into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + to draw the color of the shadow. + Please note that the code for the opengl version of the method is based on + free code sent in by Philipp Dortmann, lots of thanks go to him! + \param clearStencilBuffer: Set this to false, if you want to draw every shadow + with the same color, and only want to call drawStencilShadow() once after all + shadow volumes have been drawn. Set this to true, if you want to paint every + shadow with its own color. + \param leftUpEdge: Color of the shadow in the upper left corner of screen. + \param rightUpEdge: Color of the shadow in the upper right corner of screen. + \param leftDownEdge: Color of the shadow in the lower left corner of screen. + \param rightDownEdge: Color of the shadow in the lower right corner of screen. */ + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(255,0,0,0), + video::SColor rightUpEdge = video::SColor(255,0,0,0), + video::SColor leftDownEdge = video::SColor(255,0,0,0), + video::SColor rightDownEdge = video::SColor(255,0,0,0)) = 0; + + //! Draws a mesh buffer + /** \param mb: Buffer to draw; */ + virtual void drawMeshBuffer( const scene::IMeshBuffer* mb) = 0; + + //! Sets the fog mode. + /** These are global values attached to each 3d object + rendered, which has the fog flag enabled in its material. + \param color: Color of the fog + \param linearFog: Set this to true for linear fog, otherwise exponential fog is applied. + \param start: Only used in linear fog mode (linearFog=true). Specifies where fog starts. + \param end: Only used in linear fog mode (linearFog=true). Specifies where fog ends. + \param density: Only used in expotential fog mode (linearFog=false). Must be a value between 0 and 1. + \param pixelFog: Set this to false for vertex fog, and true if you want pixel fog. + \param rangeFog: Set this to true to enable range-based vertex fog. The distance + from the viewer is used to compute the fog, not the z-coordinate. This is + better, but slower. This is only available with D3D and vertex fog. */ + virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true, f32 start=50.0f, f32 end=100.0f, + f32 density=0.01f, bool pixelFog=false, bool rangeFog=false) = 0; + + //! Returns the size of the screen or render window. + /** \return Size of screen or render window. */ + virtual const core::dimension2d& getScreenSize() const = 0; + + //! Returns the size of the current render target, or the screen size if the driver + //! doesnt support render to texture + /** \return Size of render target or screen/window */ + virtual const core::dimension2d& getCurrentRenderTargetSize() const = 0; + + + //! Returns current frames per second value. + /** \return Returns amount of frames per second drawn. **/ + virtual s32 getFPS() const = 0; + + //! Returns amount of primitives (mostly triangles) which were drawn in the last frame. + /** Together with getFPS() very useful method for statistics. + \return Amount of primitives drawn in the last frame. */ + virtual u32 getPrimitiveCountDrawn( u32 param = 0 ) const = 0; + + //! Deletes all dynamic lights which were previously added with addDynamicLight(). + virtual void deleteAllDynamicLights() = 0; + + //! Adds a dynamic light. + /** \param light: Data specifying the dynamic light. */ + virtual void addDynamicLight(const SLight& light) = 0; + + //! Returns the maximal amount of dynamic lights the device can handle + /** \return Maximal amount of dynamic lights. */ + virtual u32 getMaximalDynamicLightAmount() const = 0; + + //! Returns current amount of dynamic lights set + /** \return Current amount of dynamic lights set */ + virtual u32 getDynamicLightCount() const = 0; + + //! Returns light data which was previously set by IVideoDriver::addDynamicLight(). + /** \param idx: Zero based index of the light. Must be 0 or greater and smaller + than IVideoDriver()::getDynamicLightCount. + \return Light data. */ + virtual const SLight& getDynamicLight(u32 idx) const = 0; + + //! Gets name of this video driver. + /** \return Returns the name of the video driver. Example: In case of the Direct3D8 + driver, it would return "Direct3D 8.1". */ + virtual const wchar_t* getName() const = 0; + + //! Adds an external image loader to the engine. + /** This is useful if + the Irrlicht Engine should be able to load textures of currently + unsupported file formats (e.g .gif). The IImageLoader only needs + to be implemented for loading this file format. A pointer to + the implementation can be passed to the engine using this method. + \param loader: Pointer to the external loader created. */ + virtual void addExternalImageLoader(IImageLoader* loader) = 0; + + //! Adds an external image writer to the engine. + /** This is useful if + the Irrlicht Engine should be able to write textures of currently + unsupported file formats (e.g .gif). The IImageWriter only needs + to be implemented for writing this file format. A pointer to + the implementation can be passed to the engine using this method. + \param writer: Pointer to the external writer created. */ + virtual void addExternalImageWriter(IImageWriter* writer) = 0; + + //! Returns the maximum amount of primitives + /** (mostly vertices) which + the device is able to render with one drawIndexedTriangleList + call. */ + virtual u32 getMaximalPrimitiveCount() const = 0; + + //! Enables or disables a texture creation flag. + /** This flag defines how + textures should be created. By changing this value, you can influence for example + the speed of rendering a lot. But please note that the video drivers + take this value only as recommendation. It could happen that you + enable the ETCM_ALWAYS_16_BIT mode, but the driver creates 32 bit + textures. + \param flag: Texture creation flag. + \param enabled: Specifies if the given flag should be enabled or disabled.*/ + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) = 0; + + //! Returns if a texture creation flag is enabled or disabled. + /** You can change this value using setTextureCreationMode(). + \param flag: Texture creation flag. + \return Returns the current texture creation mode. */ + virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const = 0; + + //! Creates a software image from a file. + /** No hardware texture will + be created for this image. This method is useful for example if + you want to read a heightmap for a terrain renderer. + \param filename: Name of the file from which the image is created. + \return Returns the created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromFile(const c8* filename) = 0; + + //! Creates a software image from a file. + /** No hardware texture will + be created for this image. This method is useful for example if + you want to read a heightmap for a terrain renderer. + \param file: File from which the image is created. + \return Returns the created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromFile(io::IReadFile* file) = 0; + + //! Writes the provided image to disk file + /** Requires that there is a suitable image writer + registered for writing the image to disk + \param image: Image to write to disk + \param filename: name of the file to write + \param param: control parameter for the backend ( eq. compression level ) + \return Returns true on success */ + virtual bool writeImageToFile(IImage* image, const c8* filename, u32 param = 0) = 0; + + //! Creates a software image from a byte array. + /** No hardware texture will + be created for this image. This method is useful for example if + you want to read a heightmap for a terrain renderer. + \param format: Desired color format of the texture + \param size: Desired size of the image + \param data: A byte array with pixel color information + \param ownForeignMemory: If true, the image will use the data pointer + directly and own it afterwards. + If false the memory will by copied internally. + \param deleteMemory: Whether the memory is deallocated upon destruction + \return Returns the created image. + If you no longer need the image, you should call IImage::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IImage* createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d& size, void *data, + bool ownForeignMemory=false, + bool deleteMemory = true) = 0; + + //! Only used by the internal engine. + /** Used to notify the driver that + the window was resized. Usually, there is no need to call this method. */ + virtual void OnResize(const core::dimension2d& size) = 0; + + //! Adds a new material renderer to the video device. + /** Use this method to extend the VideoDriver with new MaterialTypes. To extend the + engine using this method do the following: + Derive a class from IMaterialRenderer and override the methods you need. For + setting the right renderstates, you can try to get a pointer to the real rendering device + using IVideoDriver::getExposedVideoData(). Add your class with + IVideoDriver::addMaterialRenderer(). To use an object being displayed + with your new material set the MaterialType member of the SMaterial struct to the + value returned by this method. + If you simply want to create a new material using vertex and/or pixel shaders it would + be easier to use the video::IGPUProgrammingServices interface which you can get using + the getGPUProgrammingServices() method. + \param renderer: A pointer to the new renderer. + \param name: Optional name for this registered material renderer entry. + \return Returns the number of the + material type which can be set in SMaterial::MaterialType to use the renderer. + -1 is returned if an error occured. (For example if you tried to add + an material renderer to the software renderer or the null device, which do not accept + material renderers.) */ + virtual s32 addMaterialRenderer(IMaterialRenderer* renderer, const c8* name = 0) = 0; + + //! Returns pointer to material renderer or null if not existing. + /** \param idx: Id of the material renderer. Can be a value of the E_MATERIAL_TYPE enum or a + value which was returned by addMaterialRenderer(). */ + virtual IMaterialRenderer* getMaterialRenderer(u32 idx) = 0; + + //! Returns amount of currently available material renderers. + virtual u32 getMaterialRendererCount() const = 0; + + //! Returns name of the material renderer + /** This string can for example be used to test if a specific renderer already has + been registered/created, or use this string to store data about materials: This + returned name will be also used when serializing Materials. + \param idx: Id of the material renderer. Can be a value of the E_MATERIAL_TYPE enum or a + value which was returned by addMaterialRenderer(). */ + virtual const c8* getMaterialRendererName(u32 idx) const = 0; + + //! Sets the name of a material renderer. + /** Will have no effect on built-in material renderers. + \param idx: Id of the material renderer. Can be a value of the E_MATERIAL_TYPE enum or a + value which was returned by addMaterialRenderer(). + \param name: New name of the material renderer. */ + virtual void setMaterialRendererName(s32 idx, const c8* name) = 0; + + //! Creates material attributes list from a material, usable for serialization and more. + /** Please note that the videodriver will use the material renderer names from + getMaterialRendererName() to write out the material type name, so they should be set before. */ + virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material) = 0; + + //! Fills an SMaterial structure from attributes. + /** Please note that for setting material types of the material, the video driver + will need to query the material renderers for their names, so all non built-in materials must have been created before + calling this method. */ + virtual void fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attributes) = 0; + + //! Returns driver and operating system specific data about the IVideoDriver. + /** This method should only be used if the engine should be extended without having + to modify the source of the engine. */ + virtual const SExposedVideoData& getExposedVideoData() = 0; + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const = 0; + + //! Returns pointer to the IGPUProgrammingServices interface. + /** Returns 0 if the + videodriver does not support this. (For example the Software and the NULL device + will always return 0) */ + virtual IGPUProgrammingServices* getGPUProgrammingServices() = 0; + + //! Clears the ZBuffer. + /** Note that you usually need not to call this method, + This is done automaticly during IVideoDriver::beginScene() or + IVideoDriver::setRenderTarget() if you specify zBuffer=true. + But if you have to render some special things, you can clear the zbuffer + during the rendering process with this method another time. */ + virtual void clearZBuffer() = 0; + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot() = 0; + + //! looks if the image is already loaded + virtual video::ITexture* findTexture(const c8* filename) = 0; + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + //! \return Returns true if the clipping plane is usable. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false) = 0; + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable) = 0; + + //! Sets the driver's ambient light color. + /** This color is set in the scene manager, see ISceneManager.h. + \param color: New color of the ambient light. */ + virtual void setAmbientLight(const SColorf& color) = 0; + + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IVideoModeList.h b/src/dep/include/irrlicht/IVideoModeList.h new file mode 100644 index 0000000..d65a6f6 --- /dev/null +++ b/src/dep/include/irrlicht/IVideoModeList.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_I_VIDEO_MODE_LIST_H_INCLUDED__ +#define __IRR_I_VIDEO_MODE_LIST_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" + +namespace irr +{ +namespace video +{ + + //! A list of all available video modes. + /** You can get a list via IrrlichtDevice::getVideoModeList(). If you are confused + now, because you think you have to create an Irrlicht Device with a video + mode before being able to get the video mode list, let me tell you that + there is no need to start up an Irrlicht Device with EDT_DIRECT3D8, EDT_OPENGL or + EDT_SOFTWARE: For this (and for lots of other reasons) the null device, + EDT_NULL exists.*/ + class IVideoModeList : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IVideoModeList() {} + + //! Gets amount of video modes in the list. + //! \return Returns amount of video modes. + virtual s32 getVideoModeCount() const = 0; + + //! Returns the screen size of a video mode in pixels. + //! \param modeNumber: zero based index of the video mode. + //! \return Returns size of screen in pixels of the specified video mode. + virtual core::dimension2d getVideoModeResolution(s32 modeNumber) const = 0; + + //! Returns the pixel depth of a video mode in bits. + //! \param modeNumber: zero based index of the video mode. + //! \return Returns the size of each pixel of the specified video mode in bits. + virtual s32 getVideoModeDepth(s32 modeNumber) const = 0; + + //! Returns current desktop screen resolution. + //! \return Returns size of screen in pixels of the current desktop video mode. + virtual core::dimension2d getDesktopResolution() const = 0; + + //! Returns the pixel depth of a video mode in bits. + //! \return Returns the size of each pixel of the current desktop video mode in bits. + virtual s32 getDesktopDepth() const = 0; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/IWriteFile.h b/src/dep/include/irrlicht/IWriteFile.h new file mode 100644 index 0000000..49fe565 --- /dev/null +++ b/src/dep/include/irrlicht/IWriteFile.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_WRITE_FILE_H_INCLUDED__ +#define __I_WRITE_FILE_H_INCLUDED__ + +#include "IReferenceCounted.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing write acess to a file. + class IWriteFile : public virtual IReferenceCounted + { + public: + + virtual ~IWriteFile() {} + + //! Writes an amount of bytes to the file. + //! \param buffer: Pointer to buffer of bytes to write. + //! \param sizeToWrite: Amount of bytes to write to the file. + //! \return Returns how much bytes were written. + virtual s32 write(const void* buffer, u32 sizeToWrite) = 0; + + //! Changes position in file, returns true if successful. + //! \param finalPos: Destination position in the file. + //! \param relativeMovement: If set to true, the position in the file is + //! changed relative to current position. Otherwise the position is changed + //! from begin of file. + //! \return Returns true if successful, otherwise false. + virtual bool seek(long finalPos, bool relativeMovement = false) = 0; + + //! Returns the current position in the file. + //! \return Returns the current position in the file in bytes. + virtual long getPos() const = 0; + + //! Returns name of file. + //! \return Returns the file name as zero terminated character string. + virtual const c8* getFileName() const = 0; + }; + + //! Internal function, please do not use. + IWriteFile* createWriteFile(const c8* fileName, bool append); + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IXMLReader.h b/src/dep/include/irrlicht/IXMLReader.h new file mode 100644 index 0000000..ca6ee2a --- /dev/null +++ b/src/dep/include/irrlicht/IXMLReader.h @@ -0,0 +1,31 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_XML_READER_H_INCLUDED__ +#define __I_XML_READER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrXML.h" + +namespace irr +{ +namespace io +{ + //! A xml reader for wide characters, derived from IReferenceCounted. + //! This XML Parser can read any type of text files from any source where irrlicht + //! can read. Just call IFileSystem::createXMLReader(). + //! For more informations on how to use the parser, see IIrrXMLReader + typedef IIrrXMLReader IXMLReader; + + //! A xml reader for ASCII or UTF-8 characters, derived from IReferenceCounted. + //! This XML Parser can read any type of text files from any source where irrlicht + //! can read. Just call IFileSystem::createXMLReaderUTF8(). + //! For more informations on how to use the parser, see IIrrXMLReader + typedef IIrrXMLReader IXMLReaderUTF8; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IXMLWriter.h b/src/dep/include/irrlicht/IXMLWriter.h new file mode 100644 index 0000000..79cd639 --- /dev/null +++ b/src/dep/include/irrlicht/IXMLWriter.h @@ -0,0 +1,77 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_XML_WRITER_H_INCLUDED__ +#define __I_XML_WRITER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing methods for making it easier to write XML files. + /** This XML Writer only writes UTF-16 xml files, because these are parsed + faster than all other formats by IXMLReader. + */ + class IXMLWriter : public virtual IReferenceCounted + { + public: + + //! Destructor + virtual ~IXMLWriter() {} + + //! Writes a xml 1.0 header like <?xml version="1.0"?>. This should + //! always be called before writing anything other, because also the + //! text file header for unicode texts is written out with this method. + virtual void writeXMLHeader() = 0; + + //! Writes an xml element with maximal 5 attributes like "" or + //! <foo optAttr="value" />. The element can be empty or not. + //! \param name: Name of the element + //! \param empty: Specifies if the element should be empty. Like "". If + //! You set this to false, something like this is written instead: "". + //! \param attr1Name: 1st attributes name + //! \param attr1Value: 1st attributes value + //! \param attr2Name: 2nd attributes name + //! \param attr2Value: 2nd attributes value + //! \param attr3Name: 3rd attributes name + //! \param attr3Value: 3rd attributes value + //! \param attr4Name: 4th attributes name + //! \param attr4Value: 4th attributes value + //! \param attr5Name: 5th attributes name + //! \param attr5Value: 5th attributes value + virtual void writeElement(const wchar_t* name, bool empty=false, + const wchar_t* attr1Name = 0, const wchar_t* attr1Value = 0, + const wchar_t* attr2Name = 0, const wchar_t* attr2Value = 0, + const wchar_t* attr3Name = 0, const wchar_t* attr3Value = 0, + const wchar_t* attr4Name = 0, const wchar_t* attr4Value = 0, + const wchar_t* attr5Name = 0, const wchar_t* attr5Value = 0) = 0; + + //! Writes an xml element with any number of attributes + virtual void writeElement(const wchar_t* name, bool empty, + core::array &names, core::array &values) = 0; + + //! Writes a comment into the xml file + virtual void writeComment(const wchar_t* comment) = 0; + + //! Writes the closing tag for an element. Like "" + virtual void writeClosingTag(const wchar_t* name) = 0; + + //! Writes a text into the file. All occurrences of special characters like + //! & (&), < (<), > (>), and " (") are automaticly replaced. + virtual void writeText(const wchar_t* text) = 0; + + //! Writes a line break + virtual void writeLineBreak() = 0; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/IrrCompileConfig.h b/src/dep/include/irrlicht/IrrCompileConfig.h new file mode 100644 index 0000000..d752acc --- /dev/null +++ b/src/dep/include/irrlicht/IrrCompileConfig.h @@ -0,0 +1,314 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_COMPILE_CONFIG_H_INCLUDED__ +#define __IRR_COMPILE_CONFIG_H_INCLUDED__ + +//! Irrlicht SDK Version +#define IRRLICHT_SDK_VERSION "1.4" + +//! The defines for different operating system are: +//! _IRR_XBOX_PLATFORM_ for XBox +//! _IRR_WINDOWS_ for all irrlicht supported Windows versions +//! _IRR_WINDOWS_API_ for Windows or XBox +//! _IRR_LINUX_PLATFORM_ for Linux (it is defined here if no other os is defined) +//! _IRR_SOLARIS_PLATFORM_ for Solaris +//! _IRR_POSIX_API_ for Posix compatible systems +//! _IRR_USE_SDL_DEVICE_ for platform independent SDL framework +//! _IRR_USE_WINDOWS_DEVICE_ for Windows API based device +//! _IRR_USE_LINUX_DEVICE_ for X11 based device +//! MACOSX for Mac OS X + +//#define _IRR_USE_SDL_DEVICE_ 1 + +//! WIN32 for Windows32 +//! WIN64 for Windows64 +#if defined(WIN32) || defined(WIN64) +#define _IRR_WINDOWS_ +#define _IRR_WINDOWS_API_ +#ifndef _IRR_USE_SDL_DEVICE_ +#define _IRR_USE_WINDOWS_DEVICE_ +#endif +#endif + +#if defined(_XBOX) +#define _IRR_XBOX_PLATFORM_ +#define _IRR_WINDOWS_API_ +#endif + +#if !defined(_IRR_WINDOWS_API_) && !defined(MACOSX) +#if defined(__sparc__) || defined(__sun__) +#define __BIG_ENDIAN__ +#define _IRR_SOLARIS_PLATFORM_ +#else +#define _IRR_LINUX_PLATFORM_ +#endif +#define _IRR_POSIX_API_ + +#ifndef _IRR_USE_SDL_DEVICE_ +#define _IRR_USE_LINUX_DEVICE_ +#endif +#endif + +#include // TODO: Although included elsewhere this is required at least for mingw + +//! Define _IRR_COMPILE_WITH_DIRECT3D_8_ and _IRR_COMPILE_WITH_DIRECT3D_9_ to +//! compile the Irrlicht engine with Direct3D8 and/or DIRECT3D9. +/** If you only want to use the software device or opengl this can be useful. +This switch is mostly disabled because people do not get the g++ compiler compile +directX header files, and directX is only available on windows platforms. If you +are using Dev-Cpp, and want to compile this using a DX dev pack, you can define +_IRR_COMPILE_WITH_DX9_DEV_PACK_. So you simply need to add something like this +to the compiler settings: -DIRR_COMPILE_WITH_DX9_DEV_PACK +and this to the linker settings: -ld3dx9 -ld3dx8 **/ +#if defined(_IRR_WINDOWS_API_) && (!defined(__GNUC__) || defined(IRR_COMPILE_WITH_DX9_DEV_PACK)) + +#define _IRR_COMPILE_WITH_DIRECT3D_8_ +#define _IRR_COMPILE_WITH_DIRECT3D_9_ + +#endif + +//! Define _IRR_COMPILE_WITH_OPENGL_ to compile the Irrlicht engine with OpenGL. +/** If you do not wish the engine to be compiled with OpengGL, comment this +define out. */ +#define _IRR_COMPILE_WITH_OPENGL_ + +//! Define _IRR_COMPILE_WITH_SOFTWARE_ to compile the Irrlicht engine with software driver +/** If you do not need the software driver, or want to use Burning's Video instead, +comment this define out */ +#define _IRR_COMPILE_WITH_SOFTWARE_ + +//! Define _IRR_COMPILE_WITH_BURNINGSVIDEO_ to compile the Irrlicht engine with Burning's video driver +/** If you do not need this software driver, you can comment this define out. */ +#define _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +//! Define _IRR_COMPILE_WITH_X11_ to compile the Irrlicht engine with X11 support. +/** If you do not wish the engine to be compiled with X11, comment this +define out. */ +// Only used in LinuxDevice. +#define _IRR_COMPILE_WITH_X11_ + +//! Define _IRR_OPENGL_USE_EXTPOINTER_ if the OpenGL renderer should use OpenGL extensions via function pointers. +/** On some systems there is no support for the dynamic extension of OpenGL + via function pointers such that this has to be undef'ed. */ +#if !defined(MACOSX) && !defined(_IRR_SOLARIS_PLATFORM_) +#define _IRR_OPENGL_USE_EXTPOINTER_ +#endif + +//! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags +//! to remove the dependencies such that Irrlicht will compile on those systems, too. +#if defined(_IRR_LINUX_PLATFORM_) +#define _IRR_LINUX_X11_VIDMODE_ +//#define _IRR_LINUX_X11_RANDR_ +#endif + +//! Define _IRR_COMPILE_WITH_GUI_ to compile the engine with the built-in GUI +/** Disable this if you are using an external library to draw the GUI. If you disable this then +you will not be able to use anything provided by the GUI Environment, including loading fonts. */ +#define _IRR_COMPILE_WITH_GUI_ + +//! Define _IRR_COMPILE_WITH_ZLIB_ to enable compiling the engine using zlib. +/** This enables the engine to read from compressed .zip archives. If you +disable this feature, the engine can still read archives, but only uncompressed +ones. */ +#define _IRR_COMPILE_WITH_ZLIB_ + +//! Define _IRR_USE_NON_SYSTEM_ZLIB_ to let irrlicht use the zlib which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the zlib installed in the system. + This is only used when _IRR_COMPILE_WITH_ZLIB_ is defined. */ +#define _IRR_USE_NON_SYSTEM_ZLIB_ + + +//! Define _IRR_COMPILE_WITH_JPEGLIB_ to enable compiling the engine using libjpeg. +/** This enables the engine to read jpeg images. If you comment this out, +the engine will no longer read .jpeg images. */ +#define _IRR_COMPILE_WITH_LIBJPEG_ + +//! Define _IRR_USE_NON_SYSTEM_JPEG_LIB_ to let irrlicht use the jpeglib which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the jpeg lib installed in the system. + This is only used when _IRR_COMPILE_WITH_LIBJPEG_ is defined. */ +#define _IRR_USE_NON_SYSTEM_JPEG_LIB_ + + +//! Define _IRR_COMPILE_WITH_LIBPNG_ to enable compiling the engine using libpng. +/** This enables the engine to read png images. If you comment this out, +the engine will no longer read .png images. */ +#define _IRR_COMPILE_WITH_LIBPNG_ + +//! Define _IRR_USE_NON_SYSTEM_LIBPNG_ to let irrlicht use the libpng which comes with irrlicht. +/** If this is commented out, Irrlicht will try to compile using the libpng installed in the system. + This is only used when _IRR_COMPILE_WITH_LIBPNG_ is defined. */ +#define _IRR_USE_NON_SYSTEM_LIB_PNG_ + + +//! Define _IRR_D3D_NO_SHADER_DEBUGGING to disable shader debugging in D3D9 +/** If _IRR_D3D_NO_SHADER_DEBUGGING is undefined in IrrCompileConfig.h, +it is possible to debug all D3D9 shaders in VisualStudio. All shaders +(which have been generated in memory or read from archives for example) will be emitted +into a temporary file at runtime for this purpose. To debug your shaders, choose +Debug->Direct3D->StartWithDirect3DDebugging in Visual Studio, and for every shader a +file named 'irr_dbg_shader_%%.vsh' or 'irr_dbg_shader_%%.psh' will be created. Drag'n'drop +the file you want to debug into visual studio. That's it. You can now set breakpoints and +watch registers, variables etc. This works with ASM, HLSL, and both with pixel and vertex shaders. +Note that the engine will run in D3D REF for this, which is a lot slower than HAL. */ +#define _IRR_D3D_NO_SHADER_DEBUGGING + + +#ifdef _IRR_WINDOWS_API_ + +#ifndef _IRR_STATIC_LIB_ +#ifdef IRRLICHT_EXPORTS +#define IRRLICHT_API __declspec(dllexport) +#else +#define IRRLICHT_API __declspec(dllimport) +#endif // IRRLICHT_EXPORT +#else +#define IRRLICHT_API +#endif // _IRR_STATIC_LIB_ + +// Declare the calling convention. +#if defined(_STDCALL_SUPPORTED) +#define IRRCALLCONV __stdcall +#else +#define IRRCALLCONV __cdecl +#endif // STDCALL_SUPPORTED + +#else +#define IRRLICHT_API +#define IRRCALLCONV +#endif // _IRR_WINDOWS_API_ + +// We need to disable DIRECT3D9 support for Visual Studio 6.0 because +// those $%&$!! disabled support for it since Dec. 2004 and users are complaining +// about linker errors. Comment this out only if you are knowing what you are +// doing. (Which means you have an old DX9 SDK and VisualStudio6). +#ifdef _MSC_VER +#if (_MSC_VER < 1300 && !defined(__GNUC__)) +#undef _IRR_COMPILE_WITH_DIRECT3D_9_ +#pragma message("Compiling Irrlicht with Visual Studio 6.0, support for DX9 is disabled.") +#endif +#endif + +//! Define one of the three setting for Burning's Video Software Rasterizer +/** So if we were marketing guys we could says Irrlicht has 4 Software-Rasterizers. + In a Nutshell: + All Burnings Rasterizers use 32 Bit Backbuffer, 32Bit Texture & 32 Bit Z or WBuffer, + 16 Bit/32 Bit can be adjusted on a global flag. + + BURNINGVIDEO_RENDERER_BEAUTIFUL + 32 Bit + Vertexcolor + Lighting + Per Pixel Perspective Correct + SubPixel/SubTexel Correct + + Bilinear Texturefiltering + WBuffer + + BURNINGVIDEO_RENDERER_FAST + 32 Bit + Per Pixel Perspective Correct + SubPixel/SubTexel Correct + WBuffer + + Bilinear Dithering TextureFiltering + WBuffer + + BURNINGVIDEO_RENDERER_ULTRA_FAST + 16Bit + SubPixel/SubTexel Correct + ZBuffer +*/ + +#define BURNINGVIDEO_RENDERER_BEAUTIFUL +//#define BURNINGVIDEO_RENDERER_FAST +//#define BURNINGVIDEO_RENDERER_ULTRA_FAST + + +//! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based +/** animated meshes. If you compile without this, you will be unable to load +B3D, MS3D or X meshes */ +#define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to use Blitz3D files +#define _IRR_COMPILE_WITH_B3D_LOADER_ +//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to Milkshape files +#define _IRR_COMPILE_WITH_MS3D_LOADER_ +//! Define _IRR_COMPILE_WITH_X_LOADER_ if you want to use Microsoft X files +#define _IRR_COMPILE_WITH_X_LOADER_ +#endif + +//! Define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ if you want to load Irrlicht Engine .irrmesh files +#define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + +//! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files +#define _IRR_COMPILE_WITH_MD2_LOADER_ +//! Define _IRR_COMPILE_WITH_MD3_LOADER_ if you want to load Quake 3 animated files +#define _IRR_COMPILE_WITH_MD3_LOADER_ + +//! Define _IRR_COMPILE_WITH_3DS_LOADER_ if you want to load 3D Studio Max files +#define _IRR_COMPILE_WITH_3DS_LOADER_ +//! Define _IRR_COMPILE_WITH_COLLADA_LOADER_ if you want to load Collada files +#define _IRR_COMPILE_WITH_COLLADA_LOADER_ +//! Define _IRR_COMPILE_WITH_CSM_LOADER_ if you want to load Cartography Shop files +#define _IRR_COMPILE_WITH_CSM_LOADER_ +//! Define _IRR_COMPILE_WITH_BSP_LOADER_ if you want to load Quake 3 BSP files +#define _IRR_COMPILE_WITH_BSP_LOADER_ +//! Define _IRR_COMPILE_WITH_DMF_LOADER_ if you want to load DeleD files +#define _IRR_COMPILE_WITH_DMF_LOADER_ +//! Define _IRR_COMPILE_WITH_LMTS_LOADER_ if you want to load LMTools files +#define _IRR_COMPILE_WITH_LMTS_LOADER_ +//! Define _IRR_COMPILE_WITH_MY3D_LOADER_ if you want to load MY3D files +#define _IRR_COMPILE_WITH_MY3D_LOADER_ +//! Define _IRR_COMPILE_WITH_OBJ_LOADER_ if you want to load Wavefront OBJ files +#define _IRR_COMPILE_WITH_OBJ_LOADER_ +//! Define _IRR_COMPILE_WITH_OCT_LOADER_ if you want to load FSRad OCT files +#define _IRR_COMPILE_WITH_OCT_LOADER_ +//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files +#define _IRR_COMPILE_WITH_OGRE_LOADER_ +//! Define _IRR_COMPILE_WITH_STL_LOADER_ if you want to load .stl files +#define _IRR_COMPILE_WITH_STL_LOADER_ + +//! Define _IRR_COMPILE_WITH_IRR_WRITER_ if you want to write static .irr files +#define _IRR_COMPILE_WITH_IRR_WRITER_ +//! Define _IRR_COMPILE_WITH_COLLADA_WRITER_ if you want to write Collada files +#define _IRR_COMPILE_WITH_COLLADA_WRITER_ +//! Define _IRR_COMPILE_WITH_STL_WRITER_ if you want to write .stl files +#define _IRR_COMPILE_WITH_STL_WRITER_ + +//! Define _IRR_COMPILE_WITH_BMP_LOADER_ if you want to load .bmp files +#define _IRR_COMPILE_WITH_BMP_LOADER_ +//! Define _IRR_COMPILE_WITH_JPG_LOADER_ if you want to load .jpg files +#define _IRR_COMPILE_WITH_JPG_LOADER_ +//! Define _IRR_COMPILE_WITH_PCX_LOADER_ if you want to load .pcx files +#define _IRR_COMPILE_WITH_PCX_LOADER_ +//! Define _IRR_COMPILE_WITH_PNG_LOADER_ if you want to load .png files +#define _IRR_COMPILE_WITH_PNG_LOADER_ +//! Define _IRR_COMPILE_WITH_PPM_LOADER_ if you want to load .ppm/.pgm/.pbm files +#define _IRR_COMPILE_WITH_PPM_LOADER_ +//! Define _IRR_COMPILE_WITH_PSD_LOADER_ if you want to load .psd files +#define _IRR_COMPILE_WITH_PSD_LOADER_ +//! Define _IRR_COMPILE_WITH_TGA_LOADER_ if you want to load .tga files +#define _IRR_COMPILE_WITH_TGA_LOADER_ + +//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files +#define _IRR_COMPILE_WITH_BMP_WRITER_ +//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files +#define _IRR_COMPILE_WITH_JPG_WRITER_ +//! Define _IRR_COMPILE_WITH_PCX_WRITER_ if you want to write .pcx files +#define _IRR_COMPILE_WITH_PCX_WRITER_ +//! Define _IRR_COMPILE_WITH_PNG_WRITER_ if you want to write .png files +#define _IRR_COMPILE_WITH_PNG_WRITER_ +//! Define _IRR_COMPILE_WITH_PPM_WRITER_ if you want to write .ppm files +#define _IRR_COMPILE_WITH_PPM_WRITER_ +//! Define _IRR_COMPILE_WITH_PSD_WRITER_ if you want to write .psd files +#define _IRR_COMPILE_WITH_PSD_WRITER_ +//! Define _IRR_COMPILE_WITH_TGA_WRITER_ if you want to write .tga files +#define _IRR_COMPILE_WITH_TGA_WRITER_ + +//! Set FPU settings +/** Irrlicht should use approximate float and integer fpu techniques +precision will be lower but speed higher. currently X86 only +*/ +#if !defined(MACOSX) && !defined(_IRR_SOLARIS_PLATFORM_) + //#define IRRLICHT_FAST_MATH +#endif + +// Some cleanup +// XBox does not have OpenGL or DirectX9 +#if defined(_IRR_XBOX_PLATFORM_) +#undef _IRR_COMPILE_WITH_OPENGL_ +#undef _IRR_COMPILE_WITH_DIRECT3D_9_ +#endif + +#endif // __IRR_COMPILE_CONFIG_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/IrrlichtDevice.h b/src/dep/include/irrlicht/IrrlichtDevice.h new file mode 100644 index 0000000..f126af9 --- /dev/null +++ b/src/dep/include/irrlicht/IrrlichtDevice.h @@ -0,0 +1,183 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IRRLICHT_DEVICE_H_INCLUDED__ +#define __I_IRRLICHT_DEVICE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "IVideoDriver.h" +#include "EDriverTypes.h" +#include "IEventReceiver.h" +#include "ICursorControl.h" +#include "IVideoModeList.h" +#include "ITimer.h" +#include "IOSOperator.h" + +namespace irr +{ + class ILogger; + class IEventReceiver; + + namespace io { + class IFileSystem; + } // end namespace io + + namespace gui { + class IGUIEnvironment; + } // end namespace gui + + namespace scene { + class ISceneManager; + } // end namespace scene + + //! The Irrlicht device. You can create it with createDevice() or createDeviceEx(). + /** This is the most important class of the Irrlicht Engine. You can access everything + in the engine if you have a pointer to an instance of this class. + */ + class IrrlichtDevice : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IrrlichtDevice() {} + + //! Runs the device. + /** Also increments the virtual timer by calling ITimer::tick();. You can prevent this + by calling ITimer::stop(); before and ITimer::start() after calling IrrlichtDevice::run(). + Returns false if device wants to be deleted. Use it in this way: + \code +while(device->run()) +{ + // draw everything here +} + \endcode + If you want the device to do nothing if the window is inactive (recommended), + use this slightly enhanced code instead: + \code +while(device->run()) + if (device->isWindowActive()) + { + // draw everything here + } + \endcode + Note if you are running Irrlicht inside an external, custom created window: + Calling Device->run() will cause Irrlicht to dispatch windows messages internally. + If you are running Irrlicht in your own, custom window, you + you can also simply use your own message loop + using GetMessage, DispatchMessage and whatever and simply don't use this method. + But note that Irrlicht will not be able to fetch user input then. See + irr::SIrrlichtCreationParameters::WindowId for more informations and example code. + */ + virtual bool run() = 0; + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield() = 0; + + //! Pause execution and let other processes to run for a specified amount of time. + /** It may not wait the full given time, as sleep may be interrupted + \param timeMs: Time to sleep for in milisecs. + \param pauseTimer: If true, pauses the device timer while sleeping + */ + virtual void sleep(u32 timeMs, bool pauseTimer=false) = 0; + + //! Provides access to the video driver for drawing 3d and 2d geometry. + /** \return Returns a pointer the video driver. */ + virtual video::IVideoDriver* getVideoDriver() = 0; + + //! Provides access to the virtual file system. + /** \return Returns a pointer to the file system. */ + virtual io::IFileSystem* getFileSystem() = 0; + + //! Provides access to the 2d user interface environment. + /** \return Returns a pointer to the gui environment. */ + virtual gui::IGUIEnvironment* getGUIEnvironment() = 0; + + //! \return Returns a pointer to the scene manager. + virtual scene::ISceneManager* getSceneManager() = 0; + + //! Provides access to the cursor control. + /** \return Returns a pointer to the mouse cursor control interface. */ + virtual gui::ICursorControl* getCursorControl() = 0; + + //! Provides access to the logger. + /** \return Returns a pointer to the logger. */ + virtual ILogger* getLogger() = 0; + + //! Gets a list with all video modes available. + /** If you are confused + now, because you think you have to create an Irrlicht Device with a video + mode before being able to get the video mode list, let me tell you that + there is no need to start up an Irrlicht Device with EDT_DIRECT3D8, EDT_OPENGL or + EDT_SOFTWARE: For this (and for lots of other reasons) the null device, + EDT_NULL exists. + \return Returns a pointer to a list with all video modes supported + by the gfx adapter. */ + virtual video::IVideoModeList* getVideoModeList() = 0; + + //! Returns the operation system opertator object. + /** It provides methods for + getting operation system specific informations and doing operation system + specific operations. Like for example exchanging data with the clipboard + or reading the operation system version. */ + virtual IOSOperator* getOSOperator() = 0; + + //! Returns pointer to the timer. + /** \return Returns a pointer to the ITimer object. The system time can be retrieved by it as + well as the virtual time, which also can be manipulated. */ + virtual ITimer* getTimer() = 0; + + //! Sets the caption of the window. + /** \param text: New text of the window caption. */ + virtual void setWindowCaption(const wchar_t* text) = 0; + + //! Returns if the window is active. + /** \return Returns true if window is active. If the window is inactive, + nothing need to be drawn. So if you don't want to draw anything when + the window is inactive, create your drawing loop this way: + \code +while(device->run()) + if (device->isWindowActive()) + { + // draw everything here + } + \endcode */ + virtual bool isWindowActive() const = 0; + + //! Notifies the device that it should close itself. + /** IrrlichtDevice::run() will always return false after closeDevice() was called. */ + virtual void closeDevice() = 0; + + //! Returns the version of the engine. + /** The returned string + will look like this: "1.2.3" or this: "1.2". */ + virtual const c8* getVersion() const = 0; + + //! Sets a new event receiver to receive events. + virtual void setEventReceiver(IEventReceiver* receiver) = 0; + + //! Returns poinhter to the current event receiver. Returns 0 if there is none. + virtual IEventReceiver* getEventReceiver() = 0; + + //! Sends a user created event to the engine. + /** Is is usually not necessary to use this. However, if you are using an own + input library for example for doing joystick input, you can use this to post key or mouse input + events to the engine. Internally, this method only delegates the events further to the + scene manager and the GUI environment. */ + virtual void postEventFromUser(const SEvent& event) = 0; + + //! Sets the input receiving scene manager. + /** If set to null, the main scene manager (returned by GetSceneManager()) will receive the input */ + virtual void setInputReceivingSceneManager(scene::ISceneManager* sceneManager) = 0; + + //! Sets if the window should be resizeable in windowed mode. + /** The default is false. This method only works in windowed mode. */ + virtual void setResizeAble(bool resize=false) = 0; + }; + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/Keycodes.h b/src/dep/include/irrlicht/Keycodes.h new file mode 100644 index 0000000..c35124c --- /dev/null +++ b/src/dep/include/irrlicht/Keycodes.h @@ -0,0 +1,163 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_KEY_CODES_H_INCLUDED__ +#define __IRR_KEY_CODES_H_INCLUDED__ + +namespace irr +{ + + enum EKEY_CODE + { + KEY_LBUTTON = 0x01, // Left mouse button + KEY_RBUTTON = 0x02, // Right mouse button + KEY_CANCEL = 0x03, // Control-break processing + KEY_MBUTTON = 0x04, // Middle mouse button (three-button mouse) + KEY_XBUTTON1 = 0x05, // Windows 2000/XP: X1 mouse button + KEY_XBUTTON2 = 0x06, // Windows 2000/XP: X2 mouse button + KEY_BACK = 0x08, // BACKSPACE key + KEY_TAB = 0x09, // TAB key + KEY_CLEAR = 0x0C, // CLEAR key + KEY_RETURN = 0x0D, // ENTER key + KEY_SHIFT = 0x10, // SHIFT key + KEY_CONTROL = 0x11, // CTRL key + KEY_MENU = 0x12, // ALT key + KEY_PAUSE = 0x13, // PAUSE key + KEY_CAPITAL = 0x14, // CAPS LOCK key + KEY_KANA = 0x15, // IME Kana mode + KEY_HANGUEL = 0x15, // IME Hanguel mode (maintained for compatibility use KEY_HANGUL) + KEY_HANGUL = 0x15, // IME Hangul mode + KEY_JUNJA = 0x17, // IME Junja mode + KEY_FINAL = 0x18, // IME final mode + KEY_HANJA = 0x19, // IME Hanja mode + KEY_KANJI = 0x19, // IME Kanji mode + KEY_ESCAPE = 0x1B, // ESC key + KEY_CONVERT = 0x1C, // IME convert + KEY_NONCONVERT = 0x1D, // IME nonconvert + KEY_ACCEPT = 0x1E, // IME accept + KEY_MODECHANGE = 0x1F, // IME mode change request + KEY_SPACE = 0x20, // SPACEBAR + KEY_PRIOR = 0x21, // PAGE UP key + KEY_NEXT = 0x22, // PAGE DOWN key + KEY_END = 0x23, // END key + KEY_HOME = 0x24, // HOME key + KEY_LEFT = 0x25, // LEFT ARROW key + KEY_UP = 0x26, // UP ARROW key + KEY_RIGHT = 0x27, // RIGHT ARROW key + KEY_DOWN = 0x28, // DOWN ARROW key + KEY_SELECT = 0x29, // SELECT key + KEY_PRINT = 0x2A, // PRINT key + KEY_EXECUT = 0x2B, // EXECUTE key + KEY_SNAPSHOT = 0x2C, // PRINT SCREEN key + KEY_INSERT = 0x2D, // INS key + KEY_DELETE = 0x2E, // DEL key + KEY_HELP = 0x2F, // HELP key + KEY_KEY_0 = 0x30, // 0 key + KEY_KEY_1 = 0x31, // 1 key + KEY_KEY_2 = 0x32, // 2 key + KEY_KEY_3 = 0x33, // 3 key + KEY_KEY_4 = 0x34, // 4 key + KEY_KEY_5 = 0x35, // 5 key + KEY_KEY_6 = 0x36, // 6 key + KEY_KEY_7 = 0x37, // 7 key + KEY_KEY_8 = 0x38, // 8 key + KEY_KEY_9 = 0x39, // 9 key + KEY_KEY_A = 0x41, // A key + KEY_KEY_B = 0x42, // B key + KEY_KEY_C = 0x43, // C key + KEY_KEY_D = 0x44, // D key + KEY_KEY_E = 0x45, // E key + KEY_KEY_F = 0x46, // F key + KEY_KEY_G = 0x47, // G key + KEY_KEY_H = 0x48, // H key + KEY_KEY_I = 0x49, // I key + KEY_KEY_J = 0x4A, // J key + KEY_KEY_K = 0x4B, // K key + KEY_KEY_L = 0x4C, // L key + KEY_KEY_M = 0x4D, // M key + KEY_KEY_N = 0x4E, // N key + KEY_KEY_O = 0x4F, // O key + KEY_KEY_P = 0x50, // P key + KEY_KEY_Q = 0x51, // Q key + KEY_KEY_R = 0x52, // R key + KEY_KEY_S = 0x53, // S key + KEY_KEY_T = 0x54, // T key + KEY_KEY_U = 0x55, // U key + KEY_KEY_V = 0x56, // V key + KEY_KEY_W = 0x57, // W key + KEY_KEY_X = 0x58, // X key + KEY_KEY_Y = 0x59, // Y key + KEY_KEY_Z = 0x5A, // Z key + KEY_LWIN = 0x5B, // Left Windows key (Microsoft® Natural® keyboard) + KEY_RWIN = 0x5C, // Right Windows key (Natural keyboard) + KEY_APPS = 0x5D, //Applications key (Natural keyboard) + KEY_SLEEP = 0x5F, // Computer Sleep key + KEY_NUMPAD0 = 0x60, // Numeric keypad 0 key + KEY_NUMPAD1 = 0x61, // Numeric keypad 1 key + KEY_NUMPAD2 = 0x62, // Numeric keypad 2 key + KEY_NUMPAD3 = 0x63, // Numeric keypad 3 key + KEY_NUMPAD4 = 0x64, // Numeric keypad 4 key + KEY_NUMPAD5 = 0x65, // Numeric keypad 5 key + KEY_NUMPAD6 = 0x66, // Numeric keypad 6 key + KEY_NUMPAD7 = 0x67, // Numeric keypad 7 key + KEY_NUMPAD8 = 0x68, // Numeric keypad 8 key + KEY_NUMPAD9 = 0x69, // Numeric keypad 9 key + KEY_MULTIPLY = 0x6A, // Multiply key + KEY_ADD = 0x6B, // Add key + KEY_SEPARATOR = 0x6C, // Separator key + KEY_SUBTRACT = 0x6D, // Subtract key + KEY_DECIMAL = 0x6E, // Decimal key + KEY_DIVIDE = 0x6F, // Divide key + KEY_F1 = 0x70, // F1 key + KEY_F2 = 0x71, // F2 key + KEY_F3 = 0x72, // F3 key + KEY_F4 = 0x73, // F4 key + KEY_F5 = 0x74, // F5 key + KEY_F6 = 0x75, // F6 key + KEY_F7 = 0x76, // F7 key + KEY_F8 = 0x77, // F8 key + KEY_F9 = 0x78, // F9 key + KEY_F10 = 0x79, // F10 key + KEY_F11 = 0x7A, // F11 key + KEY_F12 = 0x7B, // F12 key + KEY_F13 = 0x7C, // F13 key + KEY_F14 = 0x7D, // F14 key + KEY_F15 = 0x7E, // F15 key + KEY_F16 = 0x7F, // F16 key + KEY_F17 = 0x80, // F17 key + KEY_F18 = 0x81, // F18 key + KEY_F19 = 0x82, // F19 key + KEY_F20 = 0x83, // F20 key + KEY_F21 = 0x84, // F21 key + KEY_F22 = 0x85, // F22 key + KEY_F23 = 0x86, // F23 key + KEY_F24 = 0x87, // F24 key + KEY_NUMLOCK = 0x90, // NUM LOCK key + KEY_SCROLL = 0x91, // SCROLL LOCK key + KEY_LSHIFT = 0xA0, // Left SHIFT key + KEY_RSHIFT = 0xA1, // Right SHIFT key + KEY_LCONTROL = 0xA2, // Left CONTROL key + KEY_RCONTROL = 0xA3, // Right CONTROL key + KEY_LMENU = 0xA4, // Left MENU key + KEY_RMENU = 0xA5, // Right MENU key + KEY_PLUS = 0xBB, // Plus Key (+) + KEY_COMMA = 0xBC, // Comma Key (,) + KEY_MINUS = 0xBD, // Minus Key (-) + KEY_PERIOD = 0xBE, // Period Key (.) + KEY_ATTN = 0xF6, // Attn key + KEY_CRSEL = 0xF7, // CrSel key + KEY_EXSEL = 0xF8, // ExSel key + KEY_EREOF = 0xF9, // Erase EOF key + KEY_PLAY = 0xFA, // Play key + KEY_ZOOM = 0xFB, // Zoom key + KEY_PA1 = 0xFD, // PA1 key + KEY_OEM_CLEAR = 0xFE, // Clear key + + KEY_KEY_CODES_COUNT = 0xFF // this is not a key, but the amount of keycodes there are. + }; + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/S3DVertex.h b/src/dep/include/irrlicht/S3DVertex.h new file mode 100644 index 0000000..ad6e7e6 --- /dev/null +++ b/src/dep/include/irrlicht/S3DVertex.h @@ -0,0 +1,219 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_3D_VERTEX_H_INCLUDED__ +#define __S_3D_VERTEX_H_INCLUDED__ + +#include "vector3d.h" +#include "vector2d.h" +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! Enumeration for all vertex types there are. +enum E_VERTEX_TYPE +{ + //! Standard vertex type used by the Irrlicht engine, video::S3DVertex. + EVT_STANDARD = 0, + + //! Vertex with two texture coordinates, video::S3DVertex2TCoords. Usually used + //! for geometry with lightmaps or other special materials. + EVT_2TCOORDS, + + //! Vertex with a tangent and binormal vector, video::S3DVertexTangents. Usually + //! used for tangent space normal mapping. + EVT_TANGENTS +}; + +//! Array holding the built in vertex type names +const char* const sBuiltInVertexTypeNames[] = +{ + "standard", + "2tcoords", + "tangents", + 0 +}; + +//! standard vertex used by the Irrlicht engine. +struct S3DVertex +{ + //! default constructor + S3DVertex() {} + + //! constructor + S3DVertex(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv) + : Pos(x,y,z), Normal(nx,ny,nz), Color(c), TCoords(tu,tv) {} + + //! constructor + S3DVertex(const core::vector3df& pos, const core::vector3df& normal, + SColor color, const core::vector2d& tcoords) + : Pos(pos), Normal(normal), Color(color), TCoords(tcoords) {} + + //! Position + core::vector3df Pos; + + //! Normal vector + core::vector3df Normal; + + //! Color + SColor Color; + + //! Texture coordinates + core::vector2d TCoords; + + bool operator == (const S3DVertex& other) const + { + return (Pos == other.Pos && Normal == other.Normal && + Color == other.Color && TCoords == other.TCoords); + } + + bool operator != (const S3DVertex& other) const + { + return (Pos != other.Pos || Normal != other.Normal || + Color != other.Color || TCoords != other.TCoords); + } + + E_VERTEX_TYPE getType() const + { + return EVT_STANDARD; + } +}; + + +//! Vertex with two texture coordinates. +/** Usually used for geometry with lightmaps +or other special materials. +*/ +struct S3DVertex2TCoords : public S3DVertex +{ + //! default constructor + S3DVertex2TCoords() : S3DVertex() {} + + //! constructor with two different texture coords, but no normal + S3DVertex2TCoords(f32 x, f32 y, f32 z, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2) + : S3DVertex(x,y,z, 0.0f, 0.0f, 0.0f, c, tu,tv), TCoords2(tu2,tv2) {} + + //! constructor with two different texture coords, but no normal + S3DVertex2TCoords(const core::vector3df& pos, SColor color, + const core::vector2d& tcoords, const core::vector2d& tcoords2) + : S3DVertex(pos, core::vector3df(), color, tcoords), TCoords2(tcoords2) {} + + //! constructor with all values + S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal, const SColor& color, + const core::vector2d& tcoords, const core::vector2d& tcoords2) + : S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords2) {} + + //! constructor with all values + S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu2,tv2) {} + + //! constructor with the same texture coords and normal + S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu,tv) {} + + //! constructor with the same texture coords and normal + S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal, + SColor color, const core::vector2d& tcoords) + : S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords) {} + + //! constructor from S3DVertex + S3DVertex2TCoords(S3DVertex& o) : S3DVertex(o) {} + + //! Second set of texture coordinates + core::vector2d TCoords2; + + //! Equality operator + bool operator == (const S3DVertex2TCoords& other) const + { + return (static_cast(*this)==other && + TCoords2 == other.TCoords2); + } + + //! Inequality operator + bool operator != (const S3DVertex2TCoords& other) const + { + return (static_cast(*this)!=other && + TCoords2 != other.TCoords2); + } + + E_VERTEX_TYPE getType() const + { + return EVT_2TCOORDS; + } +}; + + +//! Vertex with a tangent and binormal vector. +/** Usually used for tangent space normal mapping. +*/ +struct S3DVertexTangents : public S3DVertex +{ + //! default constructor + S3DVertexTangents() : S3DVertex() { } + + //! constructor + S3DVertexTangents(f32 x, f32 y, f32 z, f32 nx=0.0f, f32 ny=0.0f, f32 nz=0.0f, SColor c = 0xFFFFFFFF, f32 tu=0.0f, f32 tv=0.0f, f32 tanx=0.0f, f32 tany=0.0f, f32 tanz=0.0f, f32 bx=0.0f, f32 by=0.0f, f32 bz=0.0f) + : S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), Tangent(tanx,tany,tanz), Binormal(bx,by,bz) { } + + //! constructor + S3DVertexTangents(const core::vector3df& pos, SColor c, + const core::vector2df& tcoords) + : S3DVertex(pos, core::vector3df(), c, tcoords) { } + + //! constructor + S3DVertexTangents(const core::vector3df& pos, + const core::vector3df& normal, SColor c, + const core::vector2df& tcoords, + const core::vector3df& tangent=core::vector3df(), + const core::vector3df& binormal=core::vector3df()) + : S3DVertex(pos, normal, c, tcoords), Tangent(tangent), Binormal(binormal) { } + + //! Tangent vector along the x-axis of the texture + core::vector3df Tangent; + + //! Binormal vector (tangent x normal) + core::vector3df Binormal; + + bool operator == (const S3DVertexTangents& other) const + { + return (static_cast(*this)==other && + Tangent == other.Tangent && Binormal == other.Binormal); + } + + bool operator != (const S3DVertexTangents& other) const + { + return (static_cast(*this)!=other && + Tangent != other.Tangent || Binormal != other.Binormal); + } + + E_VERTEX_TYPE getType() const + { + return EVT_TANGENTS; + } +}; + + + +inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType) +{ + switch (vertexType) + { + case video::EVT_2TCOORDS: + return sizeof(video::S3DVertex2TCoords); + case video::EVT_TANGENTS: + return sizeof(video::S3DVertexTangents); + default: + return sizeof(video::S3DVertex); + } +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SAnimatedMesh.h b/src/dep/include/irrlicht/SAnimatedMesh.h new file mode 100644 index 0000000..03c5ef3 --- /dev/null +++ b/src/dep/include/irrlicht/SAnimatedMesh.h @@ -0,0 +1,155 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_ANIMATED_MESH_H_INCLUDED__ +#define __S_ANIMATED_MESH_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "IMesh.h" +#include "aabbox3d.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + + //! Simple implementation of the IAnimatedMesh interface. + struct SAnimatedMesh : public IAnimatedMesh + { + //! constructor + SAnimatedMesh() : IAnimatedMesh(), Type(EAMT_UNKNOWN) + { + #ifdef _DEBUG + setDebugName("SAnimatedMesh"); + #endif + } + + + //! constructor + SAnimatedMesh(scene::IMesh* mesh, scene::E_ANIMATED_MESH_TYPE type) : IAnimatedMesh(), Type(type) + { + #ifdef _DEBUG + setDebugName("SAnimatedMesh"); + #endif + addMesh(mesh); + recalculateBoundingBox(); + } + + + //! destructor + virtual ~SAnimatedMesh() + { + // drop meshes + for (u32 i=0; idrop(); + }; + + + //! Gets the frame count of the animated mesh. + //! \return Returns the amount of frames. If the amount is 1, it is a static, non animated mesh. + virtual u32 getFrameCount() const + { + return Meshes.size(); + } + + + + //! Returns the IMesh interface for a frame. + //! \param frame: Frame number as zero based index. The maximum frame number is + //! getFrameCount() - 1; + //! \param detailLevel: Level of detail. 0 is the lowest, + //! 255 the highest level of detail. Most meshes will ignore the detail level. + //! \param startFrameLoop: start frame + //! \param endFrameLoop: end frame + //! \return Returns the animated mesh based on a detail level. + virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop=-1, s32 endFrameLoop=-1) + { + if (Meshes.empty()) + return 0; + + return Meshes[frame]; + } + + + //! adds a Mesh + void addMesh(IMesh* mesh) + { + if (mesh) + { + mesh->grab(); + Meshes.push_back(mesh); + } + } + + + //! Returns an axis aligned bounding box of the mesh. + //! \return A bounding box of this mesh is returned. + virtual const core::aabbox3d& getBoundingBox() const + { + return Box; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + Box = box; + } + + void recalculateBoundingBox() + { + Box.reset(0,0,0); + + if (Meshes.empty()) + return; + + Box = Meshes[0]->getBoundingBox(); + + for (u32 i=1; igetBoundingBox()); + } + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const + { + return Type; + } + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return 0; + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return 0; + } + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const + { + return 0; + } + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + } + + + core::aabbox3d Box; + core::array Meshes; + E_ANIMATED_MESH_TYPE Type; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SColor.h b/src/dep/include/irrlicht/SColor.h new file mode 100644 index 0000000..1564ac9 --- /dev/null +++ b/src/dep/include/irrlicht/SColor.h @@ -0,0 +1,541 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __COLOR_H_INCLUDED__ +#define __COLOR_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a) + { + return ((a & 0x80) << 8 | + (r & 0xF8) << 7 | + (g & 0xF8) << 2 | + (b & 0xF8) >> 3); + } + + + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGB16(u32 r, u32 g, u32 b) + { + return RGBA16(r,g,b,0xFF); + } + + + //! Creates a 16 bit A1R5G5B5 color, based on 16 bit input values + inline u16 RGB16from16(u16 r, u16 g, u16 b) + { + return (r & 0x1F) << 10 | + (g & 0x1F) << 5 | + (b & 0x1F); + } + + + //! Converts a 32 bit (X8R8G8B8) color to a 16 A1R5G5B5 color + inline u16 X8R8G8B8toA1R5G5B5(u32 color) + { + return ( 0x8000 | + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32 bit (A8R8G8B8) color to a 16 A1R5G5B5 color + inline u16 A8R8G8B8toA1R5G5B5(u32 color) + { + return (( color & 0x80000000) >> 16| + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32 bit (A8R8G8B8) color to a 16 R5G6B5 color + inline u16 A8R8G8B8toR5G6B5(u32 color) + { + return (( color & 0x00F80000) >> 8 | + ( color & 0x0000FC00) >> 5 | + ( color & 0x000000F8) >> 3); + } + + + //! Returns A8R8G8B8 Color from A1R5G5B5 color + //! build a nicer 32 Bit Color by extending dest lower bits with source high bits + inline u32 A1R5G5B5toA8R8G8B8(u16 color) + { + return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) | + (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) | + (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) | + (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2) + ); + } + + + //! Returns A8R8G8B8 Color from R5G6B5 color + inline u32 R5G6B5toA8R8G8B8(u16 color) + { + return 0xFF000000 | + ((color & 0xF800) << 8)| + ((color & 0x07E0) << 5)| + ((color & 0x001F) << 3); + } + + + //! Returns A1R5G5B5 Color from R5G6B5 color + inline u16 R5G6B5toA1R5G5B5(u16 color) + { + return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F)); + } + + + //! Returns R5G6B5 Color from A1R5G5B5 color + inline u16 A1R5G5B5toR5G6B5(u16 color) + { + return (((color & 0x7FE0) << 1) | (color & 0x1F)); + } + + + + //! Returns the alpha component from A1R5G5B5 color + inline u32 getAlpha(u16 color) + { + return ((color >> 15)&0x1); + } + + + //! Returns the red component from A1R5G5B5 color. + //! Shift left by 3 to get 8 bit value. + inline u32 getRed(u16 color) + { + return ((color >> 10)&0x1F); + } + + + //! Returns the green component from A1R5G5B5 color + //! Shift left by 3 to get 8 bit value. + inline u32 getGreen(u16 color) + { + return ((color >> 5)&0x1F); + } + + + //! Returns the blue component from A1R5G5B5 color + //! Shift left by 3 to get 8 bit value. + inline u32 getBlue(u16 color) + { + return (color & 0x1F); + } + + //! Returns the red component from A1R5G5B5 color. + //! Shift left by 3 to get 8 bit value. + inline s32 getRedSigned(u16 color) + { + return ((color >> 10)&0x1F); + } + + + //! Returns the green component from A1R5G5B5 color + //! Shift left by 3 to get 8 bit value. + inline s32 getGreenSigned(u16 color) + { + return ((color >> 5)&0x1F); + } + + + //! Returns the blue component from A1R5G5B5 color + //! Shift left by 3 to get 8 bit value. + inline s32 getBlueSigned(u16 color) + { + return (color & 0x1F); + } + + //! Returns the average from a 16 bit A1R5G5B5 color + inline s32 getAverage(s16 color) + { + return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3; + } + + + + //! Class representing a 32 bit ARGB color. + /** The color values for alpha, red, green, and blue are + stored in a single s32. So all four values may be between 0 and 255. + This class is used by most parts of the Irrlicht Engine + to specify a color. Another way is using the class Colorf, which + stores the color values in 4 floats. + */ + class SColor + { + public: + + //! Constructor of the Color. Does nothing. The color value + //! is not initialized to save time. + inline SColor() {} + + //! Constructs the color from 4 values representing the alpha, red, green and + //! blue components of the color. Must be values between 0 and 255. + inline SColor (u32 a, u32 r, u32 g, u32 b) + : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {} + + //! Constructs the color from a 32 bit value. Could be another color. + inline SColor(u32 clr) + : color(clr) {} + + //! Returns the alpha component of the color. The alpha component + //! defines how transparent a color should be. + //! 0 means not transparent (opaque), 255 means fully transparent. + inline u32 getAlpha() const { return color>>24; } + + //! Returns the red component of the color. + //! \return Returns a value between 0 and 255, specifying how red the color is. + //! 0 means no red, 255 means full red. + inline u32 getRed() const { return (color>>16) & 0xff; } + + //! Returns the green component of the color. + //! \return Returns a value between 0 and 255, specifying how green the color is. + //! 0 means no green, 255 means full green. + inline u32 getGreen() const { return (color>>8) & 0xff; } + + //! Returns the blue component of the color. + //! \return Returns a value between 0 and 255, specifying how blue the color is. + //! 0 means no blue, 255 means full blue. + inline u32 getBlue() const { return color & 0xff; } + + //! Returns the luminance of the color. + inline f32 getLuminance() const + { + return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue(); + } + + //! Returns the average intensity of the color. + inline u32 getAverage() const + { + return ( getRed() + getGreen() + getBlue() ) / 3; + } + + //! Sets the alpha component of the Color. The alpha component + //! defines how transparent a color should be. + //! \param a: Has to be a value between 0 and 255. + //! 0 means not transparent (opaque), 255 means fully transparent. + inline void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); } + + //! Sets the red component of the Color. + //! \param r: Has to be a value between 0 and 255. + //! 0 means no red (=black), 255 means full red. + inline void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); } + + //! Sets the green component of the Color. + //! \param g: Has to be a value between 0 and 255. + //! 0 means no green (=black), 255 means full green. + inline void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); } + + //! Sets the blue component of the Color. + //! \param b: Has to be a value between 0 and 255. + //! 0 means no blue (=black), 255 means full blue. + inline void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); } + + //! Calculates a 16 bit A1R5G5B5 value of this color. + //! \return Returns the 16 bit A1R5G5B5 value of this color. + inline u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }; + + //! Converts color to OpenGL color format, + //! from ARGB to RGBA in 4 byte components for endian aware + //! passing to OpenGL + //! \param dest: address where the 4x8 bit OpenGL color is stored. + inline void toOpenGLColor(u8* dest) const + { + *dest = getRed(); + *++dest = getGreen(); + *++dest = getBlue(); + *++dest = getAlpha(); + }; + + //! Sets all four components of the color at once. + //! Constructs the color from 4 values representing the alpha, red, green and + //! blue components of the color. Must be values between 0 and 255. + //! \param a: Alpha component of the color. + //! The alpha component defines how transparent a color should be. + //! Has to be a value between 0 and 255. + //! 0 means not transparent (opaque), 255 means fully transparent. + //! \param r: Sets the red component of the Color. + //! Has to be a value between 0 and 255. + //! 0 means no red (=black), 255 means full red. + //! \param g: Sets the green component of the Color. + //! Has to be a value between 0 and 255. + //! 0 means no green (=black), 255 means full green. + //! \param b: Sets the blue component of the Color. + //! Has to be a value between 0 and 255. + //! 0 means no blue (=black), 255 means full blue. + inline void set(u32 a, u32 r, u32 g, u32 b) { color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)); } + inline void set(u32 col) { color = col; } + + //! Compares the color to another color. + //! \return Returns true if the colors are the same, and false if not. + inline bool operator==(const SColor& other) const { return other.color == color; } + + //! Compares the color to another color. + //! \return Returns true if the colors are different, and false if they are the same. + inline bool operator!=(const SColor& other) const { return other.color != color; } + + //! Adds two colors + inline SColor operator+(const SColor& other) const + { + s32 a = getAlpha() + other.getAlpha(); + if (a > 255) + a = 255; + + s32 r = getRed() + other.getRed(); + if (r > 255) + r = 255; + + s32 g = getGreen() + other.getGreen(); + if (g > 255) + g = 255; + + s32 b = getBlue() + other.getBlue(); + if (b > 255) + b = 255; + + return SColor(a,r,g,b); + } + + //! Interpolates the color with a f32 value to another color + //! \param other: Other color + //! \param d: value between 0.0f and 1.0f + //! \return Returns interpolated color. + inline SColor getInterpolated(const SColor &other, f32 d) const + { + const f32 inv = 1.0f - d; + return SColor((u32)(other.getAlpha()*inv + getAlpha()*d), + (u32)(other.getRed()*inv + getRed()*d), + (u32)(other.getGreen()*inv + getGreen()*d), + (u32)(other.getBlue()*inv + getBlue()*d)); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + inline SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, const f32 d) const + { + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColor ( core::clamp ( core::floor32 ( getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ), + core::clamp ( core::floor32 ( getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ), + core::clamp ( core::floor32 ( getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ), + core::clamp ( core::floor32 ( getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 )); + } + + //! color in A8R8G8B8 Format + u32 color; + }; + + + //! Class representing a color with four floats. + /** The color values for red, green, blue + and alpha are each stored in a 32 bit floating point variable. + So all four values may be between 0.0f and 1.0f. + This class is rarely used by the Irrlicht Engine + to specify a color. Another, faster way is using the class Color, which + stores the color values in a single 32 bit integer. + */ + class SColorf + { + public: + + //! Constructs a color. All values are initialised with 0.0f, resulting + //! in a black color. + SColorf() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}; + + //! Constructs a color from three color values: red, green and blue. + //! \param r: Red color component. Should be a value between 0.0f meaning + //! no red (=black) and 1.0f, meaning full red. + //! \param g: Green color component. Should be a value between 0.0f meaning + //! no green (=black) and 1.0f, meaning full green. + //! \param b: Blue color component. Should be a value between 0.0f meaning + //! no blue (=black) and 1.0f, meaning full blue. + SColorf(f32 r, f32 g, f32 b) : r(r), g(g), b(b), a(1.0f) {}; + + //! Constructs a color from four color values: red, green, blue, and alpha. + //! \param r: Red color component. Should be a value between 0.0f meaning + //! no red (=black) and 1.0f, meaning full red. + //! \param g: Green color component. Should be a value between 0.0f meaning + //! no green (=black) and 1.0f, meaning full green. + //! \param b: Blue color component. Should be a value between 0.0f meaning + //! no blue (=black) and 1.0f, meaning full blue. + //! \param a: Alpha color component of the color. + //! The alpha component defines how transparent a color should be. + //! Has to be a value between 0.0f and 1.0f, + //! 0.0f means not transparent (opaque), 1.0f means fully transparent. + SColorf(f32 r, f32 g, f32 b, f32 a) : r(r), g(g), b(b), a(a) {}; + + //! Constructs a color from 32 bit Color. + //! \param c: 32 bit color value from which this Colorf class is + //! constructed from. + SColorf(SColor c) { const f32 inv = 1.0f / 255.0f; r = c.getRed() * inv; g = c.getGreen() * inv; b = c.getBlue() * inv; a = c.getAlpha() * inv; }; + + //! Converts this color to a SColor without floats. + SColor toSColor() const + { + return SColor((s32)(a*255.0f), (s32)(r*255.0f), (s32)(g*255.0f), (s32)(b*255.0f)); + } + + //! red color component + f32 r; + + //! green color component + f32 g; + + //! blue component + f32 b; + + //! alpha color component + f32 a; + + //! Sets three color components to new values at once. + //! \param rr: Red color component. Should be a value between 0.0f meaning + //! no red (=black) and 1.0f, meaning full red. + //! \param gg: Green color component. Should be a value between 0.0f meaning + //! no green (=black) and 1.0f, meaning full green. + //! \param bb: Blue color component. Should be a value between 0.0f meaning + //! no blue (=black) and 1.0f, meaning full blue. + void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }; + + //! Sets all four color components to new values at once. + //! \param aa: Alpha component. + //! \param rr: Red color component. Should be a value between 0.0f meaning + //! no red (=black) and 1.0f, meaning full red. + //! \param gg: Green color component. Should be a value between 0.0f meaning + //! no green (=black) and 1.0f, meaning full green. + //! \param bb: Blue color component. Should be a value between 0.0f meaning + //! no blue (=black) and 1.0f, meaning full blue. + void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }; + + //! Interpolates the color with a f32 value to another color + //! \param other: Other color + //! \param d: value between 0.0f and 1.0f + //! \return Returns interpolated color. + inline SColorf getInterpolated(const SColorf &other, f32 d) const + { + const f32 inv = 1.0f - d; + return SColorf(other.r*inv + r*d, + other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2, const f32 d) const + { + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColorf ( r * mul0 + c1.r * mul1 + c2.r * mul2, + g * mul0 + c1.g * mul1 + c2.g * mul2, + g * mul0 + c1.b * mul1 + c2.b * mul2, + a * mul0 + c1.a * mul1 + c2.a * mul2); + } + + + + //! Sets a color component by index. R=0, G=1, B=2, A=3 + inline void setColorComponentValue(s32 index, f32 value) + { + switch(index) + { + case 0: r = value; break; + case 1: g = value; break; + case 2: b = value; break; + case 3: a = value; break; + } + } + }; + + //! Class representing a color in HSV format + /** The color values for hue, saturation, value + are stored in a 32 bit floating point variable. + */ + class SColorHSL + { + public: + SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f ) + : Hue ( h ), Saturation ( s ), Luminance ( l ) {} + + void setfromRGB ( const SColor &color ); + void settoRGB ( SColor &color ) const; + + f32 Hue; + f32 Saturation; + f32 Luminance; + + private: + inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const; + + }; + + inline void SColorHSL::settoRGB ( SColor &color ) const + { + if ( Saturation == 0.0f) // grey + { + u8 c = (u8) ( Luminance * 255.0 ); + color.setRed ( c ); + color.setGreen ( c ); + color.setBlue ( c ); + return; + } + + f32 rm1, rm2; + + if ( Luminance <= 0.5f ) + { + rm2 = Luminance + Luminance * Saturation; + } + else + { + rm2 = Luminance + Saturation - Luminance * Saturation; + } + + rm1 = 2.0f * Luminance - rm2; + + color.setRed ( toRGB1(rm1, rm2, Hue + (120.0f * core::DEGTORAD )) ); + color.setGreen ( toRGB1(rm1, rm2, Hue) ); + color.setBlue ( toRGB1(rm1, rm2, Hue - (120.0f * core::DEGTORAD) ) ); + } + + + inline u32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const + { + while ( rh > 2.f * core::PI ) + rh -= 2.f * core::PI; + + while ( rh < 0.f ) + rh += 2.f * core::PI; + + if (rh < 60.0f * core::DEGTORAD ) rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD); + else if (rh < 180.0f * core::DEGTORAD ) rm1 = rm2; + else if (rh < 240.0f * core::DEGTORAD ) rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) / (60.0f * core::DEGTORAD); + + return (u32) (rm1 * 255.f); + } + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SExposedVideoData.h b/src/dep/include/irrlicht/SExposedVideoData.h new file mode 100644 index 0000000..f89e8bc --- /dev/null +++ b/src/dep/include/irrlicht/SExposedVideoData.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_EXPOSED_VIDEO_DATA_H_INCLUDED__ +#define __S_EXPOSED_VIDEO_DATA_H_INCLUDED__ + +// forward declarations for internal pointers +struct IDirect3D9; +struct IDirect3DDevice9; +struct IDirect3D8; +struct IDirect3DDevice8; + +namespace irr +{ +namespace video +{ + +//! structure for holding data describing a driver and operating system specific data. +/** This data can be retrived by IVideoDriver::getExposedVideoData(). Use this with caution. + This only should be used to make it possible to extend the engine easily without + modification of its source. Note that this structure does not contain any valid data, if + you are using the software or the null device. +*/ +struct SExposedVideoData +{ + union + { + struct + { + //! Pointer to the IDirect3D9 interface + IDirect3D9* D3D9; + + //! Pointer to the IDirect3D9 interface + IDirect3DDevice9* D3DDev9; + + //! Window handle. Get with for example + //! HWND h = reinterpret_cast(exposedData.D3D9.HWnd) + s32 HWnd; + + } D3D9; + + struct + { + //! Pointer to the IDirect3D8 interface + IDirect3D8* D3D8; + + //! Pointer to the IDirect3D8 interface + IDirect3DDevice8* D3DDev8; + + //! Window handle. Get with for example with: + //! HWND h = reinterpret_cast(exposedData.D3D8.HWnd) + s32 HWnd; + + } D3D8; + + struct + { + //! Private GDI Device Context. Get if for example with: + //! HDC h = reinterpret_cast(exposedData.OpenGLWin32.HDc) + s32 HDc; + + //! Permanent Rendering Context. Get if for example with: + //! HGLRC h = reinterpret_cast(exposedData.OpenGLWin32.HRc) + s32 HRc; + + //! Window handle. Get with for example with: + //! HWND h = reinterpret_cast(exposedData.OpenGLWin32.HWnd) + s32 HWnd; + + } OpenGLWin32; + + struct + { + // XWindow handles + void* X11Display; + unsigned long X11Window; + } OpenGLLinux; + }; +}; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/SIrrCreationParameters.h b/src/dep/include/irrlicht/SIrrCreationParameters.h new file mode 100644 index 0000000..86002f8 --- /dev/null +++ b/src/dep/include/irrlicht/SIrrCreationParameters.h @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IRRLICHT_CREATION_PARAMETERS_H_INCLUDED__ +#define __I_IRRLICHT_CREATION_PARAMETERS_H_INCLUDED__ + +namespace irr +{ + //! Structure for holding advanced Irrlicht Device creation parameters. + /** This structure is only used in the createDeviceEx() function. */ + struct SIrrlichtCreationParameters + { + //! Constructs a SIrrlichtCreationParameters structure with default values. + SIrrlichtCreationParameters() + { + DriverType = video::EDT_BURNINGSVIDEO; + WindowSize = core::dimension2d(800, 600); + Bits = 16; + Fullscreen = false; + Stencilbuffer = false; + Vsync = false; + AntiAlias = false; + HighPrecisionFPU = false; + EventReceiver = 0; + WindowId = 0; + SDK_version_do_not_use = IRRLICHT_SDK_VERSION; + } + + //! Type of the device. + /** This can currently be video::EDT_NULL, + video::EDT_SOFTWARE, video::EDT_DIRECT3D8, video::EDT_DIRECT3D9 and video::EDT_OPENGL. + Default: Software. */ + video::E_DRIVER_TYPE DriverType; + + //! Size of the window or the video mode in fullscreen mode. Default: 800x600 + core::dimension2d WindowSize; + + //! Bits per pixel in fullscreen mode. Ignored if windowed mode. Default: 16. + u32 Bits; + + //! Should be set to true if the device should run in fullscreen. + /** Otherwise the device runs in windowed mode. Default: false. */ + bool Fullscreen; + + //! Specifies if the stencil buffer should be enabled. + /** Set this to true, + if you want the engine be able to draw stencil buffer shadows. Note that not all + devices are able to use the stencil buffer. If they don't no shadows will be drawn. + Default: false. */ + bool Stencilbuffer; + + //! Specifies vertical syncronisation. + /** If set to true, the driver will wait for the vertical retrace period, otherwise not. + Default: false */ + bool Vsync; + + //! Specifies if the device should use fullscreen anti aliasing + /** Makes sharp/pixelated edges softer, but requires more performance. Also, 2D + elements might look blurred with this switched on. The resulting rendering quality + also depends on the hardware and driver you are using, your program might look + different on different hardware with this. So if you are writing a + game/application with antiAlias switched on, it would be a good idea to make it + possible to switch this option off again by the user. + This is only supported in D3D9 and D3D8. In D3D9, both sample types are supported, + D3DMULTISAMPLE_X_SAMPLES and D3DMULTISAMPLE_NONMASKABLE. Default value: false */ + bool AntiAlias; + + //! Specifies if the device should use high precision FPU setting + /** This is only relevant for DirectX Devices, which switch to low FPU precision + by default for performance reasons. However, this may lead to problems with the + other computations of the application. In this case setting this flag to true + should help - on the expense of performance loss, though. + Default value: false */ + bool HighPrecisionFPU; + + //! A user created event receiver. + IEventReceiver* EventReceiver; + + //! Window Id. + /** If this is set to a value other than 0, the Irrlicht Engine will be created in + an already existing window. For windows, set this to the HWND of the window you want. + The windowSize and FullScreen options will be ignored when using the WindowId parameter. + Default this is set to 0. + To make Irrlicht run inside the custom window, you still will have to draw Irrlicht + on your own. You can use this loop, as usual: + \code + while (device->run()) + { + driver->beginScene(true, true, 0); + smgr->drawAll(); + driver->endScene(); + } + \endcode + Instead of this, you can also simply use your own message loop + using GetMessage, DispatchMessage and whatever. Calling + IrrlichtDevice::run() will cause Irrlicht to dispatch messages internally too. + You need not call Device->run() if you want to do your own message + dispatching loop, but Irrlicht will not be able to fetch + user input then and you have to do it on your own using the window + messages, DirectInput, or whatever. Also, you'll have to increment the Irrlicht timer. + An alternative, own message dispatching loop without device->run() would + look like this: + \code + MSG msg; + while (true) + { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + break; + } + + // increase virtual timer time + device->getTimer()->tick(); + + // draw engine picture + driver->beginScene(true, true, 0); + smgr->drawAll(); + driver->endScene(); + } + \endcode + However, there is no need to draw the picture this often. Just do it how you like. + */ + void* WindowId; + + //! Don't use or change this parameter. + /** Always set it to IRRLICHT_SDK_VERSION, which is done by default. + This is needed for sdk version checks. */ + const c8* SDK_version_do_not_use; + }; + + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SKeyMap.h b/src/dep/include/irrlicht/SKeyMap.h new file mode 100644 index 0000000..dca1490 --- /dev/null +++ b/src/dep/include/irrlicht/SKeyMap.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_KEY_MAP_H_INCLUDED__ +#define __S_KEY_MAP_H_INCLUDED__ + +#include "Keycodes.h" + +namespace irr +{ + + //! enumeration for key actions. Used for example in the FPS Camera. + enum EKEY_ACTION + { + EKA_MOVE_FORWARD = 0, + EKA_MOVE_BACKWARD, + EKA_STRAFE_LEFT, + EKA_STRAFE_RIGHT, + EKA_JUMP_UP, + EKA_COUNT, + + //! This value is not used. It only forces this enumeration to compile in 32 bit. + EKA_FORCE_32BIT = 0x7fffffff + }; + + //! Struct storing which key belongs to which action. + struct SKeyMap + { + EKEY_ACTION Action; + EKEY_CODE KeyCode; + }; + +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SLight.h b/src/dep/include/irrlicht/SLight.h new file mode 100644 index 0000000..d3a76f7 --- /dev/null +++ b/src/dep/include/irrlicht/SLight.h @@ -0,0 +1,91 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_LIGHT_H_INCLUDED__ +#define __S_LIGHT_H_INCLUDED__ + +#include "SColor.h" + +namespace irr +{ +namespace video +{ + +//! Enumeration for different types of lights +enum E_LIGHT_TYPE +{ + //! point light, it has a position in space and radiates light in all directions + ELT_POINT, + //! spot light, it has a position in space, a direction, and a limited cone of influence + ELT_SPOT, + //! directional light, coming from a direction from an infinite distance + ELT_DIRECTIONAL +}; + +//! Names for light types +const c8* const LightTypeNames[] = +{ + "Point", + "Spot", + "Directional", + 0 +}; + +//! structure for holding data describing a dynamic point light. +/** Irrlicht supports point lights, spot lights, and directional lights. +*/ +struct SLight +{ + SLight() : AmbientColor(0.0f,0.0f,0.0f), DiffuseColor(1.0f,1.0f,1.0f), + SpecularColor(1.0f,1.0f,1.0f), Attenuation(1.0f,0.0f,0.0f), + Radius(100.0f), OuterCone(45.0f), InnerCone(0.0f), + Falloff(2.0f), CastShadows(true), Type(ELT_POINT), + Position(0.0f,0.0f,0.0f), Direction(0.0f,0.0f,1.0f) + {}; + + //! Ambient color emitted by the light + SColorf AmbientColor; + + //! Diffuse color emitted by the light. + /** This is the primary color you might want to set. */ + SColorf DiffuseColor; + + //! Specular color emitted by the light. + /** For details how to use specular highlights, see SMaterial::Shininess */ + SColorf SpecularColor; + + //! Attenuation factors (constant, linear, quadratic) + /** Changes the light strength fading over distance */ + core::vector3df Attenuation; + + //! Radius of light. Everything within this radius be be lighted. + f32 Radius; + + //! The angle of the spot's outer cone. Ignored for other lights. + f32 OuterCone; + + //! The angle of the spot's inner cone. Ignored for other lights. + f32 InnerCone; + + //! The light strength's decrease between Outer and Inner cone. + f32 Falloff; + + //! Does the light cast shadows? + bool CastShadows; + + //! Type of the light. Default: ELT_POINT + E_LIGHT_TYPE Type; + + //! Read-ONLY! Position of the light. If Type is ELT_DIRECTIONAL, this is ignored. + core::vector3df Position; + + //! Read-ONLY! Direction of the light. If Type is ELT_POINT, this is ignored. + core::vector3df Direction; +}; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SMaterial.h b/src/dep/include/irrlicht/SMaterial.h new file mode 100644 index 0000000..ac3e1cc --- /dev/null +++ b/src/dep/include/irrlicht/SMaterial.h @@ -0,0 +1,387 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_MATERIAL_H_INCLUDED__ +#define __S_MATERIAL_H_INCLUDED__ + +#include "SColor.h" +#include "matrix4.h" +#include "irrArray.h" +#include "EMaterialTypes.h" +#include "EMaterialFlags.h" +#include "SMaterialLayer.h" + +namespace irr +{ +namespace video +{ + class ITexture; + + //! Flag for EMT_ONETEXTURE_BLEND, ( BlendFactor ) + //! BlendFunc = source * sourceFactor + dest * destFactor + enum E_BLEND_FACTOR + { + EBF_ZERO = 0, // src & dest (0, 0, 0, 0) + EBF_ONE, // src & dest (1, 1, 1, 1) + EBF_DST_COLOR, // src (destR, destG, destB, destA) + EBF_ONE_MINUS_DST_COLOR, // src (1-destR, 1-destG, 1-destB, 1-destA) + EBF_SRC_COLOR, // dest (srcR, srcG, srcB, srcA) + EBF_ONE_MINUS_SRC_COLOR, // dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + EBF_SRC_ALPHA, // src & dest (srcA, srcA, srcA, srcA) + EBF_ONE_MINUS_SRC_ALPHA, // src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + EBF_DST_ALPHA, // src & dest (destA, destA, destA, destA) + EBF_ONE_MINUS_DST_ALPHA, // src & dest (1-destA, 1-destA, 1-destA, 1-destA) + EBF_SRC_ALPHA_SATURATE // src (min(srcA, 1-destA), idem, ...) + }; + + //! MaterialTypeParam: e.g. DirectX: D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X + enum E_MODULATE_FUNC + { + EMFN_MODULATE_1X = 1, + EMFN_MODULATE_2X = 2, + EMFN_MODULATE_4X = 4 + }; + + //! EMT_ONETEXTURE_BLEND: pack srcFact & dstFact and Modulo to MaterialTypeParam + inline f32 pack_texureBlendFunc ( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate ) + { + return (f32)(modulate << 16 | srcFact << 8 | dstFact); + } + + //! EMT_ONETEXTURE_BLEND: unpack srcFact & dstFact and Modulo to MaterialTypeParam + inline void unpack_texureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact, E_MODULATE_FUNC &modulo, const f32 param ) + { + const u32 state = (u32)param; + modulo = E_MODULATE_FUNC ( ( state & 0x00FF0000 ) >> 16 ); + srcFact = E_BLEND_FACTOR ( ( state & 0x0000FF00 ) >> 8 ); + dstFact = E_BLEND_FACTOR ( ( state & 0x000000FF ) ); + } + + //! Maximum number of texture an SMaterial can have. + const u32 MATERIAL_MAX_TEXTURES = 4; + + //! struct for holding parameters for a material renderer + class SMaterial + { + public: + //! default constructor, creates a solid material with standard colors + SMaterial() + : MaterialType(EMT_SOLID), AmbientColor(255,255,255,255), DiffuseColor(255,255,255,255), + EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255), + Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f), + Wireframe(false), PointCloud(false), GouraudShading(true), Lighting(true), + ZBuffer(true), ZWriteEnable(true), BackfaceCulling(true), + FogEnable(false), NormalizeNormals(false) + { } + + //! copy constructor + SMaterial(const SMaterial& other) + { + // These pointers are checked during assignment + for (u32 i=0; igetMaterial(0).Shininess = 20.0f; + \endcode + + You can also change the color of the highlights using + \code + sceneNode->getMaterial(0).SpecularColor.set(255,255,255,255); + \endcode + + The specular color of the dynamic lights (SLight::SpecularColor) will influence + the the highlight color too, but they are set to a useful value by default when + creating the light scene node. Here is a simple example on how + to use specular highlights: + \code + // load and display mesh + scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( + smgr->getMesh("data/faerie.md2")); + node->setMaterialTexture(0, driver->getTexture("data/Faerie2.pcx")); // set diffuse texture + node->setMaterialFlag(video::EMF_LIGHTING, true); // enable dynamic lighting + node->getMaterial(0).Shininess = 20.0f; // set size of specular highlights + + // add white light + scene::ILightSceneNode* light = smgr->addLightSceneNode(0, + core::vector3df(5,5,5), video::SColorf(1.0f, 1.0f, 1.0f)); + \endcode */ + f32 Shininess; + + //! Free parameter, dependent on the material type. + /** Mostly ignored, used for example in EMT_PARALLAX_MAP_SOLID + and EMT_TRANSPARENT_ALPHA_CHANNEL. */ + f32 MaterialTypeParam; + + //! Second free parameter, dependent on the material type. + /** Mostly ignored. */ + f32 MaterialTypeParam2; + + //! Thickness of non-3dimensional elements such as lines and points. + f32 Thickness; + + //! Texture layer array. + SMaterialLayer TextureLayer[MATERIAL_MAX_TEXTURES]; + + //! material flags + /** The user can access the material flag using + material.Wireframe = true or material.setFlag(EMF_WIREFRAME, true); */ + //! Draw as wireframe or filled triangles? Default: false + bool Wireframe; + + //! Draw as point cloud or filled triangles? Default: false + bool PointCloud; + + //! Flat or Gouraud shading? Default: true + bool GouraudShading; + + //! Will this material be lighted? Default: true + bool Lighting; + + //! Is the ZBuffer enabled? Default: true + //! Changed from bool to integer + // ( 0 == ZBuffer Off, 1 == ZBuffer LessEqual, 2 == ZBuffer Equal ) + u32 ZBuffer; + + //! Is the zbuffer writeable or is it read-only. + /** Default: 1 This flag is ignored, if the MaterialType + is a transparent type. */ + bool ZWriteEnable; + + //! Is backface culling enabled? Default: true + bool BackfaceCulling; + + //! Is fog enabled? Default: false + bool FogEnable; + + //! Should normals be normalized? Default: false + bool NormalizeNormals; + + //! Gets the texture transformation matrix for level i + core::matrix4& getTextureMatrix(u32 i) + { + if (i=MATERIAL_MAX_TEXTURES) + return; + TextureLayer[i].setTextureMatrix(mat); + } + + //! Gets the i-th texture + ITexture* getTexture(u32 i) const + { + if (i>=MATERIAL_MAX_TEXTURES) + return 0; + else + return TextureLayer[i].Texture; + } + + //! Sets the i-th texture + void setTexture(u32 i, ITexture* tex) + { + if (i>=MATERIAL_MAX_TEXTURES) + return; + TextureLayer[i].Texture = tex; + } + + //! Sets the Material flag to the given value + void setFlag(E_MATERIAL_FLAG flag, bool value) + { + switch (flag) + { + case EMF_WIREFRAME: + Wireframe = value; break; + case EMF_POINTCLOUD: + PointCloud = value; break; + case EMF_GOURAUD_SHADING: + GouraudShading = value; break; + case EMF_LIGHTING: + Lighting = value; break; + case EMF_ZBUFFER: + ZBuffer = value; break; + case EMF_ZWRITE_ENABLE: + ZWriteEnable = value; break; + case EMF_BACK_FACE_CULLING: + BackfaceCulling = value; break; + case EMF_BILINEAR_FILTER: + { + for (u32 i=0; idrop(); + } + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return MeshBuffers.size(); + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return MeshBuffers[nr]; + } + + //! returns a meshbuffer which fits a material + // reverse search + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial & material) const + { + for (s32 i = (s32) MeshBuffers.size(); --i >= 0; ) + { + if ( material == MeshBuffers[i]->getMaterial()) + return MeshBuffers[i]; + } + + return 0; + } + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const + { + return BoundingBox; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! recalculates the bounding box + void recalculateBoundingBox() + { + if (MeshBuffers.size()) + { + BoundingBox = MeshBuffers[0]->getBoundingBox(); + for (u32 i=1; igetBoundingBox()); + } + else + BoundingBox.reset(0.0f, 0.0f, 0.0f); + } + + //! adds a MeshBuffer + void addMeshBuffer(IMeshBuffer* buf) + { + if (buf) + { + buf->grab(); + MeshBuffers.push_back(buf); + } + } + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + for (u32 i=0; igetMaterial().setFlag(flag, newvalue); + } + + core::array MeshBuffers; + core::aabbox3d BoundingBox; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SMeshBuffer.h b/src/dep/include/irrlicht/SMeshBuffer.h new file mode 100644 index 0000000..73a4d90 --- /dev/null +++ b/src/dep/include/irrlicht/SMeshBuffer.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/src/dep/include/irrlicht/SMeshBufferLightMap.h b/src/dep/include/irrlicht/SMeshBufferLightMap.h new file mode 100644 index 0000000..73a4d90 --- /dev/null +++ b/src/dep/include/irrlicht/SMeshBufferLightMap.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/src/dep/include/irrlicht/SMeshBufferTangents.h b/src/dep/include/irrlicht/SMeshBufferTangents.h new file mode 100644 index 0000000..73a4d90 --- /dev/null +++ b/src/dep/include/irrlicht/SMeshBufferTangents.h @@ -0,0 +1,7 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// replaced by template +#include "CMeshBuffer.h" + diff --git a/src/dep/include/irrlicht/SParticle.h b/src/dep/include/irrlicht/SParticle.h new file mode 100644 index 0000000..92bd97a --- /dev/null +++ b/src/dep/include/irrlicht/SParticle.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_PARTICLE_H_INCLUDED__ +#define __S_PARTICLE_H_INCLUDED__ + +#include "vector3d.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + //! Struct for holding particle data + struct SParticle + { + //! Position of the particle + core::vector3df pos; + + //! Direction and speed of the particle + core::vector3df vector; + + //! Start life time of the particle + u32 startTime; + + //! End life time of the particle + u32 endTime; + + //! Current color of the particle + video::SColor color; + + //! Original color of the particle. That's the color + //! of the particle it had when it was emitted. + video::SColor startColor; + + //! Original direction and speed of the particle, + //! the direction and speed the particle had when + //! it was emitted. + core::vector3df startVector; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SSharedMeshBuffer.h b/src/dep/include/irrlicht/SSharedMeshBuffer.h new file mode 100644 index 0000000..fbbef73 --- /dev/null +++ b/src/dep/include/irrlicht/SSharedMeshBuffer.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_SHARED_MESH_BUFFER_H_INCLUDED__ +#define __S_SHARED_MESH_BUFFER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + //! Implementation of the IMeshBuffer interface with shared vertex list + struct SSharedMeshBuffer : public IMeshBuffer + { + //! constructor + SSharedMeshBuffer() : IMeshBuffer(), Vertices(0) + { + #ifdef _DEBUG + setDebugName("SSharedMeshBuffer"); + #endif + } + + SSharedMeshBuffer(core::array *vertices) : IMeshBuffer(), Vertices(vertices) + { + #ifdef _DEBUG + setDebugName("SSharedMeshBuffer"); + #endif + } + + //! destructor + virtual ~SSharedMeshBuffer() { } + + //! returns the material of this meshbuffer + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + //! returns the material of this meshbuffer + virtual video::SMaterial& getMaterial() + { + return Material; + } + + //! returns pointer to vertices + virtual const void* getVertices() const + { + if (Vertices) + return Vertices->const_pointer(); + else + return 0; + } + + //! returns pointer to vertices + virtual void* getVertices() + { + if (Vertices) + return Vertices->pointer(); + else + return 0; + } + + //! returns amount of vertices + virtual u32 getVertexCount() const + { + if (Vertices) + return Vertices->size(); + else + return 0; + } + + //! returns pointer to Indices + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + //! returns pointer to Indices + virtual u16* getIndices() + { + return Indices.pointer(); + } + + //! returns amount of indices + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const + { + return BoundingBox; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + //! returns which type of vertex data is stored. + virtual video::E_VERTEX_TYPE getVertexType() const + { + return video::EVT_STANDARD; + } + + //! recalculates the bounding box. should be called if the mesh changed. + virtual void recalculateBoundingBox() + { + if (!Vertices || Vertices->empty() || Indices.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset((*Vertices)[Indices[0]].Pos); + for (u32 i=1; i *Vertices;//! Shared Array of vertices + core::array Indices; //! Array of Indices + core::aabbox3df BoundingBox; //! Bounding box + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SSkinMeshBuffer.h b/src/dep/include/irrlicht/SSkinMeshBuffer.h new file mode 100644 index 0000000..e0ebcee --- /dev/null +++ b/src/dep/include/irrlicht/SSkinMeshBuffer.h @@ -0,0 +1,228 @@ +// Copyright (C) 2002-2006 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SKIN_MESH_BUFFER_H_INCLUDED__ +#define __I_SKIN_MESH_BUFFER_H_INCLUDED__ + +#include "IMeshBuffer.h" +#include "S3DVertex.h" + + +namespace irr +{ +namespace scene +{ + + +//! A mesh buffer able to choose between +//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime +struct SSkinMeshBuffer : public IMeshBuffer +{ + SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : VertexType(vt) + { + #ifdef _DEBUG + setDebugName("SSkinMeshBuffer"); + #endif + } + + virtual ~SSkinMeshBuffer() {} + + virtual const video::SMaterial& getMaterial() const + { + return Material; + } + + virtual video::SMaterial& getMaterial() + { + return Material; + } + + virtual video::S3DVertex *getVertex(u32 index) + { + switch (VertexType) + { + case video::EVT_2TCOORDS: return (video::S3DVertex*)&Vertices_2TCoords[index]; + case video::EVT_TANGENTS: return (video::S3DVertex*)&Vertices_Tangents[index]; + default: return &Vertices_Standard[index]; + } + } + + virtual const void* getVertices() const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: return Vertices_2TCoords.const_pointer(); + case video::EVT_TANGENTS: return Vertices_Tangents.const_pointer(); + default: return Vertices_Standard.const_pointer(); + } + } + + virtual void* getVertices() + { + switch (VertexType) + { + case video::EVT_2TCOORDS: return Vertices_2TCoords.pointer(); + case video::EVT_TANGENTS: return Vertices_Tangents.pointer(); + default: return Vertices_Standard.pointer(); + } + } + + virtual u32 getVertexCount() const + { + switch (VertexType) + { + case video::EVT_2TCOORDS: return Vertices_2TCoords.size(); + case video::EVT_TANGENTS: return Vertices_Tangents.size(); + default: return Vertices_Standard.size(); + } + } + + virtual const u16* getIndices() const + { + return Indices.const_pointer(); + } + + virtual u16* getIndices() + { + return Indices.pointer(); + } + + virtual u32 getIndexCount() const + { + return Indices.size(); + } + + virtual const core::aabbox3d& getBoundingBox() const + { + return BoundingBox; + } + + virtual void setBoundingBox( const core::aabbox3df& box) + { + BoundingBox = box; + } + + virtual void recalculateBoundingBox() + { + switch (VertexType) + { + case video::EVT_STANDARD: + { + if (Vertices_Standard.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertices_Standard[0].Pos); + for (u32 i=1; i Vertices_Tangents; + core::array Vertices_2TCoords; + core::array Vertices_Standard; + core::array Indices; + core::aabbox3d BoundingBox; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SViewFrustum.h b/src/dep/include/irrlicht/SViewFrustum.h new file mode 100644 index 0000000..87fb915 --- /dev/null +++ b/src/dep/include/irrlicht/SViewFrustum.h @@ -0,0 +1,342 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VIEW_FRUSTUM_H_INCLUDED__ +#define __S_VIEW_FRUSTUM_H_INCLUDED__ + +#include "plane3d.h" +#include "vector3d.h" +#include "aabbox3d.h" +#include "matrix4.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + + //! Defines the view frustum. That's the space visible by the camera. + /** The view frustum is enclosed by 6 planes. These six planes share + four points. A bounding box around these four points is also stored in + this structure. + */ + struct SViewFrustum + { + enum VFPLANES + { + //! Far plane of the frustum. That is the plane farest away from the eye. + VF_FAR_PLANE = 0, + //! Near plane of the frustum. That is the plane nearest to the eye. + VF_NEAR_PLANE, + //! Left plane of the frustum. + VF_LEFT_PLANE, + //! Right plane of the frustum. + VF_RIGHT_PLANE, + //! Bottom plane of the frustum. + VF_BOTTOM_PLANE, + //! Top plane of the frustum. + VF_TOP_PLANE, + + //! Amount of planes enclosing the view frustum. Should be 6. + VF_PLANE_COUNT + }; + + //! Hold a copy of important transform matrices + enum E_TRANSFORMATION_STATE_3 + { + ETS_VIEW_PROJECTION_3 = video::ETS_PROJECTION + 1, + ETS_VIEW_MODEL_INVERSE_3, + ETS_CURRENT_3, + ETS_COUNT_3 + }; + + //! Default Constructor + SViewFrustum() {} + + //! Copy Constructor + SViewFrustum(const SViewFrustum& other); + + //! This constructor creates a view frustum based on a + //! projection and/or view matrix. + SViewFrustum(const core::matrix4& mat); + + //! This constructor creates a view frustum based on a projection + //! and/or view matrix. + inline void setFrom(const core::matrix4& mat); + + //! transforms the frustum by the matrix + //! \param mat: Matrix by which the view frustum is transformed. + void transform(const core::matrix4& mat); + + //! returns the point which is on the far left upper corner inside the + //! the view frustum. + core::vector3df getFarLeftUp() const; + + //! returns the point which is on the far left bottom corner inside the + //! the view frustum. + core::vector3df getFarLeftDown() const; + + //! returns the point which is on the far right top corner inside the + //! the view frustum. + core::vector3df getFarRightUp() const; + + //! returns the point which is on the far right bottom corner inside the + //! the view frustum. + core::vector3df getFarRightDown() const; + + //! returns a bounding box enclosing the whole view frustum + const core::aabbox3d &getBoundingBox() const; + + //! recalculates the bounding box member based on the planes + inline void recalculateBoundingBox(); + + void setTransformState( video::E_TRANSFORMATION_STATE state); + + //! the position of the camera + core::vector3df cameraPosition; + + //! all planes enclosing the view frustum. + core::plane3d planes[VF_PLANE_COUNT]; + + //! bounding box around the view frustum + core::aabbox3d boundingBox; + + //! Hold a copy of important transform matrices + core::matrix4 Matrices[ETS_COUNT_3]; + }; + + + //! Construct from another view frustum + inline SViewFrustum::SViewFrustum(const SViewFrustum& other) + { + cameraPosition=other.cameraPosition; + boundingBox=other.boundingBox; + + u32 i; + for (i=0; i &SViewFrustum::getBoundingBox() const + { + return boundingBox; + } + + //! recalculates the bounding box member based on the planes + inline void SViewFrustum::recalculateBoundingBox() + { + boundingBox.reset ( cameraPosition ); + + boundingBox.addInternalPoint(getFarLeftUp()); + boundingBox.addInternalPoint(getFarRightUp()); + boundingBox.addInternalPoint(getFarLeftDown()); + boundingBox.addInternalPoint(getFarRightDown()); + } + +/* + //! This constructor creates a view frustum based on a projection + //! and/or view matrix. + inline void SViewFrustum::setFrom(const core::matrix4& mat) + { + // left clipping plane + planes[SViewFrustum::VF_LEFT_PLANE].Normal.X = -(mat(0,3) + mat(0,0)); + planes[SViewFrustum::VF_LEFT_PLANE].Normal.Y = -(mat(1,3) + mat(1,0)); + planes[SViewFrustum::VF_LEFT_PLANE].Normal.Z = -(mat(2,3) + mat(2,0)); + planes[SViewFrustum::VF_LEFT_PLANE].D = -(mat(3,3) + mat(3,0)); + + // right clipping plane + planes[SViewFrustum::VF_RIGHT_PLANE].Normal.X = -(mat(0,3) - mat(0,0)); + planes[SViewFrustum::VF_RIGHT_PLANE].Normal.Y = -(mat(1,3) - mat(1,0)); + planes[SViewFrustum::VF_RIGHT_PLANE].Normal.Z = -(mat(2,3) - mat(2,0)); + planes[SViewFrustum::VF_RIGHT_PLANE].D = -(mat(3,3) - mat(3,0)); + + // top clipping plane + planes[SViewFrustum::VF_TOP_PLANE].Normal.X = -(mat(0,3) - mat(0,1)); + planes[SViewFrustum::VF_TOP_PLANE].Normal.Y = -(mat(1,3) - mat(1,1)); + planes[SViewFrustum::VF_TOP_PLANE].Normal.Z = -(mat(2,3) - mat(2,1)); + planes[SViewFrustum::VF_TOP_PLANE].D = -(mat(3,3) - mat(3,1)); + + // bottom clipping plane + planes[SViewFrustum::VF_BOTTOM_PLANE].Normal.X = -(mat(0,3) + mat(0,1)); + planes[SViewFrustum::VF_BOTTOM_PLANE].Normal.Y = -(mat(1,3) + mat(1,1)); + planes[SViewFrustum::VF_BOTTOM_PLANE].Normal.Z = -(mat(2,3) + mat(2,1)); + planes[SViewFrustum::VF_BOTTOM_PLANE].D = -(mat(3,3) + mat(3,1)); + + // near clipping plane + planes[SViewFrustum::VF_NEAR_PLANE].Normal.X = -mat(0,2); + planes[SViewFrustum::VF_NEAR_PLANE].Normal.Y = -mat(1,2); + planes[SViewFrustum::VF_NEAR_PLANE].Normal.Z = -mat(2,2); + planes[SViewFrustum::VF_NEAR_PLANE].D = -mat(3,2); + + // far clipping plane + planes[SViewFrustum::VF_FAR_PLANE].Normal.X = -(mat(0,3) - mat(0,2)); + planes[SViewFrustum::VF_FAR_PLANE].Normal.Y = -(mat(1,3) - mat(1,2)); + planes[SViewFrustum::VF_FAR_PLANE].Normal.Z = -(mat(2,3) - mat(2,2)); + planes[SViewFrustum::VF_FAR_PLANE].D = -(mat(3,3) - mat(3,2)); + // normalize normals + + for (s32 i=0; i<6; ++i) + { + const f32 len = core::reciprocal_squareroot ( planes[i].Normal.getLengthSQ() ); + planes[i].Normal *= len; + planes[i].D *= len; + } + + // make bounding box + recalculateBoundingBox(); + } +*/ + + //! This constructor creates a view frustum based on a projection + //! and/or view matrix. + inline void SViewFrustum::setFrom(const core::matrix4& mat) + { + // left clipping plane + planes[VF_LEFT_PLANE].Normal.X = mat[3 ] + mat[0]; + planes[VF_LEFT_PLANE].Normal.Y = mat[7 ] + mat[4]; + planes[VF_LEFT_PLANE].Normal.Z = mat[11] + mat[8]; + planes[VF_LEFT_PLANE].D = mat[15] + mat[12]; + + // right clipping plane + planes[VF_RIGHT_PLANE].Normal.X = mat[3 ] - mat[0]; + planes[VF_RIGHT_PLANE].Normal.Y = mat[7 ] - mat[4]; + planes[VF_RIGHT_PLANE].Normal.Z = mat[11] - mat[8]; + planes[VF_RIGHT_PLANE].D = mat[15] - mat[12]; + + // top clipping plane + planes[VF_TOP_PLANE].Normal.X = mat[3 ] - mat[1]; + planes[VF_TOP_PLANE].Normal.Y = mat[7 ] - mat[5]; + planes[VF_TOP_PLANE].Normal.Z = mat[11] - mat[9]; + planes[VF_TOP_PLANE].D = mat[15] - mat[13]; + + // bottom clipping plane + planes[VF_BOTTOM_PLANE].Normal.X = mat[3 ] + mat[1]; + planes[VF_BOTTOM_PLANE].Normal.Y = mat[7 ] + mat[5]; + planes[VF_BOTTOM_PLANE].Normal.Z = mat[11] + mat[9]; + planes[VF_BOTTOM_PLANE].D = mat[15] + mat[13]; + + // far clipping plane + planes[VF_FAR_PLANE].Normal.X = mat[3 ] - mat[2]; + planes[VF_FAR_PLANE].Normal.Y = mat[7 ] - mat[6]; + planes[VF_FAR_PLANE].Normal.Z = mat[11] - mat[10]; + planes[VF_FAR_PLANE].D = mat[15] - mat[14]; + + // near clipping plane + planes[VF_NEAR_PLANE].Normal.X = mat[2]; + planes[VF_NEAR_PLANE].Normal.Y = mat[6]; + planes[VF_NEAR_PLANE].Normal.Z = mat[10]; + planes[VF_NEAR_PLANE].D = mat[14]; + + // normalize normals + u32 i; + for ( i=0; i != VF_PLANE_COUNT; ++i) + { + const f32 len = - core::reciprocal_squareroot ( planes[i].Normal.getLengthSQ() ); + planes[i].Normal *= len; + planes[i].D *= len; + } + + // make bounding box + recalculateBoundingBox(); + } + + inline void SViewFrustum::setTransformState( video::E_TRANSFORMATION_STATE state) + { + switch ( state ) + { + case video::ETS_VIEW: + Matrices[ETS_VIEW_PROJECTION_3].setbyproduct_nocheck ( Matrices[ video::ETS_PROJECTION], + Matrices[ video::ETS_VIEW] + ); + Matrices[ETS_VIEW_MODEL_INVERSE_3] = Matrices[ video::ETS_VIEW]; + Matrices[ETS_VIEW_MODEL_INVERSE_3].makeInverse(); + break; + + case video::ETS_WORLD: + Matrices[ETS_CURRENT_3].setbyproduct ( Matrices[ ETS_VIEW_PROJECTION_3 ], + Matrices[ video::ETS_WORLD] ); + break; + default: + break; + } + } + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/SceneParameters.h b/src/dep/include/irrlicht/SceneParameters.h new file mode 100644 index 0000000..34b7b61 --- /dev/null +++ b/src/dep/include/irrlicht/SceneParameters.h @@ -0,0 +1,114 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_PARAMETERS_H_INCLUDED__ +#define __I_SCENE_PARAMETERS_H_INCLUDED__ + +/*! \file SceneParameters.h + \brief Header file containing all scene parameters for modifying mesh loading etc. + + This file includes all parameter names which can be set using ISceneManager::getParameters() + to modify the behaviour of plugins and mesh loaders. +*/ + +namespace irr +{ +namespace scene +{ + //! Name of the parameter for changing the texture path of the built-in csm loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute( + scene::CSM_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const CSM_TEXTURE_PATH = "CSM_TexturePath"; + + //! Name of the parameter for changing the texture path of the built-in lmts loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute( + scene::LMTS_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const LMTS_TEXTURE_PATH = "LMTS_TexturePath"; + + //! Name of the parameter for changing the texture path of the built-in my3d loader. + /** Use it like this: + \code + SceneManager->getParameters()->setAttribute( + scene::MY3D_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const MY3D_TEXTURE_PATH = "MY3D_TexturePath"; + + //! Name of the parameter specifying the COLLADA mesh loading mode + /** + Specifies if the COLLADA loader should create instances of the models, lights and + cameras when loading COLLADA meshes. By default, this is set to false. If this is + set to true, the ISceneManager::getMesh() method will only return a pointer to a + dummy mesh and create instances of all meshes and lights and cameras in the collada + file by itself. Example: + \code + SceneManager->getParameters()->setAttribute( + scene::COLLADA_CREATE_SCENE_INSTANCES, true); + \endcode + */ + const c8* const COLLADA_CREATE_SCENE_INSTANCES = "COLLADA_CreateSceneInstances"; + + //! Name of the parameter for changing the texture path of the built-in DMF loader. + /** Use it like this: + \code + SceneManager->getStringParameters()->setAttribute( + scene::DMF_TEXTURE_PATH, "path/to/your/textures"); + \endcode + **/ + const c8* const DMF_TEXTURE_PATH = "DMF_TexturePath"; + + //! Name of the parameter for preserving DMF textures dir structure with built-in DMF loader. + /** Use it like this: + \code + //this way you won't use this setting + SceneManager->getParameters()->setAttribute( + scene::DMF_USE_MATERIALS_DIRS, false); + \endcode + \code + //this way you'll use this setting + SceneManager->getParameters()->setAttribute( + scene::DMF_USE_MATERIALS_DIRS, true); + \endcode + **/ + const c8* const DMF_USE_MATERIALS_DIRS = "DMF_MaterialsDir"; + + //! Name of the parameter for setting reference value of alpha in transparent materials. + /** Use it like this: + \code + //this way you'll set alpha ref to 0.1 + SceneManager->getParameters()->setAttribute( + scene::DMF_ALPHA_CHANNEL_REF, 0.1); + \endcode + **/ + const c8* const DMF_ALPHA_CHANNEL_REF = "DMF_AlphaRef"; + + //! Name of the parameter for choose to flip or not tga files. + /** Use it like this: + \code + //this way you'll choose to flip alpha textures + SceneManager->()->setAttribute( + scene::DMF_FLIP_ALPHA_TEXTURES, true); + \endcode + **/ + const c8* const DMF_FLIP_ALPHA_TEXTURES = "DMF_FlipAlpha"; + + + //! Flag set as parameter when the scene manager is used as editor + /** In this way special animators like deletion animators can be stopped from + deleting scene nodes for example */ + const c8* const IRR_SCENE_MANAGER_IS_EDITOR = "IRR_Editor"; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/aabbox3d.h b/src/dep/include/irrlicht/aabbox3d.h new file mode 100644 index 0000000..2827bad --- /dev/null +++ b/src/dep/include/irrlicht/aabbox3d.h @@ -0,0 +1,292 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_AABBOX_3D_H_INCLUDED__ +#define __IRR_AABBOX_3D_H_INCLUDED__ + +#include "irrMath.h" +#include "plane3d.h" +#include "line3d.h" + +namespace irr +{ +namespace core +{ + +//! Axis aligned bounding box in 3d dimensional space. +/** Has some useful methods used with occlusion culling or clipping. +*/ +template +class aabbox3d +{ + public: + + // Constructors + + aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {} + aabbox3d(const vector3d& min, const vector3d& max): MinEdge(min), MaxEdge(max) {} + aabbox3d(const vector3d& init): MinEdge(init), MaxEdge(init) {} + aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {} + + // operators + + inline bool operator==(const aabbox3d& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}; + inline bool operator!=(const aabbox3d& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}; + + // functions + + //! Adds a point to the bounding box, causing it to grow bigger, + //! if point is outside of the box + //! \param p: Point to add into the box. + void addInternalPoint(const vector3d& p) + { + addInternalPoint(p.X, p.Y, p.Z); + } + + //! Adds an other bounding box to the bounding box, causing it to grow bigger, + //! if the box is outside of the box + //! \param b: Other bounding box to add into this box. + void addInternalBox(const aabbox3d& b) + { + addInternalPoint(b.MaxEdge); + addInternalPoint(b.MinEdge); + } + + //! Resets the bounding box. + void reset(T x, T y, T z) + { + MaxEdge.set(x,y,z); + MinEdge = MaxEdge; + } + + //! Resets the bounding box. + void reset(const aabbox3d& initValue) + { + *this = initValue; + } + + //! Resets the bounding box. + void reset(const vector3d& initValue) + { + MaxEdge = initValue; + MinEdge = initValue; + } + + //! Adds a point to the bounding box, causing it to grow bigger, + //! if point is outside of the box. + //! \param x: X Coordinate of the point to add to this box. + //! \param y: Y Coordinate of the point to add to this box. + //! \param z: Z Coordinate of the point to add to this box. + void addInternalPoint(T x, T y, T z) + { + if (x>MaxEdge.X) MaxEdge.X = x; + if (y>MaxEdge.Y) MaxEdge.Y = y; + if (z>MaxEdge.Z) MaxEdge.Z = z; + + if (x& p) const + { + return (p.X >= MinEdge.X && p.X <= MaxEdge.X && + p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && + p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z); + }; + + //! Determinates if a point is within this box and its borders. + //! \param p: Point to check. + //! \return Returns true if the point is withing the box, and false if it is not. + bool isPointTotalInside(const vector3d& p) const + { + return (p.X > MinEdge.X && p.X < MaxEdge.X && + p.Y > MinEdge.Y && p.Y < MaxEdge.Y && + p.Z > MinEdge.Z && p.Z < MaxEdge.Z); + }; + + //! Determinates if the box intersects with an other box. + //! \param other: Other box to check a intersection with. + //! \return Returns true if there is a intersection with the other box, + //! otherwise false. + bool intersectsWithBox(const aabbox3d& other) const + { + return (MinEdge <= other.MaxEdge && MaxEdge >= other.MinEdge); + } + + //! Returns if this box is completely inside the 'other' box. + bool isFullInside(const aabbox3d& other) const + { + return MinEdge >= other.MinEdge && MaxEdge <= other.MaxEdge; + } + + //! Tests if the box intersects with a line + //! \param line: Line to test intersection with. + //! \return Returns true if there is an intersection and false if not. + bool intersectsWithLine(const line3d& line) const + { + return intersectsWithLine(line.getMiddle(), line.getVector().normalize(), + (T)(line.getLength() * 0.5)); + } + + //! Tests if the box intersects with a line + //! \return Returns true if there is an intersection and false if not. + bool intersectsWithLine(const vector3d& linemiddle, + const vector3d& linevect, + T halflength) const + { + const vector3d e = getExtent() * (T)0.5; + const vector3d t = getCenter() - linemiddle; + + if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) || + (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) || + (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) ) + return false; + + T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y); + if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r ) + return false; + + r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X); + if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r ) + return false; + + r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X); + if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r) + return false; + + return true; + } + + //! Classifies a relation with a plane. + //! \param plane: Plane to classify relation to. + //! \return Returns ISREL3D_FRONT if the box is in front of the plane, + //! ISREL3D_BACK if the box is behind the plane, and + //! ISREL3D_CLIPPED if it is on both sides of the plane. + EIntersectionRelation3D classifyPlaneRelation(const plane3d& plane) const + { + vector3d nearPoint(MaxEdge); + vector3d farPoint(MinEdge); + + if (plane.Normal.X > (T)0) + { + nearPoint.X = MinEdge.X; + farPoint.X = MaxEdge.X; + } + + if (plane.Normal.Y > (T)0) + { + nearPoint.Y = MinEdge.Y; + farPoint.Y = MaxEdge.Y; + } + + if (plane.Normal.Z > (T)0) + { + nearPoint.Z = MinEdge.Z; + farPoint.Z = MaxEdge.Z; + } + + if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0) + return ISREL3D_FRONT; + + if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0) + return ISREL3D_CLIPPED; + + return ISREL3D_BACK; + } + + + //! returns center of the bounding box + vector3d getCenter() const + { + return (MinEdge + MaxEdge) / 2; + } + + //! returns extend of the box + vector3d getExtent() const + { + return MaxEdge - MinEdge; + } + + + //! stores all 8 edges of the box into a array + //! \param edges: Pointer to array of 8 edges + void getEdges(vector3d *edges) const + { + const core::vector3d middle = getCenter(); + const core::vector3d diag = middle - MaxEdge; + + /* + Edges are stored in this way: + Hey, am I an ascii artist, or what? :) niko. + /3--------/7 + / | / | + / | / | + 1---------5 | + | 2- - -| -6 + | / | / + |/ | / + 0---------4/ + */ + + edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z); + edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z); + edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z); + edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z); + edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z); + edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z); + edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z); + edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z); + } + + + //! returns if the box is empty, which means that there is + //! no space within the min and the max edge. + bool isEmpty() const + { + return MinEdge.equals ( MaxEdge ); + } + + //! repairs the box, if for example MinEdge and MaxEdge are swapped. + void repair() + { + T t; + + if (MinEdge.X > MaxEdge.X) + { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; } + if (MinEdge.Y > MaxEdge.Y) + { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; } + if (MinEdge.Z > MaxEdge.Z) + { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; } + } + + //! Calculates a new interpolated bounding box. + //! \param other: other box to interpolate between + //! \param d: value between 0.0f and 1.0f. + aabbox3d getInterpolated(const aabbox3d& other, f32 d) const + { + f32 inv = 1.0f - d; + return aabbox3d((other.MinEdge*inv) + (MinEdge*d), + (other.MaxEdge*inv) + (MaxEdge*d)); + } + + // member variables + + vector3d MinEdge; + vector3d MaxEdge; +}; + + //! Typedef for a f32 3d bounding box. + typedef aabbox3d aabbox3df; + //! Typedef for an integer 3d bounding box. + typedef aabbox3d aabbox3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/coreutil.h b/src/dep/include/irrlicht/coreutil.h new file mode 100644 index 0000000..97fd6c2 --- /dev/null +++ b/src/dep/include/irrlicht/coreutil.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_CORE_UTIL_H_INCLUDED__ +#define __IRR_CORE_UTIL_H_INCLUDED__ + +#include "irrString.h" + +namespace irr +{ +namespace core +{ + +/*! \file irrxml.h + \brief File containing useful basic utility functions +*/ + +// ----------- some basic quite often used string functions ----------------- + +//! cut the filename extension from a string +inline stringc& cutFilenameExtension ( stringc &dest, const stringc &source ) +{ + s32 endPos = source.findLast ( '.' ); + dest = source.subString ( 0, endPos < 0 ? source.size () : endPos ); + return dest; +} + +//! get the filename extension from a string +inline stringc& getFileNameExtension ( stringc &dest, const stringc &source ) +{ + s32 endPos = source.findLast ( '.' ); + if ( endPos < 0 ) + dest = ""; + else + dest = source.subString ( endPos, source.size () ); + return dest; +} + +//! some standard function ( to remove dependencies ) +#undef isdigit +#undef isspace +#undef isupper +inline s32 isdigit(s32 c) { return c >= '0' && c <= '9'; } +inline s32 isspace(s32 c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } +inline s32 isupper(s32 c) { return c >= 'A' && c <= 'Z'; } + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/dimension2d.h b/src/dep/include/irrlicht/dimension2d.h new file mode 100644 index 0000000..977685c --- /dev/null +++ b/src/dep/include/irrlicht/dimension2d.h @@ -0,0 +1,78 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_DIMENSION2D_H_INCLUDED__ +#define __IRR_DIMENSION2D_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + + //! Specifies a 2 dimensional size. + template + class dimension2d + { + public: + dimension2d() : Width(0), Height(0) {} + + dimension2d(const T& width, const T& height) + : Width(width), Height(height) {} + + bool operator == (const dimension2d& other) const + { + return Width == other.Width && Height == other.Height; + } + + bool operator != (const dimension2d& other) const + { + return ! (*this == other); + } + + dimension2d& set(const T& width, const T& height) + { + Width = width; + Height = height; + return *this; + } + + dimension2d& operator/=(const T& scale) + { + Width /= scale; + Height /= scale; + return *this; + } + + dimension2d operator/(const T& scale) const + { + return dimension2d(Width/scale, Height/scale); + } + + dimension2d& operator*=(const T& scale) + { + Width *= scale; + Height *= scale; + return *this; + } + + dimension2d operator*(const T& scale) const + { + return dimension2d(Width*scale, Height*scale); + } + + T Width, Height; + }; + + //! Typedef for a f32 dimension. + typedef dimension2d dimension2df; + //! Typedef for an integer dimension. + typedef dimension2d dimension2di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/fast_atof.h b/src/dep/include/irrlicht/fast_atof.h new file mode 100644 index 0000000..ff1977b --- /dev/null +++ b/src/dep/include/irrlicht/fast_atof.h @@ -0,0 +1,116 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __FAST_A_TO_F_H_INCLUDED__ +#define __FAST_A_TO_F_H_INCLUDED__ + +#include +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + +const float fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug + 0.f, + 0.1f, + 0.01f, + 0.001f, + 0.0001f, + 0.00001f, + 0.000001f, + 0.0000001f, + 0.00000001f, + 0.000000001f, + 0.0000000001f, + 0.00000000001f, + 0.000000000001f, + 0.0000000000001f, + 0.00000000000001f, + 0.000000000000001f +}; + +inline u32 strtol10(const char* in, const char** out=0) +{ + u32 value = 0; + + while ( 1 ) + { + if ( *in < '0' || *in > '9' ) + break; + + value = ( value * 10 ) + ( *in - '0' ); + ++in; + } + if (out) + *out = in; + return value; +} + +//! Provides a fast function for converting a string into a float, +//! about 6 times faster than atof in win32. +// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. +inline const char* fast_atof_move( const char* c, float& out) +{ + bool inv = false; + const char *t; + float f; + + if (*c=='-') + { + ++c; + inv = true; + } + + //f = (float)strtol(c, &t, 10); + f = (float) strtol10 ( c, &c ); + + if (*c == '.') + { + ++c; + + //float pl = (float)strtol(c, &t, 10); + float pl = (float) strtol10 ( c, &t ); + pl *= fast_atof_table[t-c]; + + f += pl; + + c = t; + + if (*c == 'e') + { + ++c; + //float exp = (float)strtol(c, &t, 10); + bool einv = (*c=='-'); + if (einv) + ++c; + + float exp = (float)strtol10(c, &c); + if (einv) + exp *= -1.0f; + + f *= (float)pow(10.0f, exp); + } + } + + if (inv) + f *= -1.0f; + + out = f; + return c; +} + +inline float fast_atof(const char* c) +{ + float ret; + fast_atof_move(c, ret); + return ret; +} + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/heapsort.h b/src/dep/include/irrlicht/heapsort.h new file mode 100644 index 0000000..b346364 --- /dev/null +++ b/src/dep/include/irrlicht/heapsort.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_HEAPSORT_H_INCLUDED__ +#define __IRR_HEAPSORT_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! Sinks an element into the heap. +template +inline void heapsink(T*array, s32 element, s32 max) +{ + while ((element<<1) < max) // there is a left child + { + s32 j = (element<<1); + + if (j+1 < max && array[j] < array[j+1]) + j = j+1; // take right child + + if (array[element] < array[j]) + { + T t = array[j]; // swap elements + array[j] = array[element]; + array[element] = t; + element = j; + } + else + return; + } +} + + +//! Sorts an array with size 'size' using heapsort. +template +inline void heapsort(T* array_, s32 size) +{ + // for heapsink we pretent this is not c++, where + // arrays start with index 0. So we decrease the array pointer, + // the maximum always +2 and the element always +1 + + T* virtualArray = array_ - 1; + s32 virtualSize = size + 2; + s32 i; + + // build heap + + for (i=((size-1)/2); i>=0; --i) + heapsink(virtualArray, i+1, virtualSize-1); + + // sort array + + for (i=size-1; i>=0; --i) + { + T t = array_[0]; + array_[0] = array_[i]; + array_[i] = t; + heapsink(virtualArray, 1, i + 1); + } +} + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/irrAllocator.h b/src/dep/include/irrlicht/irrAllocator.h new file mode 100644 index 0000000..9c12f6c --- /dev/null +++ b/src/dep/include/irrlicht/irrAllocator.h @@ -0,0 +1,116 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_ALLOCATOR_H_INCLUDED__ +#define __IRR_ALLOCATOR_H_INCLUDED__ + +#include "irrTypes.h" +#include +#include + +namespace irr +{ +namespace core +{ + +#ifdef DEBUG_CLIENTBLOCK +#undef DEBUG_CLIENTBLOCK +#define DEBUG_CLIENTBLOCK new +#endif + +//! Very simple allocator implementation, containers using it are able to +//! be used it across dll boundaries +template +class irrAllocator +{ +public: + + //! destructor + virtual ~irrAllocator() {} + + //! allocate memory for an array of objects + T* allocate(size_t cnt) + { + return (T*)internal_new(cnt* sizeof(T)); + } + + //! deallocate memory for an array of objects + void deallocate(T* ptr) + { + internal_delete(ptr); + } + + //! construct an element + void construct(T* ptr, const T&e) + { + new ((void*)ptr) T(e); + } + + //! destruct an element + void destruct(T* ptr) + { + ptr->~T(); + } + +protected: + + virtual void* internal_new(size_t cnt) + { + return operator new(cnt); + } + + virtual void internal_delete(void* ptr) + { + operator delete(ptr); + } + +}; + + +//! fast allocator, only to be used in containers inside the same memory heap. +/** Containers using it are NOT able to be used it across dll boundaries. Use this +when using in an internal class or function or when compiled into a static lib */ +template +class irrAllocatorFast +{ +public: + + //! allocate memory for an array of objects + T* allocate(size_t cnt) + { + return (T*)operator new(cnt* sizeof(T)); + } + + //! deallocate memory for an array of objects + void deallocate(T* ptr) + { + operator delete(ptr); + } + + //! construct an element + void construct(T* ptr, const T&e) + { + new ((void*)ptr) T(e); + } + + //! destruct an element + void destruct(T* ptr) + { + ptr->~T(); + } +}; + + + +#ifdef DEBUG_CLIENTBLOCK +#undef DEBUG_CLIENTBLOCK +#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) +#endif + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/irrArray.h b/src/dep/include/irrlicht/irrArray.h new file mode 100644 index 0000000..01d8117 --- /dev/null +++ b/src/dep/include/irrlicht/irrArray.h @@ -0,0 +1,521 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_ARRAY_H_INCLUDED__ +#define __IRR_ARRAY_H_INCLUDED__ + +#include "irrTypes.h" +#include "heapsort.h" +#include "irrAllocator.h" + +namespace irr +{ +namespace core +{ + +//! Self reallocating template array (like stl vector) with additional features. +/** Some features are: Heap sorting, binary search methods, easier debugging. +*/ +template > +class array +{ + +public: + + array() + : data(0), allocated(0), used(0), + free_when_destroyed(true), is_sorted(true) + { + } + + //! Constructs a array and allocates an initial chunk of memory. + //! \param start_count: Amount of elements to allocate. + array(u32 start_count) + : data(0), allocated(0), used(0), + free_when_destroyed(true), is_sorted(true) + { + reallocate(start_count); + } + + + //! Copy constructor + array(const array& other) + : data(0) + { + *this = other; + } + + + + //! Destructor. Frees allocated memory, if set_free_when_destroyed + //! was not set to false by the user before. + ~array() + { + if (free_when_destroyed) + { + for (u32 i=0; i allocated) + { + // reallocate(used * 2 +1); + // this doesn't work if the element is in the same array. So + // we'll copy the element first to be sure we'll get no data + // corruption + + T e(element); + reallocate(used * 2 +1); // increase data block + + allocator.construct(&data[used++], e); // data[used++] = e; // push_back + } + else + { + //data[used++] = element; + // instead of using this here, we copy it the safe way: + allocator.construct(&data[used++], element); + } + + is_sorted = false; + } + + + //! Adds an element at the front of the array. If the array is to small to + //! add this new element, the array is made bigger. Please note that this + //! is slow, because the whole array needs to be copied for this. + //! \param element: Element to add at the back of the array. + void push_front(const T& element) + { + if (used + 1 > allocated) + reallocate(used +1); + + for (u32 i=used; i>0; --i) + { + //data[i] = data[i-1]; + allocator.construct(&data[i], data[i-1]); + } + + // data[0] = element; + allocator.construct(&data[0], element); + + is_sorted = false; + ++used; + } + + + //! Insert item into array at specified position. Please use this + //! only if you know what you are doing (possible performance loss). + //! The preferred method of adding elements should be push_back(). + //! \param element: Element to be inserted + //! \param index: Where position to insert the new element. + void insert(const T& element, u32 index=0) + { + _IRR_DEBUG_BREAK_IF(index>used) // access violation + + if (used + 1 > allocated) + reallocate(used +1); + + for (u32 i=used++; i>index; --i) + allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1]; + + allocator.construct(&data[index], element); // data[index] = element; + is_sorted = false; + } + + + + + //! Clears the array and deletes all allocated memory. + void clear() + { + for (u32 i=0; i& other) + { + if (data) + { + for (u32 i=0; i& other) const + { + if (used != other.used) + return false; + + for (u32 i=0; i& other) const + { + return !(*this==other); + } + + //! Direct access operator + T& operator [](u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + + + //! Direct access operator + const T& operator [](u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + //! Gets last frame + T& getLast() + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + + //! Gets last frame + const T& getLast() const + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + //! Returns a pointer to the array. + //! \return Pointer to the array. + T* pointer() + { + return data; + } + + + + //! Returns a const pointer to the array. + //! \return Pointer to the array. + const T* const_pointer() const + { + return data; + } + + + + //! Returns size of used array. + //! \return Size of elements in the array. + u32 size() const + { + return used; + } + + + + //! Returns amount memory allocated. + //! \return Returns amount of memory allocated. The amount of bytes + //! allocated would be allocated_size() * sizeof(ElementsUsed); + u32 allocated_size() const + { + return allocated; + } + + + + //! Returns true if array is empty + //! \return True if the array is empty, false if not. + bool empty() const + { + return used == 0; + } + + + + //! Sorts the array using heapsort. There is no additional memory waste and + //! the algorithm performs O(n*log n) in worst case. + void sort() + { + if (is_sorted || used<2) + return; + + heapsort(data, used); + is_sorted = true; + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! The array will be sorted before the binary search if it is not + //! already sorted. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element) + { + sort(); + return binary_search(element, 0, used-1); + } + + //! Performs a binary search for an element, returns -1 if not found. + //! The array must be sorted prior + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search_const(const T& element) const + { + return binary_search(element, 0, used-1); + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! \param element: Element to search for. + //! \param left: First left index + //! \param right: Last right index. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element, s32 left, s32 right) const + { + if (!used) + return -1; + + s32 m; + + do + { + m = (left+right)>>1; + + if (element < data[m]) + right = m - 1; + else + left = m + 1; + + } while((element < data[m] || data[m] < element) && left<=right); + + // this last line equals to: + // " while((element != array[m]) && left<=right);" + // but we only want to use the '<' operator. + // the same in next line, it is "(element == array[m])" + + if (!(element < data[m]) && !(data[m] < element)) + return m; + + return -1; + } + + + //! Finds an element in linear time, which is very slow. Use + //! binary_search for faster finding. Only works if ==operator is implemented. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 linear_search(const T& element) const + { + for (u32 i=0; i=0; --i) + if (data[i] == element) + return i; + + return -1; + } + + + + //! Erases an element from the array. May be slow, because all elements + //! following after the erased element have to be copied. + //! \param index: Index of element to be erased. + void erase(u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + for (u32 i=index+1; i=used || count<1 || index+count>used) // access violation + + u32 i; + for (i=index; i index+count) + allocator.destruct(&data[i-count]); + + allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i]; + + if (i >= used-count) + allocator.destruct(&data[i]); + } + + used-= count; + } + + + //! Sets if the array is sorted + void set_sorted(bool _is_sorted) + { + is_sorted = _is_sorted; + } + + + private: + + T* data; + u32 allocated; + u32 used; + bool free_when_destroyed; + bool is_sorted; + TAlloc allocator; +}; + + +} // end namespace core +} // end namespace irr + + +#endif + diff --git a/src/dep/include/irrlicht/irrList.h b/src/dep/include/irrlicht/irrList.h new file mode 100644 index 0000000..cc85c06 --- /dev/null +++ b/src/dep/include/irrlicht/irrList.h @@ -0,0 +1,392 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LIST_H_INCLUDED__ +#define __IRR_LIST_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + + +//! Double linked list template. +template +class list +{ +private: + + //! List element node with pointer to previous and next element in the list. + struct SKListNode + { + SKListNode() : Next(0), Prev(0) {}; + + SKListNode* Next; + SKListNode* Prev; + T Element; + }; + +public: + class ConstIterator; + + //! List iterator. + class Iterator + { + public: + Iterator() : Current(0) {} + + Iterator& operator ++() { Current = Current->Next; return *this; } + Iterator& operator --() { Current = Current->Prev; return *this; } + Iterator operator ++(s32) { Iterator tmp = *this; Current = Current->Next; return tmp; } + Iterator operator --(s32) { Iterator tmp = *this; Current = Current->Prev; return tmp; } + + Iterator& operator +=(s32 num) + { + if(num > 0) + { + while (num-- && this->Current != 0) ++(*this); + } + else + { + while(num++ && this->Current != 0) --(*this); + } + return *this; + } + + Iterator operator + (s32 num) const { Iterator tmp = *this; return tmp += num; } + Iterator& operator -=(s32 num) const { return (*this)+=(-num); } + Iterator operator - (s32 num) const { return (*this)+ (-num); } + + bool operator ==(const Iterator& other) const { return Current == other.Current; } + bool operator !=(const Iterator& other) const { return Current != other.Current; } + bool operator ==(const ConstIterator& other) const { return Current == other.Current; } + bool operator !=(const ConstIterator& other) const { return Current != other.Current; } + + #if defined (_MSC_VER) && (_MSC_VER < 1300) + #pragma warning(disable:4284) // infix notation problem when using iterator operator -> + #endif + + T & operator * () { return Current->Element; } + T * operator ->() { return &Current->Element; } + + private: + Iterator(SKListNode* begin) : Current(begin) {} + + SKListNode* Current; + + friend class list; + }; + + class ConstIterator + { + public: + + ConstIterator() : Current(0) {} + + ConstIterator& operator ++() { Current = Current->Next; return *this; } + ConstIterator& operator --() { Current = Current->Prev; return *this; } + ConstIterator operator ++(s32) { ConstIterator tmp = *this; Current = Current->Next; return tmp; } + ConstIterator operator --(s32) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; } + + ConstIterator& operator +=(s32 num) + { + if(num > 0) + { + while(num-- && this->Current != 0) ++(*this); + } + else + { + while(num++ && this->Current != 0) --(*this); + } + return *this; + } + + ConstIterator operator + (s32 num) const { ConstIterator tmp = *this; return tmp += num; } + ConstIterator& operator -=(s32 num) const { return (*this)+=(-num); } + ConstIterator operator - (s32 num) const { return (*this)+ (-num); } + + bool operator ==(const ConstIterator& other) const { return Current == other.Current; } + bool operator !=(const ConstIterator& other) const { return Current != other.Current; } + bool operator ==(const Iterator& other) const { return Current == other.Current; } + bool operator !=(const Iterator& other) const { return Current != other.Current; } + + const T & operator * () { return Current->Element; } + const T * operator ->() { return &Current->Element; } + + ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; } + + private: + ConstIterator(SKListNode* begin) : Current(begin) {} + + SKListNode* Current; + + friend class Iterator; + friend class list; + }; + + //! constructor + list() + : First(0), Last(0), Size(0) {} + + + //! copy constructor + list(const list& other) : First(0), Last(0), Size(0) + { + *this = other; + } + + + //! destructor + ~list() + { + clear(); + } + + + //! Assignment operator + void operator=(const list& other) + { + if(&other == this) + { + return; + } + + clear(); + + SKListNode* node = other.First; + while(node) + { + push_back(node->Element); + node = node->Next; + } + } + + + + //! Returns amount of elements in list. + //! \return Returns amount of elements in the list. + u32 getSize() const + { + return Size; + } + + + + //! Clears the list, deletes all elements in the list. All existing + //! iterators of this list will be invalid. + void clear() + { + while(First) + { + SKListNode * next = First->Next; + delete First; + First = next; + } + + //First = 0; handled by loop + Last = 0; + Size = 0; + } + + + + //! Returns ture if the list is empty. + //! \return Returns true if the list is empty and false if not. + bool empty() const + { + return (First == 0); + } + + + + //! Adds an element at the end of the list. + //! \param element: Element to add to the list. + void push_back(const T& element) + { + SKListNode* node = new SKListNode; + node->Element = element; + + ++Size; + + if (First == 0) + First = node; + + node->Prev = Last; + + if (Last != 0) + Last->Next = node; + + Last = node; + } + + + //! Adds an element at the begin of the list. + //! \param element: Element to add to the list. + void push_front(const T& element) + { + SKListNode* node = new SKListNode; + node->Element = element; + + ++Size; + + if (First == 0) + { + Last = node; + First = node; + } + else + { + node->Next = First; + First->Prev = node; + First = node; + } + } + + + //! Gets begin node. + //! \return Returns a list iterator pointing to the begin of the list. + Iterator begin() + { + return Iterator(First); + } + + + //! Gets begin node. + //! \return Returns a list iterator pointing to the begin of the list. + ConstIterator begin() const + { + return ConstIterator(First); + } + + + //! Gets end node. + //! \return Returns a list iterator pointing to null. + Iterator end() + { + return Iterator(0); + } + + + //! Gets end node. + //! \return Returns a list iterator pointing to null. + ConstIterator end() const + { + return ConstIterator(0); + } + + + //! Gets last element. + //! \return Returns a list iterator pointing to the end of the list. + Iterator getLast() + { + return Iterator(Last); + } + + + //! Gets last element. + //! \return Returns a list iterator pointing to the end of the list. + ConstIterator getLast() const + { + return ConstIterator(Last); + } + + + //! Inserts an element after an element. + //! \param it: Iterator pointing to element after which the new element + //! should be inserted. + //! \param element: The new element to be inserted into the list. + void insert_after(const Iterator& it, const T& element) + { + SKListNode* node = new SKListNode; + node->Element = element; + + node->Next = it.Current->Next; + + if (it.Current->Next) + it.Current->Next->Prev = node; + + node->Prev = it.Current; + it.Current->Next = node; + ++Size; + + if (it.Current == Last) + Last = node; + } + + + //! Inserts an element before an element. + //! \param it: Iterator pointing to element before which the new element + //! should be inserted. + //! \param element: The new element to be inserted into the list. + void insert_before(const Iterator& it, const T& element) + { + SKListNode* node = new SKListNode; + node->Element = element; + + node->Prev = it.Current->Prev; + + if (it.Current->Prev) + it.Current->Prev->Next = node; + + node->Next = it.Current; + it.Current->Prev = node; + ++Size; + + if (it.Current == First) + First = node; + } + + + //! Erases an element + //! \param it: Iterator pointing to the element which shall be erased. + //! \return Returns iterator pointing to next element. + Iterator erase(Iterator& it) + { + // suggest changing this to a const Iterator& and + // working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?) + + Iterator returnIterator(it); + ++returnIterator; + + if(it.Current == First) + { + First = it.Current->Next; + } + else + { + it.Current->Prev->Next = it.Current->Next; + } + + if(it.Current == Last) + { + Last = it.Current->Prev; + } + else + { + it.Current->Next->Prev = it.Current->Prev; + } + + delete it.Current; + it.Current = 0; + --Size; + + return returnIterator; + } + +private: + + SKListNode* First; + SKListNode* Last; + u32 Size; + +}; + + +} // end namespace core +}// end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/irrMap.h b/src/dep/include/irrlicht/irrMap.h new file mode 100644 index 0000000..98279fd --- /dev/null +++ b/src/dep/include/irrlicht/irrMap.h @@ -0,0 +1,946 @@ +// Copyright 2006-2007 by Kat'Oun +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MAP_H_INCLUDED__ +#define __IRR_MAP_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! map template for associative arrays using a red-black tree +template +class map +{ + //! red/black tree for map + template + class RBTree + { + public: + + RBTree(const KeyTypeRB& k, const ValueTypeRB& v) + : LeftChild(0), RightChild(0), Parent(0), Key(k), + Value(v), IsRed(true) {} + + ~RBTree() {} + + void setLeftChild(RBTree* p) + { + LeftChild=p; + if (p) + p->setParent(this); + } + + void setRightChild(RBTree* p) + { + RightChild=p; + if (p) + p->setParent(this); + } + + void setParent(RBTree* p) { Parent=p; } + + void setValue(const ValueTypeRB& v) { Value = v; } + + void setRed() { IsRed = true; } + void setBlack() { IsRed = false; } + + RBTree* getLeftChild() const { return LeftChild; } + RBTree* getRightChild() const { return RightChild; } + RBTree* getParent() const { return Parent; } + + ValueTypeRB getValue() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Value; + } + + KeyTypeRB getKey() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Key; + } + + bool isRoot() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Parent==0; + } + + bool isLeftChild() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (Parent != 0) && (Parent->getLeftChild()==this); + } + + bool isRightChild() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (Parent!=0) && (Parent->getRightChild()==this); + } + + bool isLeaf() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (LeftChild==0) && (RightChild==0); + } + + unsigned int getLevel() const + { + if (isRoot()) + return 1; + else + return getParent()->getLevel() + 1; + } + + + bool isRed() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsRed; + } + + bool isBlack() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return !IsRed; + } + + private: + RBTree(); + + RBTree* LeftChild; + RBTree* RightChild; + + RBTree* Parent; + + KeyTypeRB Key; + ValueTypeRB Value; + + bool IsRed; + }; + + public: + + typedef RBTree Node; + + //! Normal Iterator + class Iterator + { + public: + + Iterator() : Root(0), Cur(0) {} + + // Constructor(Node*) + Iterator(Node* root) : Root(root) + { + reset(); + } + + // Copy constructor + Iterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {} + + void reset(bool atLowest=true) + { + if (atLowest) + Cur = getMin(Root); + else + Cur = getMax(Root); + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() + { + return Cur; + } + + Iterator& operator=(const Iterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + void operator--(int) + { + dec(); + } + + + Node* operator -> () + { + return getNode(); + } + + Node& operator* () + { + if (atEnd()) + throw "Iterator at end"; + + return *Cur; + } + + private: + + Node* getMin(Node* n) + { + while(n && n->getLeftChild()) + n = n->getLeftChild(); + return n; + } + + Node* getMax(Node* n) + { + while(n && n->getRightChild()) + n = n->getRightChild(); + return n; + } + + void inc() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getRightChild()) + { + // If current node has a right child, the next higher node is the + // node with lowest key beneath the right child. + Cur = getMin(Cur->getRightChild()); + } + else if (Cur->isLeftChild()) + { + // No right child? Well if current node is a left child then + // the next higher node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is left child nor has a right child. + // Ie it is either right child or root + // The next higher node is the parent of the first non-right + // child (ie either a left child or the root) up in the + // hierarchy. Root's parent is 0. + while(Cur->isRightChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + void dec() + { + // Already at end? + if (Cur==0) + return; + + if (Cur->getLeftChild()) + { + // If current node has a left child, the next lower node is the + // node with highest key beneath the left child. + Cur = getMax(Cur->getLeftChild()); + } + else if (Cur->isRightChild()) + { + // No left child? Well if current node is a right child then + // the next lower node is the parent + Cur = Cur->getParent(); + } + else + { + // Current node neither is right child nor has a left child. + // Ie it is either left child or root + // The next higher node is the parent of the first non-left + // child (ie either a right child or the root) up in the + // hierarchy. Root's parent is 0. + + while(Cur->isLeftChild()) + Cur = Cur->getParent(); + Cur = Cur->getParent(); + } + } + + Node* Root; + Node* Cur; + }; // Iterator + + + + //! Parent First Iterator. + //! Traverses the tree from top to bottom. Typical usage is + //! when storing the tree structure, because when reading it + //! later (and inserting elements) the tree structure will + //! be the same. + class ParentFirstIterator + { + public: + + + ParentFirstIterator() : Root(0), Cur(0) + { + } + + + explicit ParentFirstIterator(Node* root) : Root(root), Cur(0) + { + reset(); + } + + void reset() + { + Cur = Root; + } + + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() + { + return Cur; + } + + + ParentFirstIterator& operator=(const ParentFirstIterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + + void operator++(int) + { + inc(); + } + + + Node* operator -> () + { + return getNode(); + } + + Node& operator* () + { + if (atEnd()) + throw "ParentFirstIterator at end"; + return *getNode(); + } + + private: + + void inc() + { + // Already at end? + if (Cur==0) + return; + + // First we try down to the left + if (Cur->getLeftChild()) + { + Cur = Cur->getLeftChild(); + } + else if (Cur->getRightChild()) + { + // No left child? The we go down to the right. + Cur = Cur->getRightChild(); + } + else + { + // No children? Move up in the hierarcy until + // we either reach 0 (and are finished) or + // find a right uncle. + while (Cur!=0) + { + // But if parent is left child and has a right "uncle" the parent + // has already been processed but the uncle hasn't. Move to + // the uncle. + if (Cur->isLeftChild() && Cur->getParent()->getRightChild()) + { + Cur = Cur->getParent()->getRightChild(); + return; + } + Cur = Cur->getParent(); + } + } + } + + Node* Root; + Node* Cur; + + }; // ParentFirstIterator + + + //! Parent Last Iterator + //! Traverse the tree from bottom to top. + //! Typical usage is when deleting all elements in the tree + //! because you must delete the children before you delete + //! their parent. + class ParentLastIterator + { + public: + + ParentLastIterator() : Root(0), Cur(0) {} + + explicit ParentLastIterator(Node* root) : Root(root), Cur(0) + { + reset(); + } + + void reset() + { + Cur = getMin(Root); + } + + bool atEnd() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Cur==0; + } + + Node* getNode() + { + return Cur; + } + + ParentLastIterator& operator=(const ParentLastIterator& src) + { + Root = src.Root; + Cur = src.Cur; + return (*this); + } + + void operator++(int) + { + inc(); + } + + Node* operator -> () + { + return getNode(); + } + + Node& operator* () + { + if (atEnd()) + throw "ParentLastIterator at end"; + return *getNode(); + } + private: + + Node* getMin(Node* n) + { + while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0)) + { + if (n->getLeftChild()) + n = n->getLeftChild(); + else + n = n->getRightChild(); + } + return n; + } + + void inc() + { + // Already at end? + if (Cur==0) + return; + + // Note: Starting point is the node as far down to the left as possible. + + // If current node has an uncle to the right, go to the + // node as far down to the left from the uncle as possible + // else just go up a level to the parent. + if (Cur->isLeftChild() && Cur->getParent()->getRightChild()) + { + Cur = getMin(Cur->getParent()->getRightChild()); + } + else + Cur = Cur->getParent(); + } + + + Node* Root; + Node* Cur; + }; // ParentLastIterator + + + // AccessClass is a temporary class used with the [] operator. + // It makes it possible to have different behavior in situations like: + // myTree["Foo"] = 32; + // If "Foo" already exists, just update its value else insert a new + // element. + // int i = myTree["Foo"] + // If "Foo" exists return its value, else throw an exception. + class AccessClass + { + // Let map be the only one who can instantiate this class. + friend class map; + + public: + + // Assignment operator. Handles the myTree["Foo"] = 32; situation + void operator=(const ValueType& value) + { + // Just use the Set method, it handles already exist/not exist situation + Tree.set(Key,value); + } + + // ValueType operator + operator ValueType() + { + Node* node = Tree.find(Key); + + // Not found + if (node==0) + throw "Item not found"; + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return node->getValue(); + } + + private: + + AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {} + + AccessClass(); + + map& Tree; + const KeyType& Key; + }; // AccessClass + + + // Constructor. + map() : Root(0), Size(0) {} + + // Destructor + ~map() + { + clear(); + } + + //------------------------------ + // Public Commands + //------------------------------ + + //! Inserts a new node into the tree + //! \param keyNew: the index for this value + //! \param v: the value to insert + //! \return Returns true if successful, + //! false if it fails (already exists) + bool insert(const KeyType& keyNew, const ValueType& v) + { + // First insert node the "usual" way (no fancy balance logic yet) + Node* newNode = new Node(keyNew,v); + if (!insert(newNode)) + { + delete newNode; + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // Then attend a balancing party + while (!newNode->isRoot() && (newNode->getParent()->isRed())) + { + if (newNode->getParent()->isLeftChild()) + { + // If newNode is a left child, get its right 'uncle' + Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild(); + if ( newNodesUncle!=0 && newNodesUncle->isRed()) + { + // case 1 - change the colours + newNode->getParent()->setBlack(); + newNodesUncle->setBlack(); + newNode->getParent()->getParent()->setRed(); + // Move newNode up the tree + newNode = newNode->getParent()->getParent(); + } + else + { + // newNodesUncle is a black node + if ( newNode->isRightChild()) + { + // and newNode is to the right + // case 2 - move newNode up and rotate + newNode = newNode->getParent(); + rotateLeft(newNode); + } + // case 3 + newNode->getParent()->setBlack(); + newNode->getParent()->getParent()->setRed(); + rotateRight(newNode->getParent()->getParent()); + } + } + else + { + // If newNode is a right child, get its left 'uncle' + Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild(); + if ( newNodesUncle!=0 && newNodesUncle->isRed()) + { + // case 1 - change the colours + newNode->getParent()->setBlack(); + newNodesUncle->setBlack(); + newNode->getParent()->getParent()->setRed(); + // Move newNode up the tree + newNode = newNode->getParent()->getParent(); + } + else + { + // newNodesUncle is a black node + if (newNode->isLeftChild()) + { + // and newNode is to the left + // case 2 - move newNode up and rotate + newNode = newNode->getParent(); + rotateRight(newNode); + } + // case 3 + newNode->getParent()->setBlack(); + newNode->getParent()->getParent()->setRed(); + rotateLeft(newNode->getParent()->getParent()); + } + + } + } + // Color the root black + Root->setBlack(); + return true; + } + + //! Replaces the value if the key already exists, + //! otherwise inserts a new element. + //! \param k: the index for this value + //! \param v: the new value of + void set(const KeyType& k, const ValueType& v) + { + Node* p = find(k); + if (p) + p->setValue(v); + else + insert(k,v); + } + + //! Removes a node from the tree and returns it. + //! The returned node must be deleted by the user + //! \param k: the key to remove + //! \return: A pointer to the node, or 0 if not found + Node* delink(const KeyType& k) + { + Node* p = find(k); + if (p == 0) + return 0; + + // Rotate p down to the left until it has no right child, will get there + // sooner or later. + while(p->getRightChild()) + { + // "Pull up my right child and let it knock me down to the left" + rotateLeft(p); + } + // p now has no right child but might have a left child + Node* left = p->getLeftChild(); + + // Let p's parent point to p's child instead of point to p + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + + else + { + // p has no parent => p is the root. + // Let the left child be the new root. + setRoot(left); + } + + // p is now gone from the tree in the sense that + // no one is pointing at it, so return it. + + --Size; + return p; + } + + //! Removes a node from the tree and deletes it. + //! \return True if the node was found and deleted + bool remove(const KeyType& k) + { + Node* p = find(k); + if (p == 0) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // Rotate p down to the left until it has no right child, will get there + // sooner or later. + while(p->getRightChild()) + { + // "Pull up my right child and let it knock me down to the left" + rotateLeft(p); + } + // p now has no right child but might have a left child + Node* left = p->getLeftChild(); + + // Let p's parent point to p's child instead of point to p + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + + else + { + // p has no parent => p is the root. + // Let the left child be the new root. + setRoot(left); + } + + // p is now gone from the tree in the sense that + // no one is pointing at it. Let's get rid of it. + delete p; + + --Size; + return true; + } + + //! Clear the entire tree + void clear() + { + ParentLastIterator i(getParentLastIterator()); + + while(!i.atEnd()) + { + Node* p = i.getNode(); + i++; // Increment it before it is deleted + // else iterator will get quite confused. + delete p; + } + Root = 0; + Size= 0; + } + + //! Is the tree empty? + //! \return Returns true if empty, false if not + bool isEmpty() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Root == 0; + } + + //! Search for a node with the specified key. + //! \param keyToFind: The key to find + //! \return Returns 0 if node couldn't be found. + Node* find(const KeyType& keyToFind) const + { + Node* pNode = Root; + + while(pNode!=0) + { + KeyType key(pNode->getKey()); + + if (keyToFind == key) + return pNode; + else if (keyToFind < key) + pNode = pNode->getLeftChild(); + else //keyToFind > key + pNode = pNode->getRightChild(); + } + + return 0; + } + + //! Gets the root element. + //! \return Returns a pointer to the root node, or + //! 0 if the tree is empty. + Node* getRoot() const + { + return Root; + } + + //! Returns the number of nodes in the tree. + u32 size() const + { + return Size; + } + + //------------------------------ + // Public Iterators + //------------------------------ + + //! Returns an iterator + Iterator getIterator() + { + Iterator it(getRoot()); + return it; + } + //! Returns a ParentFirstIterator. + //! Traverses the tree from top to bottom. Typical usage is + //! when storing the tree structure, because when reading it + //! later (and inserting elements) the tree structure will + //! be the same. + ParentFirstIterator getParentFirstIterator() + { + ParentFirstIterator it(getRoot()); + return it; + } + //! Returns a ParentLastIterator to traverse the tree from + //! bottom to top. + //! Typical usage is when deleting all elements in the tree + //! because you must delete the children before you delete + //! their parent. + ParentLastIterator getParentLastIterator() + { + ParentLastIterator it(getRoot()); + return it; + } + + //------------------------------ + // Public Operators + //------------------------------ + + //! operator [] for access to elements + //! for example myMap["key"] + AccessClass operator[](const KeyType& k) + { + return AccessClass(*this, k); + } + private: + + //------------------------------ + // Disabled methods + //------------------------------ + //! Copy constructor and assignment operator deliberately + //! defined but not implemented. The tree should never be + //! copied, pass along references to it instead. + explicit map(const map& src); + map& operator = (const map& src); + + void setRoot(Node* newRoot) + { + Root = newRoot; + if (Root != 0) + Root->setParent(0); + } + + //! Insert a node into the tree without using any fancy balancing logic. + //! Returns false if that key already exist in the tree. + bool insert(Node* newNode) + { + bool result=true; // Assume success + + if (Root==0) + { + setRoot(newNode); + Size = 1; + } + else + { + Node* pNode = Root; + KeyType keyNew = newNode->getKey(); + while (pNode) + { + KeyType key(pNode->getKey()); + + if (keyNew == key) + { + result = false; + pNode = 0; + } + else if (keyNew < key) + { + if (pNode->getLeftChild() == 0) + { + pNode->setLeftChild(newNode); + pNode = 0; + } + else + pNode = pNode->getLeftChild(); + } + else // keyNew > key + { + if (pNode->getRightChild()==0) + { + pNode->setRightChild(newNode); + pNode = 0; + } + else + { + pNode = pNode->getRightChild(); + } + } + } + + if (result) + ++Size; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return result; + } + + //! Rotate left. + //! Pull up node's right child and let it knock node down to the left + void rotateLeft(Node* p) + { + Node* right = p->getRightChild(); + + p->setRightChild(right->getLeftChild()); + + if (p->isLeftChild()) + p->getParent()->setLeftChild(right); + else if (p->isRightChild()) + p->getParent()->setRightChild(right); + else + setRoot(right); + + right->setLeftChild(p); + } + + //! Rotate right. + //! Pull up node's left child and let it knock node down to the right + void rotateRight(Node* p) + { + + Node* left = p->getLeftChild(); + + p->setLeftChild(left->getRightChild()); + + if (p->isLeftChild()) + p->getParent()->setLeftChild(left); + else if (p->isRightChild()) + p->getParent()->setRightChild(left); + else + setRoot(left); + + left->setRightChild(p); + } + + //------------------------------ + // Private Members + //------------------------------ + Node* Root; // The top node. 0 if empty. + u32 Size; // Number of nodes in the tree +}; + +} // end namespace core +} // end namespace irr + +#endif // __IRR_MAP_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/irrMath.h b/src/dep/include/irrlicht/irrMath.h new file mode 100644 index 0000000..568880d --- /dev/null +++ b/src/dep/include/irrlicht/irrMath.h @@ -0,0 +1,445 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MATH_H_INCLUDED__ +#define __IRR_MATH_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "irrTypes.h" +#include + +#if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) + #define sqrtf(X) (f32)sqrt((f64)(X)) + #define sinf(X) (f32)sin((f64)(X)) + #define cosf(X) (f32)cos((f64)(X)) + #define ceilf(X) (f32)ceil((f64)(X)) + #define floorf(X) (f32)floor((f64)(X)) + #define powf(X,Y) (f32)pow((f64)(X),(f64)(Y)) + #define fmodf(X,Y) (f32)fmod((f64)(X),(f64)(Y)) + #define fabsf(X) (f32)fabs((f64)(X)) +#endif + +namespace irr +{ +namespace core +{ + + //! Rounding error constant often used when comparing f32 values. + +#ifdef IRRLICHT_FAST_MATH + const f32 ROUNDING_ERROR_32 = 0.00005f; + const f64 ROUNDING_ERROR_64 = 0.000005f; +#else + const f32 ROUNDING_ERROR_32 = 0.000001f; + const f64 ROUNDING_ERROR_64 = 0.00000001f; +#endif + + //! Constant for PI. + const f32 PI = 3.14159265359f; + + //! Constant for reciprocal of PI. + const f32 RECIPROCAL_PI = 1.0f/PI; + + //! Constant for half of PI. + const f32 HALF_PI = PI/2.0f; + + //! Constant for 64bit PI. + const f64 PI64 = 3.1415926535897932384626433832795028841971693993751; + + //! Constant for 64bit reciprocal of PI. + const f64 RECIPROCAL_PI64 = 1.0/PI64; + + //! 32bit Constant for converting from degrees to radians + const f32 DEGTORAD = PI / 180.0f; + + //! 32bit constant for converting from radians to degrees (formally known as GRAD_PI) + const f32 RADTODEG = 180.0f / PI; + + //! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2) + const f64 DEGTORAD64 = PI64 / 180.0; + + //! 64bit constant for converting from radians to degrees + const f64 RADTODEG64 = 180.0 / PI64; + + //! returns minimum of two values. Own implementation to get rid of the STL (VS6 problems) + template + inline const T& min_(const T& a, const T& b) + { + return a < b ? a : b; + } + + //! returns minimum of three values. Own implementation to get rid of the STL (VS6 problems) + template + inline const T& min_(const T& a, const T& b, const T& c) + { + return a < b ? min_(a, c) : min_(b, c); + } + + //! returns maximum of two values. Own implementation to get rid of the STL (VS6 problems) + template + inline const T& max_(const T& a, const T& b) + { + return a < b ? b : a; + } + + //! returns maximum of three values. Own implementation to get rid of the STL (VS6 problems) + template + inline const T& max_(const T& a, const T& b, const T& c) + { + return a < b ? max_(b, c) : max_(a, c); + } + + //! returns abs of two values. Own implementation to get rid of STL (VS6 problems) + template + inline T abs_(const T& a) + { + return a < (T)0 ? -a : a; + } + + //! returns linear interpolation of a and b with ratio t + //! \return: a if t==0, b if t==1, and the linear interpolation else + template + inline T lerp(const T& a, const T& b, const f32 t) + { + return (a*(1.f-t)) + (b*t); + } + + //! clamps a value between low and high + template + inline const T clamp (const T& value, const T& low, const T& high) + { + return min_ (max_(value,low), high); + } + + //! returns if a equals b, taking possible rounding errors into account + inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_32) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + //! returns if a equals b, taking possible rounding errors into account + inline bool equals(const s32 a, const s32 b, const s32 tolerance = 0) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + //! returns if a equals b, taking possible rounding errors into account + inline bool equals(const u32 a, const u32 b, const u32 tolerance = 0) + { + return (a + tolerance >= b) && (a - tolerance <= b); + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_32) + { + return fabsf ( a ) <= tolerance; + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const s32 a, const s32 tolerance = 0) + { + return ( a & 0x7ffffff ) <= tolerance; + } + + //! returns if a equals zero, taking rounding errors into account + inline bool iszero(const u32 a, const u32 tolerance = 0) + { + return a <= tolerance; + } + + inline s32 s32_min ( s32 a, s32 b) + { + s32 mask = (a - b) >> 31; + return (a & mask) | (b & ~mask); + } + + inline s32 s32_max ( s32 a, s32 b) + { + s32 mask = (a - b) >> 31; + return (b & mask) | (a & ~mask); + } + + inline s32 s32_clamp (s32 value, s32 low, s32 high) + { + return s32_min (s32_max(value,low), high); + } + + /* + + float IEEE-754 bit represenation + + 0 0x00000000 + 1.0 0x3f800000 + 0.5 0x3f000000 + 3 0x40400000 + +inf 0x7f800000 + -inf 0xff800000 + +NaN 0x7fc00000 or 0x7ff00000 + in general: number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits) + */ + + #define F32_AS_S32(f) (*((s32 *) &(f))) + #define F32_AS_U32(f) (*((u32 *) &(f))) + #define F32_AS_U32_POINTER(f) ( ((u32 *) &(f))) + + #define F32_VALUE_0 0x00000000 + #define F32_VALUE_1 0x3f800000 + #define F32_SIGN_BIT 0x80000000U + #define F32_EXPON_MANTISSA 0x7FFFFFFFU + + //! code is taken from IceFPU + //! Integer representation of a floating-point value. + #define IR(x) ((u32&)(x)) + + //! Absolute integer representation of a floating-point value + #define AIR(x) (IR(x)&0x7fffffff) + + //! Floating-point representation of an integer value. + #define FR(x) ((f32&)(x)) + + #define IEEE_1_0 0x3f800000 //!< integer representation of 1.0 + #define IEEE_255_0 0x437f0000 //!< integer representation of 255.0 + +#ifdef IRRLICHT_FAST_MATH + #define F32_LOWER_0(f) (F32_AS_U32(f) > F32_SIGN_BIT) + #define F32_LOWER_EQUAL_0(f) (F32_AS_S32(f) <= F32_VALUE_0) + #define F32_GREATER_0(f) (F32_AS_S32(f) > F32_VALUE_0) + #define F32_GREATER_EQUAL_0(f) (F32_AS_U32(f) <= F32_SIGN_BIT) + #define F32_EQUAL_1(f) (F32_AS_U32(f) == F32_VALUE_1) + #define F32_EQUAL_0(f) ( (F32_AS_U32(f) & F32_EXPON_MANTISSA ) == F32_VALUE_0) + + // only same sign + #define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b))) +#else + #define F32_LOWER_0(n) ((n) < 0.0f) + #define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f) + #define F32_GREATER_0(n) ((n) > 0.0f) + #define F32_GREATER_EQUAL_0(n) ((n) >= 0.0f) + #define F32_EQUAL_1(n) ((n) == 1.0f) + #define F32_EQUAL_0(n) ((n) == 0.0f) + #define F32_A_GREATER_B(a,b) ((a) > (b)) +#endif + + +#ifndef REALINLINE + #ifdef _MSC_VER + #define REALINLINE __forceinline + #else + #define REALINLINE inline + #endif +#endif + + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_b ( const s32 condition, const u32 a, const u32 b ) + { + return ( ( -condition >> 31 ) & ( a ^ b ) ) ^ b; + } + + //! conditional set based on mask and arithmetic shift + REALINLINE u32 if_c_a_else_0 ( const s32 condition, const u32 a ) + { + return ( -condition >> 31 ) & a; + } + + /* + if (condition) state |= m; else state &= ~m; + */ + REALINLINE void setbit ( u32 &state, s32 condition, u32 mask ) + { + // 0, or any postive to mask + //s32 conmask = -condition >> 31; + state ^= ( ( -condition >> 31 ) ^ state ) & mask; + } + + + + inline f32 round_( f32 x ) + { + return floorf( x + 0.5f ); + } + + REALINLINE void clearFPUException () + { +#ifdef IRRLICHT_FAST_MATH +#ifdef feclearexcept + feclearexcept(FE_ALL_EXCEPT); +#elif defined(_MSC_VER) + __asm fnclex; +#elif defined(__GNUC__) && defined(__x86__) + __asm__ __volatile__ ("fclex \n\t"); +#else +# warn clearFPUException not supported. +#endif +#endif + } + + REALINLINE f32 reciprocal_squareroot(const f32 x) + { +#ifdef IRRLICHT_FAST_MATH + // comes from Nvidia +#if 1 + u32 tmp = (u32(IEEE_1_0 << 1) + IEEE_1_0 - *(u32*)&x) >> 1; + f32 y = *(f32*)&tmp; + return y * (1.47f - 0.47f * x * y * y); +#elif defined(_MSC_VER) + // an sse2 version + __asm + { + movss xmm0, x + rsqrtss xmm0, xmm0 + movss x, xmm0 + } + return x; +#endif +#else // no fast math + return 1.f / sqrtf ( x ); +#endif + } + + + + REALINLINE f32 reciprocal ( const f32 f ) + { +#ifdef IRRLICHT_FAST_MATH + //! i do not divide through 0.. (fpu expection) + // instead set f to a high value to get a return value near zero.. + // -1000000000000.f.. is use minus to stay negative.. + // must test's here (plane.normal dot anything ) checks on <= 0.f + return 1.f / f; + //u32 x = (-(AIR(f) != 0 ) >> 31 ) & ( IR(f) ^ 0xd368d4a5 ) ^ 0xd368d4a5; + //return 1.f / FR ( x ); +#else // no fast math + return 1.f / f; +#endif + } + + + REALINLINE f32 reciprocal_approxim ( const f32 p ) + { +#ifdef IRRLICHT_FAST_MATH + register u32 x = 0x7F000000 - IR ( p ); + const f32 r = FR ( x ); + return r * (2.0f - p * r); +#else // no fast math + return 1.f / p; +#endif + } + + + REALINLINE s32 floor32(f32 x) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fsub h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fsub %2 \n\t" + "fistpl %0" + : "=m" (t) + : "t" (x), "f" (h) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) floorf ( x ); +#endif + return t; +#else // no fast math + return (s32) floorf ( x ); +#endif + } + + + REALINLINE s32 ceil32 ( f32 x ) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fadd h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fadd %2 \n\t" + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x), "f"(h) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) ceilf ( x ); +#endif + return t; +#else // not fast math + return (s32) ceilf ( x ); +#endif + } + + + + REALINLINE s32 round32(f32 x) + { +#if defined(IRRLICHT_FAST_MATH) + s32 t; + +#if defined(_MSC_VER) + __asm + { + fld x + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x) + : "st" + ); +#else +# warn IRRLICHT_FAST_MATH not supported. + return (s32) round_(x); +#endif + return t; +#else // no fast math + return (s32) round_(x); +#endif + } + + inline f32 f32_max3(const f32 a, const f32 b, const f32 c) + { + return a > b ? (a > c ? a : c) : (b > c ? b : c); + } + + inline f32 f32_min3(const f32 a, const f32 b, const f32 c) + { + return a < b ? (a < c ? a : c) : (b < c ? b : c); + } + + inline f32 fract ( f32 x ) + { + return x - floorf ( x ); + } + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/irrString.h b/src/dep/include/irrlicht/irrString.h new file mode 100644 index 0000000..1b3f5be --- /dev/null +++ b/src/dep/include/irrlicht/irrString.h @@ -0,0 +1,875 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_STRING_H_INCLUDED__ +#define __IRR_STRING_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrAllocator.h" +#include "irrMath.h" +#include +#include +#include + +namespace irr +{ +namespace core +{ + +//! Very simple string class with some useful features. +/** string and string work both with unicode AND ascii, +so you can assign unicode to string and ascii to string +(and the other way round) if your ever would want to. +Note that the conversation between both is not done using an encoding. + +Known bugs: +Special characters like umlauts are ignored in the +methods make_upper, make_lower and equals_ignore_case. +*/ +template > +class string +{ +public: + + //! Default constructor + string() + : array(0), allocated(1), used(1) + { + array = allocator.allocate(1); // new T[1]; + array[0] = 0x0; + } + + + + //! Constructor + string(const string& other) + : array(0), allocated(0), used(0) + { + *this = other; + } + + + + //! Constructs a string from a float + string(const double number) + : array(0), allocated(0), used(0) + { + c8 tmpbuf[255]; + snprintf(tmpbuf, 255, "%0.6f", number); + *this = tmpbuf; + } + + + + //! Constructs a string from an int + string(int number) + : array(0), allocated(0), used(0) + { + // store if negative and make positive + + bool negative = false; + if (number < 0) + { + number *= -1; + negative = true; + } + + // temporary buffer for 16 numbers + + c8 tmpbuf[16]; + tmpbuf[15] = 0; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + // add sign + + if (negative) + { + --idx; + tmpbuf[idx] = '-'; + } + + *this = &tmpbuf[idx]; + } + + + + //! Constructs a string from an unsigned int + string(unsigned int number) + : array(0), allocated(0), used(0) + { + // temporary buffer for 16 numbers + + c8 tmpbuf[16]; + tmpbuf[15] = 0; + u32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + --idx; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number /= 10; + } + + *this = &tmpbuf[idx]; + } + + + + //! Constructor for copying a string from a pointer with a given length + template + string(const B* const c, u32 length) + : array(0), allocated(0), used(0) + { + if (!c) + { + // correctly init the string to an empty one + *this=""; + return; + } + + allocated = used = length+1; + array = allocator.allocate(used); // new T[used]; + + for (u32 l = 0; l + string(const B* const c) + : array(0), allocated(0), used(0) + { + *this = c; + } + + + + //! destructor + ~string() + { + allocator.deallocate(array); // delete [] array; + } + + + + //! Assignment operator + string& operator=(const string& other) + { + if (this == &other) + return *this; + + allocator.deallocate(array); // delete [] array; + allocated = used = other.size()+1; + array = allocator.allocate(used); //new T[used]; + + const T* p = other.c_str(); + for (u32 i=0; i + string& operator=(const B* const c) + { + if (!c) + { + if (!array) + { + array = allocator.allocate(1); //new T[1]; + allocated = 1; + } + used = 1; + array[0] = 0x0; + return *this; + } + + if ((void*)c == (void*)array) + return *this; + + u32 len = 0; + const B* p = c; + while(*p) + { + ++len; + ++p; + } + + // we'll take the old string for a while, because the new + // string could be a part of the current string. + T* oldArray = array; + + ++len; + allocated = used = len; + array = allocator.allocate(used); //new T[used]; + + for (u32 l = 0; l operator+(const string& other) const + { + string str(*this); + str.append(other); + + return str; + } + + //! Add operator for strings, ascii and unicode + template + string operator+(const B* const c) const + { + string str(*this); + str.append(c); + + return str; + } + + + //! Direct access operator + T& operator [](const u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + return array[index]; + } + + + //! Direct access operator + const T& operator [](const u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + return array[index]; + } + + + //! Comparison operator + bool operator ==(const T* const str) const + { + if (!str) + return false; + + u32 i; + for(i=0; array[i] && str[i]; ++i) + if (array[i] != str[i]) + return false; + + return !array[i] && !str[i]; + } + + + + //! Comparison operator + bool operator ==(const string& other) const + { + for(u32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return false; + + return used == other.used; + } + + + //! Is smaller operator + bool operator <(const string& other) const + { + for(u32 i=0; array[i] && other.array[i]; ++i) + { + s32 diff = array[i] - other.array[i]; + if ( diff ) + return diff < 0; +/* + if (array[i] != other.array[i]) + return (array[i] < other.array[i]); +*/ + } + + return used < other.used; + } + + + + //! Equals not operator + bool operator !=(const T* const str) const + { + return !(*this == str); + } + + + + //! Equals not operator + bool operator !=(const string& other) const + { + return !(*this == other); + } + + + + //! Returns length of string + /** \return Returns length of the string in characters. */ + u32 size() const + { + return used-1; + } + + + + //! Returns character string + /** \return Returns pointer to C-style zero terminated string. */ + const T* c_str() const + { + return array; + } + + + + //! Makes the string lower case. + void make_lower() + { + for (u32 i=0; i=a && array[i]<=z) + array[i] += diff; + } + } + + + + //! Compares the string ignoring case. + /** \param other: Other string to compare. + \return Returns true if the string are equal ignoring case. */ + bool equals_ignore_case(const string& other) const + { + for(u32 i=0; array[i] && other[i]; ++i) + if (ansi_lower(array[i]) != ansi_lower(other[i])) + return false; + + return used == other.used; + } + + //! Compares the string ignoring case. + /** \param other: Other string to compare. + \return Returns true if the string is smaller ignoring case. */ + bool lower_ignore_case(const string& other) const + { + for(u32 i=0; array[i] && other.array[i]; ++i) + { + s32 diff = (s32) ansi_lower ( array[i] ) - (s32) ansi_lower ( other.array[i] ); + if ( diff ) + return diff < 0; + } + + return used < other.used; + } + + + + //! compares the first n characters of the strings + bool equalsn(const string& other, int len) const + { + u32 i; + for(i=0; array[i] && other[i] && i < len; ++i) + if (array[i] != other[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same length + return (i == len) || (used == other.used); + } + + + //! compares the first n characters of the strings + bool equalsn(const T* const str, int len) const + { + if (!str) + return false; + u32 i; + for(i=0; array[i] && str[i] && i < len; ++i) + if (array[i] != str[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same length + return (i == len) || (array[i] == 0 && str[i] == 0); + } + + + //! Appends a character to this string + /** \param character: Character to append. */ + void append(T character) + { + if (used + 1 > allocated) + reallocate(used + 1); + + ++used; + + array[used-2] = character; + array[used-1] = 0; + } + + //! Appends a char string to this string + /** \param other: Char string to append. */ + void append(const T* const other) + { + if (!other) + return; + + u32 len = 0; + const T* p = other; + while(*p) + { + ++len; + ++p; + } + + if (used + len > allocated) + reallocate(used + len); + + --used; + ++len; + + for (u32 l=0; l& other) + { + --used; + u32 len = other.size()+1; + + if (used + len > allocated) + reallocate(used + len); + + for (u32 l=0; l& other, u32 length) + { + if (other.size() < length) + { + append(other); + return; + } + + if (used + length > allocated) + reallocate(used + length); + + --used; + + for (u32 l=0; l + s32 findFirstCharNotInList(const B* const c, u32 count) const + { + for (u32 i=0; i + s32 findLastCharNotInList(const B* const c, u32 count) const + { + for (s32 i=(s32)(used-2); i>=0; --i) + { + u32 j; + for (j=0; j=0; --i) + if (array[i] == c) + return i; + + return -1; + } + + //! finds another string in this string + //! \param str: Another string + //! \return Returns positions where the string has been found, + //! or -1 if not found. + template + s32 find(const B* const str) const + { + if (str && *str) + { + u32 len = 0; + + while (str[len]) + ++len; + + if (len > used-1) + return -1; + + for (u32 i=0; i subString(u32 begin, s32 length) const + { + if ((length+begin) > size()) + length = size()-begin; + if (length <= 0) + return string(""); + + string o; + o.reserve(length+1); + + for (s32 i=0; i& operator += (T c) + { + append(c); + return *this; + } + + + string& operator += (const T* const c) + { + append(c); + return *this; + } + + + string& operator += (const string& other) + { + append(other); + return *this; + } + + + string& operator += (const int i) + { + append(string(i)); + return *this; + } + + + string& operator += (const unsigned int i) + { + append(string(i)); + return *this; + } + + + string& operator += (const long i) + { + append(string(i)); + return *this; + } + + + string& operator += (const unsigned long& i) + { + append(string(i)); + return *this; + } + + + string& operator += (const double i) + { + append(string(i)); + return *this; + } + + + string& operator += (const float i) + { + append(string(i)); + return *this; + } + + + //! replaces all characters of a special type with another one + void replace(T toReplace, T replaceWith) + { + for (u32 i=0; i=used) // access violation + + for (u32 i=index+1; i=(T)'A' && t<=(T)'Z') + return t + ((T)'a' - (T)'A'); + else + return t; + } +*/ + //! Returns a character converted to lower case + inline T ansi_lower ( u32 x ) const + { + return x >= 'A' && x <= 'Z' ? (T) x + 0x20 : (T) x; + } + + + //! Reallocate the array, make it bigger or smaller + void reallocate(u32 new_size) + { + T* old_array = array; + + array = allocator.allocate(new_size); //new T[new_size]; + allocated = new_size; + + u32 amount = used < new_size ? used : new_size; + for (u32 i=0; i stringc; + +//! Typedef for wide character strings +typedef string stringw; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/irrTypes.h b/src/dep/include/irrlicht/irrTypes.h new file mode 100644 index 0000000..98b9f9d --- /dev/null +++ b/src/dep/include/irrlicht/irrTypes.h @@ -0,0 +1,160 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TYPES_H_INCLUDED__ +#define __IRR_TYPES_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +namespace irr +{ + +//! 8 bit unsigned variable. +/** This is a typedef for unsigned char, it ensures portability of the engine. */ +typedef unsigned char u8; + +//! 8 bit signed variable. +/** This is a typedef for signed char, it ensures portability of the engine. */ +typedef signed char s8; + +//! 8 bit character variable. +/** This is a typedef for char, it ensures portability of the engine. */ +typedef char c8; + + + +//! 16 bit unsigned variable. +/** This is a typedef for unsigned short, it ensures portability of the engine. */ +typedef unsigned short u16; + +//! 16 bit signed variable. +/** This is a typedef for signed short, it ensures portability of the engine. */ +typedef signed short s16; + + + +//! 32 bit unsigned variable. +/** This is a typedef for unsigned int, it ensures portability of the engine. */ +typedef unsigned int u32; + +//! 32 bit signed variable. +/** This is a typedef for signed int, it ensures portability of the engine. */ +typedef signed int s32; + + + +// 64 bit signed variable. +// This is a typedef for __int64, it ensures portability of the engine. +// This type is currently not used by the engine and not supported by compilers +// other than Microsoft Compilers, so it is outcommented. +//typedef __int64 s64; + + + +//! 32 bit floating point variable. +/** This is a typedef for float, it ensures portability of the engine. */ +typedef float f32; + +//! 64 bit floating point variable. +/** This is a typedef for double, it ensures portability of the engine. */ +typedef double f64; + + +} // end namespace irr + + +#include +#ifdef _IRR_WINDOWS_API_ +//! Defines for s{w,n}printf because these methods do not match the ISO C +//! standard on Windows platforms, but it does on all others. +//! These should be int snprintf(char *str, size_t size, const char *format, ...); +//! and int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...); +#if defined(_MSC_VER) && _MSC_VER > 1310 +#define swprintf swprintf_s +#define snprintf sprintf_s +#else +#define swprintf _snwprintf +#define snprintf _snprintf +#endif + +// define the wchar_t type if not already built in. +#ifdef _MSC_VER +#ifndef _WCHAR_T_DEFINED +//! A 16 bit wide character type. +/** + Defines the wchar_t-type. + In VS6, its not possible to tell + the standard compiler to treat wchar_t as a built-in type, and + sometimes we just don't want to include the huge stdlib.h or wchar.h, + so we'll use this. +*/ +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif // wchar is not defined +#endif // microsoft compiler +#endif // _IRR_WINDOWS_API_ + +//! define a break macro for debugging. +#if defined(_DEBUG) +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3} +#else +#include "assert.h" +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) assert( !(_CONDITION_) ); +#endif +#else +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) +#endif + +//! Defines a small statement to work around a microsoft compiler bug. +/** The microsft compiler 7.0 - 7.1 has a bug: +When you call unmanaged code that returns a bool type value of false from managed code, +the return value may appear as true. See +http://support.microsoft.com/default.aspx?kbid=823071 for details. +Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/ +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400) +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100 +#else +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX +#endif // _IRR_MANAGED_MARSHALLING_BUGFIX + + +// memory debugging +#if defined(_DEBUG) && defined(IRRLICHT_EXPORTS) && defined(_MSC_VER) && \ + (_MSC_VER > 1299) && !defined(_IRR_DONT_DO_MEMORY_DEBUGGING_HERE) + + #define CRTDBG_MAP_ALLOC + #define _CRTDBG_MAP_ALLOC + #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) + #include + #include + #define new DEBUG_CLIENTBLOCK +#endif + +// disable truncated debug information warning in visual studio 6 by default +#if defined(_MSC_VER) && (_MSC_VER < 1300 ) +#pragma warning( disable: 4786) +#endif // _MSC + + +//! ignore VC8 warning deprecated +/** The microsoft compiler */ +#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER >= 1400) + //#pragma warning( disable: 4996) + //#define _CRT_SECURE_NO_DEPRECATE 1 + //#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + + +//! creates four CC codes used in Irrlicht for simple ids +/** some compilers can create those by directly writing the +code like 'code', but some generate warnings so we use this macro here */ +#define MAKE_IRR_ID(c0, c1, c2, c3) \ + ((u32)(u8)(c0) | ((u32)(u8)(c1) << 8) | \ + ((u32)(u8)(c2) << 16) | ((u32)(u8)(c3) << 24 )) + + +#endif // __IRR_TYPES_H_INCLUDED__ + + diff --git a/src/dep/include/irrlicht/irrXML.h b/src/dep/include/irrlicht/irrXML.h new file mode 100644 index 0000000..e8c498e --- /dev/null +++ b/src/dep/include/irrlicht/irrXML.h @@ -0,0 +1,541 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __IRR_XML_H_INCLUDED__ +#define __IRR_XML_H_INCLUDED__ + +#include +#include "IrrCompileConfig.h" + +/** \mainpage irrXML 1.2 API documentation +
+ + \section intro Introduction + + Welcome to the irrXML API documentation. + Here you'll find any information you'll need to develop applications with + irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample, + at the homepage of irrXML at xml.irrlicht3d.org + or into the SDK in the directory \example. + + irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and + this documentation is an important part of it. If you have any questions or + suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history. + + \section features Features + + irrXML provides forward-only, read-only + access to a stream of non validated XML data. It was fully implemented by + Nikolaus Gebhardt. Its current features are: + + - It it fast as lighting and has very low memory usage. It was + developed with the intention of being used in 3D games, as it already has been. + - irrXML is very small: It only consists of 60 KB of code and can be added easily + to your existing project. + - Of course, it is platform independent and works with lots of compilers. + - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in + little and big endian format. + - Independent of the input file format, the parser can return all strings in ASCII, UTF-8, + UTF-16 and UTF-32 format. + - With its optional file access abstraction it has the advantage that it can read not + only from files but from any type of data (memory, network, ...). For example when + used with the Irrlicht Engine, it directly reads from compressed .zip files. + - Just like the Irrlicht Engine for which it was originally created, it is extremely easy + to use. + - It has no external dependencies, it does not even need the STL. + + Although irrXML has some strenghts, it currently also has the following limitations: + + - The input xml file is not validated and assumed to be correct. + + \section irrxmlexample Example + + The following code demonstrates the basic usage of irrXML. A simple xml + file like this is parsed: + \code + + + + + + Welcome to the Mesh Viewer of the "Irrlicht Engine". + + + \endcode + + The code for parsing this file would look like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + #include // we use STL strings to store data in this example + + void main() + { + // create the reader using one of the factory functions + + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + // strings for storing the data we want to get out of the file + std::string modelFile; + std::string messageText; + std::string caption; + + // parse the file until end reached + + while(xml && xml->read()) + { + switch(xml->getNodeType()) + { + case EXN_TEXT: + // in this xml file, the only text which occurs is the messageText + messageText = xml->getNodeData(); + break; + case EXN_ELEMENT: + { + if (!strcmp("model", xml->getNodeName())) + modelFile = xml->getAttributeValue("file"); + else + if (!strcmp("messageText", xml->getNodeName())) + caption = xml->getAttributeValue("caption"); + } + break; + } + } + + // delete the xml parser after usage + delete xml; + } + \endcode + + \section howto How to use + + Simply add the source files in the /src directory of irrXML to your project. Done. + + \section license License + + The irrXML license is based on the zlib license. Basicly, this means you can do with + irrXML whatever you want: + + Copyright (C) 2002-2007 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, 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 notice may not be removed or altered from any source distribution. + + \section history History + + As lots of references in this documentation and the source show, this xml + parser has originally been a part of the + Irrlicht Engine. But because + the parser has become very useful with the latest release, people asked for a + separate version of it, to be able to use it in non Irrlicht projects. With + irrXML 1.0, this has now been done. +*/ + +namespace irr +{ +namespace io +{ + //! Enumeration of all supported source text file formats + enum ETEXT_FORMAT + { + //! ASCII, file without byte order mark, or not a text file + ETF_ASCII, + + //! UTF-8 format + ETF_UTF8, + + //! UTF-16 format, big endian + ETF_UTF16_BE, + + //! UTF-16 format, little endian + ETF_UTF16_LE, + + //! UTF-32 format, big endian + ETF_UTF32_BE, + + //! UTF-32 format, little endian + ETF_UTF32_LE + }; + + + //! Enumeration for all xml nodes which are parsed by IrrXMLReader + enum EXML_NODE + { + //! No xml node. This is usually the node if you did not read anything yet. + EXN_NONE, + + //! An xml element such as <foo> + EXN_ELEMENT, + + //! End of an xml element such as </foo> + EXN_ELEMENT_END, + + //! Text within an xml element: <foo> this is the text. <foo> + EXN_TEXT, + + //! An xml comment like <!-- I am a comment --> or a DTD definition. + EXN_COMMENT, + + //! An xml cdata section like <![CDATA[ this is some CDATA ]]> + EXN_CDATA, + + //! Unknown element. + EXN_UNKNOWN + }; + + //! Callback class for file read abstraction. + /** With this, it is possible to make the xml parser read in other things + than just files. The Irrlicht engine is using this for example to + read xml from compressed .zip files. To make the parser read in + any other data, derive a class from this interface, implement the + two methods to read your data and give a pointer to an instance of + your implementation when calling createIrrXMLReader(), + createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ + class IFileReadCallBack + { + public: + + //! virtual destructor + virtual ~IFileReadCallBack() {} + + //! Reads an amount of bytes from the file. + /** \param buffer: Pointer to buffer where to read bytes will be written to. + \param sizeToRead: Amount of bytes to read from the file. + \return Returns how much bytes were read. */ + virtual int read(void* buffer, int sizeToRead) = 0; + + //! Returns size of file in bytes + virtual long getSize() const = 0; + }; + + //! Empty class to be used as parent class for IrrXMLReader. + /** If you need another class as base class for the xml reader, you can do this by creating + the reader using for example new CXMLReaderImpl(yourcallback); + The Irrlicht Engine for example needs IReferenceCounted as base class for every object to + let it automaticly reference countend, hence it replaces IXMLBase with IReferenceCounted. + See irrXML.cpp on how this can be done in detail. */ + class IXMLBase + { + }; + + //! Interface providing easy read access to a XML file. + /** You can create an instance of this reader using one of the factory functions + createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32(). + If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() + instead. + For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features. + + The typical usage of this parser looks like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + void main() + { + // create the reader using one of the factory functions + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + if (xml == 0) + return; // file could not be opened + + // parse the file until end reached + while(xml->read()) + { + // based on xml->getNodeType(), do something. + } + + // delete the xml parser after usage + delete xml; + } + \endcode + See \ref irrxmlexample for a more detailed example. + */ + template + class IIrrXMLReader : public super_class + { + public: + + //! Destructor + virtual ~IIrrXMLReader() {} + + //! Reads forward to the next xml node. + /** \return Returns false, if there was no further node. */ + virtual bool read() = 0; + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const = 0; + + //! Returns attribute count of the current XML node. + /** This is usually + non null if the current node is EXN_ELEMENT, and the element has attributes. + \return Returns amount of attributes of this xml node. */ + virtual unsigned int getAttributeCount() const = 0; + + //! Returns name of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Name of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeName(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeValue(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param name: Name of the attribute. + \return Value of the attribute, 0 if an attribute with this name does not exist. */ + virtual const char_type* getAttributeValue(const char_type* name) const = 0; + + //! Returns the value of an attribute in a safe way. + /** Like getAttributeValue(), but does not + return 0 if the attribute does not exist. An empty string ("") is returned then. + \param name: Name of the attribute. + \return Value of the attribute, and "" if an attribute with this name does not exist */ + virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param name Name of the attribute. + \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(int idx) const = 0; + + //! Returns the value of an attribute as float. + /** \param name: Name of the attribute. + \return Value of the attribute as float, and 0 if an attribute with this name does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(const char_type* name) const = 0; + + //! Returns the value of an attribute as float. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as float, and 0 if an attribute with this index does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(int idx) const = 0; + + //! Returns the name of the current node. + /** Only non null, if the node type is EXN_ELEMENT. + \return Name of the current node or 0 if the node has no name. */ + virtual const char_type* getNodeName() const = 0; + + //! Returns data of the current node. + /** Only non null if the node has some + data and it is of type EXN_TEXT or EXN_UNKNOWN. */ + virtual const char_type* getNodeData() const = 0; + + //! Returns if an element is an empty element, like <foo /> + virtual bool isEmptyElement() const = 0; + + //! Returns format of the source xml file. + /** It is not necessary to use + this method because the parser will convert the input file format + to the format wanted by the user when creating the parser. This + method is useful to get/display additional informations. */ + virtual ETEXT_FORMAT getSourceFormat() const = 0; + + //! Returns format of the strings returned by the parser. + /** This will be UTF8 for example when you created a parser with + IrrXMLReaderUTF8() and UTF32 when it has been created using + IrrXMLReaderUTF32. It should not be necessary to call this + method and only exists for informational purposes. */ + virtual ETEXT_FORMAT getParserFormat() const = 0; + }; + + + //! defines the utf-16 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned short char16; + + //! defines the utf-32 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned long char32; + + //! A UTF-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. + The file to read can be in any format, it will be converted to UTF-8 if it is not + in this format. + Create an instance of this with createIrrXMLReader(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReader; + + //! A UTF-16 xml parser. + /** This means that all character data will be returned in UTF-16 by this parser. + The file to read can be in any format, it will be converted to UTF-16 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF16(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF16; + + //! A UTF-32 xml parser. + /** This means that all character data will be returned in UTF-32 by this parser. + The file to read can be in any format, it will be converted to UTF-32 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF32(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF32; + + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. + The file to read can be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(const char* filename); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(FILE* file); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(IFileReadCallBack* callback); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that + all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(const char* filename); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(FILE* file); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(IFileReadCallBack* callback); + + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(const char* filename); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + if you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(FILE* file); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that + all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(IFileReadCallBack* callback); + + + /*! \file irrxml.h + \brief Header file of the irrXML, the Irrlicht XML parser. + + This file includes everything needed for using irrXML, + the XML parser of the Irrlicht Engine. To use irrXML, + you only need to include this file in your project: + + \code + #include + \endcode + + It is also common to use the two namespaces in which irrXML is included, + directly after #including irrXML.h: + + \code + #include + using namespace irr; + using namespace io; + \endcode + */ + +} // end namespace io +} // end namespace irr + +#endif // __IRR_XML_H_INCLUDED__ + diff --git a/src/dep/include/irrlicht/irrlicht.h b/src/dep/include/irrlicht/irrlicht.h new file mode 100644 index 0000000..52bf324 --- /dev/null +++ b/src/dep/include/irrlicht/irrlicht.h @@ -0,0 +1,333 @@ +/* irrlicht.h -- interface of the 'Irrlicht Engine' + + Copyright (C) 2002-2007 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, 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 notice may not be removed or altered from any source distribution. + + Please note that the Irrlicht Engine is based in part on the work of the + Independent JPEG Group, the zlib and the libPng. This means that if you use + the Irrlicht Engine in your product, you must acknowledge somewhere in your + documentation that you've used the IJG code. It would also be nice to mention + that you use the Irrlicht Engine, the zlib and libPng. See the README files + in the jpeglib, the zlib and libPng for further informations. +*/ + +#ifndef __IRRLICHT_H_INCLUDED__ +#define __IRRLICHT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "aabbox3d.h" +#include "coreutil.h" +#include "irrArray.h" +#include "irrMap.h" +#include "irrMath.h" +#include "irrString.h" +#include "irrTypes.h" +#include "SColor.h" +#include "SLight.h" +#include "dimension2d.h" +#include "EDriverTypes.h" +#include "IAttributes.h" +#include "IAttributeExchangingObject.h" +#include "IAnimatedMesh.h" +#include "IAnimatedMeshMD2.h" +#include "IAnimatedMeshMD3.h" +#include "IQ3LevelMesh.h" +#include "IAnimatedMeshSceneNode.h" +#include "IBillboardSceneNode.h" +#include "IBoneSceneNode.h" +#include "ICameraSceneNode.h" +#include "IDummyTransformationSceneNode.h" +#include "IEventReceiver.h" +#include "IFileList.h" +#include "IFileSystem.h" +#include "IGPUProgrammingServices.h" +#include "IGUIButton.h" +#include "IGUICheckBox.h" +#include "IGUIColorSelectDialog.h" +#include "IGUIComboBox.h" +#include "IGUIContextMenu.h" +#include "IGUIEditBox.h" +#include "IGUIElement.h" +#include "IGUIElementFactory.h" +#include "IGUIEnvironment.h" +#include "IGUIFileOpenDialog.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "IGUIImage.h" +#include "IGUIInOutFader.h" +#include "IGUIListBox.h" +#include "IGUIMeshViewer.h" +#include "IGUIScrollBar.h" +#include "IGUISkin.h" +#include "IGUISpinBox.h" +#include "IGUISpriteBank.h" +#include "IGUIStaticText.h" +#include "IGUITabControl.h" +#include "IGUIToolbar.h" +#include "IGUIWindow.h" +#include "IImage.h" +#include "ILightSceneNode.h" +#include "ILogger.h" +#include "IMaterialRenderer.h" +#include "IMaterialRendererServices.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IMeshCache.h" +#include "IMeshSceneNode.h" +#include "IMeshManipulator.h" +#include "IMeshWriter.h" +#include "IMetaTriangleSelector.h" +#include "IReadFile.h" +#include "IrrlichtDevice.h" +#include "ISceneManager.h" +#include "ISceneNode.h" +#include "ISceneUserDataSerializer.h" +#include "ITriangleSelector.h" +#include "ISceneNodeAnimator.h" +#include "ISceneCollisionManager.h" +#include "ISceneNodeFactory.h" +#include "ISceneNodeAnimatorFactory.h" +#include "ISceneNodeAnimatorCollisionResponse.h" +#include "IShaderConstantSetCallBack.h" +#include "IParticleSystemSceneNode.h" // also includes all emitters and attractors +#include "ISkinnedMesh.h" +#include "ITerrainSceneNode.h" +#include "ITextSceneNode.h" +#include "ITexture.h" +#include "IReferenceCounted.h" +#include "IVideoDriver.h" +#include "IVideoModeList.h" +#include "IWriteFile.h" +#include "IXMLReader.h" +#include "IXMLWriter.h" +#include "Keycodes.h" +#include "line2d.h" +#include "line3d.h" +#include "irrList.h" +#include "matrix4.h" +#include "plane3d.h" +#include "vector2d.h" +#include "vector3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "quaternion.h" +#include "rect.h" +#include "S3DVertex.h" +#include "SAnimatedMesh.h" +#include "SExposedVideoData.h" +#include "SKeyMap.h" +#include "SMaterial.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SMeshBufferLightMap.h" +#include "SMeshBufferTangents.h" +#include "SViewFrustum.h" + +/*! \mainpage Irrlicht Engine 1.4 API documentation + * + *
+ * + * \section intro Introduction + * + * Welcome to the Irrlicht Engine API documentation. + * Here you'll find any information you'll need to develop applications with + * the Irrlicht Engine. If you are looking for a tutorial on how to start, you'll + * find some on the homepage of the Irrlicht Engine at + * irrlicht.sourceforge.net + * or inside the SDK in the examples directory. + * + * The Irrlicht Engine is intended to be an easy-to-use 3d engine, so + * this documentation is an important part of it. If you have any questions or + * suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + * (niko (at) irrlicht3d.org). + * + * + * \section links Links + * + * Namespaces: A very good place to start reading + * the documentation.
+ * Class list: List of all classes with descriptions.
+ * Class members: Good place to find forgotten features.
+ * + * \section irrexample Short example + * + * A simple application, starting up the engine, loading a Quake 2 animated + * model file and the corresponding texture, animating and displaying it + * in front of a blue background and placing a user controlable 3d camera + * would look like the following code. I think this example shows the usage + * of the engine quite well: + * + * \code + * #include + * using namespace irr; + * + * int main() + * { + * // start up the engine + * IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D8, + * core::dimension2d(640,480)); + * + * video::IVideoDriver* driver = device->getVideoDriver(); + * scene::ISceneManager* scenemgr = device->getSceneManager(); + * + * device->setWindowCaption(L"Hello World!"); + * + * // load and show quake2 .md2 model + * scene::ISceneNode* node = scenemgr->addAnimatedMeshSceneNode( + * scenemgr->getMesh("quake2model.md2")); + * + * // if everything worked, add a texture and disable lighting + * if (node) + * { + * node->setMaterialTexture(0, driver->getTexture("texture.bmp")); + * node->setMaterialFlag(video::EMF_LIGHTING, false); + * } + * + * // add a first person shooter style user controlled camera + * scenemgr->addCameraSceneNodeFPS(); + * + * // draw everything + * while(device->run() && driver) + * { + * driver->beginScene(true, true, video::SColor(255,0,0,255)); + * scenemgr->drawAll(); + * driver->endScene(); + * } + * + * // delete device + * device->drop(); + * return 0; + * } + * \endcode + * + * Irrlicht can load a lot of file formats automaticly, see irr::scene::ISceneManager::getMesh() + * for a detailed list. So if you would like to replace the simple blue screen background by + * a cool Quake 3 Map, optimized by an octtree, just insert this code + * somewhere before the while loop: + * + * \code + * // add .pk3 archive to the file system + * device->getFileSystem()->addZipFileArchive("quake3map.pk3"); + * + * // load .bsp file and show it using an octtree + * scenemgr->addOctTreeSceneNode( + * scenemgr->getMesh("quake3map.bsp")); + * \endcode + * + * As you can see, the engine uses namespaces. Everything in the engine is + * placed into the namespace 'irr', but there are also 5 sub namespaces. + * You can find a list of all namespaces with descriptions at the + * namespaces page. + * This is also a good place to start reading the documentation. If you + * don't want to write the namespace names all the time, just use all namespaces like + * this: + * \code + * using namespace core; + * using namespace scene; + * using namespace video; + * using namespace io; + * using namespace gui; + * \endcode + * + * There is a lot more the engine can do, but I hope this gave a short + * overview over the basic features of the engine. For more examples, please take + * a look into the examples directory of the SDK. + */ + +#include "SIrrCreationParameters.h" + +//! Everything in the Irrlicht Engine can be found in this namespace. +namespace irr +{ + //! Creates an Irrlicht device. The Irrlicht device is the root object for using the engine. + /** If you need more parameters to be passed to the creation of the Irrlicht Engine device, + use the createDeviceEx() function. + \param deviceType: Type of the device. This can currently be video::EDT_NULL, + video::EDT_SOFTWARE, video::EDT_BURNINGSVIDEO, video::EDT_DIRECT3D8, video::EDT_DIRECT3D9 and video::EDT_OPENGL. + \param windowSize: Size of the window or the video mode in fullscreen mode. + \param bits: Bits per pixel in fullscreen mode. Ignored if windowed mode. + \param fullscreen: Should be set to true if the device should run in fullscreen. Otherwise + the device runs in windowed mode. + \param stencilbuffer: Specifies if the stencil buffer should be enabled. Set this to true, + if you want the engine be able to draw stencil buffer shadows. Note that not all + devices are able to use the stencil buffer. If they don't no shadows will be drawn. + \param vsync: Specifies vertical syncronisation: If set to true, the driver will wait + for the vertical retrace period, otherwise not. + \param receiver: A user created event receiver. + \param sdk_version_do_not_use: Don't use or change this parameter. Always set it to + IRRLICHT_SDK_VERSION, which is done by default. This is needed for sdk version checks. + \return Returns pointer to the created IrrlichtDevice or null if the + device could not be created. + */ + IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice( + video::E_DRIVER_TYPE deviceType = video::EDT_SOFTWARE, + const core::dimension2d& windowSize = (core::dimension2d(640,480)), // paranthese are necessary for some compilers + u32 bits = 16, + bool fullscreen = false, + bool stencilbuffer = false, + bool vsync = false, + IEventReceiver* receiver = 0, + const c8* sdk_version_do_not_use = IRRLICHT_SDK_VERSION); + + //! Creates an Irrlicht device with the option to specify advanced parameters. + /** Usually you should used createDevice() for creating an Irrlicht Engine device. + Use this function only if you wish to specify advanced parameters like a window + handle in which the device should be created. + \param parameters: Structure containing advanced parameters for the creation of the device. + See irr::SIrrlichtCreationParameters for details. + \return Returns pointer to the created IrrlichtDevice or null if the + device could not be created. */ + IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx( + const SIrrlichtCreationParameters& parameters); + + + // THE FOLLOWING IS AN EMPTY LIST OF ALL SUB NAMESPACES + // EXISTING ONLY FOR THE DOCUMENTATION SOFTWARE DOXYGEN. + + //! In this namespace can be found basic classes like vectors, planes, arrays, lists and so on. + namespace core + { + } + + //! The gui namespace contains useful classes for easy creation of a graphical user interface. + namespace gui + { + } + + //! This namespace provides interfaces for input/output: Reading and writing files, accessing zip archives, xml files, ... + namespace io + { + } + + //! All scene management can be found in this namespace: Mesh loading, special scene nodes like octrees and billboards, ... + namespace scene + { + } + + //! The video namespace contains classes for accessing the video driver. All 2d and 3d rendering is done here. + namespace video + { + } +} + +/*! \file irrlicht.h + \brief Main header file of the irrlicht, the only file needed to include. +*/ + +#endif + diff --git a/src/dep/include/irrlicht/line2d.h b/src/dep/include/irrlicht/line2d.h new file mode 100644 index 0000000..f99cc7b --- /dev/null +++ b/src/dep/include/irrlicht/line2d.h @@ -0,0 +1,171 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LINE_2D_H_INCLUDED__ +#define __IRR_LINE_2D_H_INCLUDED__ + +#include "irrTypes.h" +#include "vector2d.h" + +namespace irr +{ +namespace core +{ + +//! 2D line between two points with intersection methods. +template +class line2d +{ + public: + + line2d() : start(0,0), end(1,1) {} + line2d(T xa, T ya, T xb, T yb) : start(xa, ya), end(xb, yb) {} + line2d(const vector2d& start, const vector2d& end) : start(start), end(end) {} + line2d(const line2d& other) : start(other.start), end(other.end) {} + + // operators + + line2d operator+(const vector2d& point) const { return line2d(start + point, end + point); } + line2d& operator+=(const vector2d& point) { start += point; end += point; return *this; } + + line2d operator-(const vector2d& point) const { return line2d(start - point, end - point); } + line2d& operator-=(const vector2d& point) { start -= point; end -= point; return *this; } + + bool operator==(const line2d& other) const { return (start==other.start && end==other.end) || (end==other.start && start==other.end);} + bool operator!=(const line2d& other) const { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);} + + // functions + + void setLine(const T& xa, const T& ya, const T& xb, const T& yb){start.set(xa, ya); end.set(xb, yb);} + void setLine(const vector2d& nstart, const vector2d& nend){start.set(nstart); end.set(nend);} + void setLine(const line2d& line){start.set(line.start); end.set(line.end);} + + //! Returns length of line + //! \return Returns length of the line. + f64 getLength() const { return start.getDistanceFrom(end); } + + //! Returns squared length of the line + //! \return Returns squared length of line. + T getLengthSQ() const { return start.getDistanceFromSQ(end); } + + //! Returns middle of the line + vector2d getMiddle() const + { + return (start + end) * (T)0.5; + } + + //! Returns the vector of the line. + //! \return Returns the vector of the line. + vector2d getVector() const { return vector2d(start.X - end.X, start.Y - end.Y); } + + //! Tests if this line intersects with another line. + //! \param l: Other line to test intersection with. + //! \param out: If there is an intersection, the location of the intersection will + //! be stored in this vector. + //! \return Returns true if there is an intersection, false if not. + bool intersectWith(const line2d& l, vector2d& out) const + { + bool found=false; + + f32 a1,a2,b1,b2; + + // calculate slopes, deal with infinity + if (end.X-start.X == 0) + b1 = (f32)1e+10; + else + b1 = (end.Y-start.Y)/(end.X-start.X); + if (l.end.X-l.start.X == 0) + b2 = (f32)1e+10; + else + b2 = (l.end.Y-l.start.Y)/(l.end.X-l.start.X); + + // calculate position + a1 = start.Y - b1 * start.X; + a2 = l.start.Y - b2 * l.start.X; + out.X = - (a1-a2)/(b1-b2); + out.Y = a1 + b1*out.X; + + // did the lines cross? + if ( (start.X-out.X) *(out.X-end.X) >= -ROUNDING_ERROR_32 && + (l.start.X-out.X)*(out.X-l.end.X)>= -ROUNDING_ERROR_32 && + (start.Y-out.Y) *(out.Y-end.Y) >= -ROUNDING_ERROR_32 && + (l.start.Y-out.Y)*(out.Y-l.end.Y)>= -ROUNDING_ERROR_32 ) + { + found = true; + } + return found; + } + + //! Returns unit vector of the line. + //! \return Returns unit vector of this line. + vector2d getUnitVector() const + { + T len = (T)(1.0 / getLength()); + return vector2d((end.X - start.X) * len, (end.Y - start.Y) * len); + } + + f64 getAngleWith(const line2d& l) const + { + vector2d vect = getVector(); + vector2d vect2 = l.getVector(); + return vect.getAngleWith(vect2); + } + + //! Tells us if the given point lies to the left, + //! right, or on the direction of the line + //! \return Returns 0 if the point is on the line + //! <0 if to the left, or >0 if to the right. + T getPointOrientation(const vector2d& point) const + { + return ( (end.X - start.X) * (point.Y - start.Y) - + (point.X - start.X) * (end.Y - start.Y) ); + } + + //! Returns if the given point is a member of the line + //! \return Returns true if + bool isPointOnLine(const vector2d& point) const + { + T d = getPointOrientation(point); + return (d == 0 && point.isBetweenPoints(start, end)); + } + + //! Returns if the given point is between start and end of the + //! line. Assumes that the point is already somewhere on the line. + bool isPointBetweenStartAndEnd(const vector2d& point) const + { + return point.isBetweenPoints(start, end); + } + + //! Returns the closest point on this line to a point + vector2d getClosestPoint(const vector2d& point) const + { + vector2d c = point - start; + vector2d v = end - start; + T d = (T)v.getLength(); + v /= d; + T t = v.dotProduct(c); + + if (t < (T)0.0) return start; + if (t > d) return end; + + v *= t; + return start + v; + } + + // member variables + + vector2d start; + vector2d end; +}; + + //! Typedef for a f32 line. + typedef line2d line2df; + //! Typedef for an integer line. + typedef line2d line2di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/line3d.h b/src/dep/include/irrlicht/line3d.h new file mode 100644 index 0000000..b5eff0c --- /dev/null +++ b/src/dep/include/irrlicht/line3d.h @@ -0,0 +1,126 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_LINE_3D_H_INCLUDED__ +#define __IRR_LINE_3D_H_INCLUDED__ + +#include "irrTypes.h" +#include "vector3d.h" + +namespace irr +{ +namespace core +{ + +//! 3D line between two points with intersection methods. +template +class line3d +{ + public: + + // Constructors + + line3d() : start(0,0,0), end(1,1,1) {} + line3d(T xa, T ya, T za, T xb, T yb, T zb) : start(xa, ya, za), end(xb, yb, zb) {} + line3d(const vector3d& start, const vector3d& end) : start(start), end(end) {} + + // operators + + line3d operator+(const vector3d& point) const { return line3d(start + point, end + point); } + line3d& operator+=(const vector3d& point) { start += point; end += point; return *this; } + + line3d operator-(const vector3d& point) const { return line3d(start - point, end - point); } + line3d& operator-=(const vector3d& point) { start -= point; end -= point; return *this; } + + bool operator==(const line3d& other) const { return (start==other.start && end==other.end) || (end==other.start && start==other.end);} + bool operator!=(const line3d& other) const { return !(start==other.start && end==other.end) || (end==other.start && start==other.end);} + + // functions + + void setLine(const T& xa, const T& ya, const T& za, const T& xb, const T& yb, const T& zb) {start.set(xa, ya, za); end.set(xb, yb, zb);} + void setLine(const vector3d& nstart, const vector3d& nend) {start.set(nstart); end.set(nend);} + void setLine(const line3d& line) {start.set(line.start); end.set(line.end);} + + //! Returns length of line + //! \return Returns length of line. + T getLength() const { return start.getDistanceFrom(end); } + + //! Returns sqared length of line + //! \return Returns sqared length of line. + T getLengthSQ() const { return start.getDistanceFromSQ(end); } + + //! Returns middle of line + vector3d getMiddle() const + { + return (start + end) * (T)0.5; + } + + //! Returns vector of line + vector3d getVector() const + { + return end - start; + } + + //! Returns if the given point is between start and end of the + //! line. Assumes that the point is already somewhere on the line. + bool isPointBetweenStartAndEnd(const vector3d& point) const + { + return point.isBetweenPoints(start, end); + } + + //! Returns the closest point on this line to a point + vector3d getClosestPoint(const vector3d& point) const + { + vector3d c = point - start; + vector3d v = end - start; + T d = (T)v.getLength(); + v /= d; + T t = v.dotProduct(c); + + if (t < (T)0.0) + return start; + if (t > d) + return end; + + v *= t; + return start + v; + } + + //! Returns if the line intersects with a shpere + //! \param sorigin: Origin of the shpere. + //! \param sradius: Radius of the sphere. + //! \param outdistance: The distance to the first intersection point. + //! \return Returns true if there is an intersection. + //! If there is one, the distance to the first intersection point + //! is stored in outdistance. + bool getIntersectionWithSphere(vector3d sorigin, T sradius, f64& outdistance) const + { + const vector3d q = sorigin - start; + T c = q.getLength(); + T v = q.dotProduct(getVector().normalize()); + T d = sradius * sradius - (c*c - v*v); + + if (d < 0.0) + return false; + + outdistance = v - sqrt((f64)d); + return true; + } + + // member variables + + vector3d start; + vector3d end; +}; + + //! Typedef for an f32 line. + typedef line3d line3df; + //! Typedef for an integer line. + typedef line3d line3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/matrix4.h b/src/dep/include/irrlicht/matrix4.h new file mode 100644 index 0000000..f541d20 --- /dev/null +++ b/src/dep/include/irrlicht/matrix4.h @@ -0,0 +1,1639 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_MATRIX_H_INCLUDED__ +#define __IRR_MATRIX_H_INCLUDED__ + +#include "irrTypes.h" +#include "vector3d.h" +#include "vector2d.h" +#include "plane3d.h" +#include "aabbox3d.h" +#include "rect.h" +#include "irrString.h" + +namespace irr +{ +namespace core +{ + + //! 4x4 matrix. Mostly used as transformation matrix for 3d calculations. + /* Matrix4 is mainly used by the Irrlicht engine for doing transformations. + The matrix is a D3D style matrix, row major with translations in the 4th row. + */ + template + class CMatrix4 + { + public: + + //! Constructor Flags + enum eConstructor + { + EM4CONST_NOTHING = 0, + EM4CONST_COPY, + EM4CONST_IDENTITY, + EM4CONST_TRANSPOSED, + EM4CONST_INVERSE, + EM4CONST_INVERSE_TRANSPOSED + }; + + CMatrix4( eConstructor constructor = EM4CONST_IDENTITY ); + CMatrix4( const CMatrix4& other,eConstructor constructor = EM4CONST_COPY); + + //! Simple operator for directly accessing every element of the matrix. + T& operator()(const s32 row, const s32 col) { definitelyIdentityMatrix=false; return M[ row * 4 + col ]; } + + //! Simple operator for directly accessing every element of the matrix. + const T& operator()(const s32 row, const s32 col) const { return M[row * 4 + col]; } + + //! Simple operator for linearly accessing every element of the matrix. + T& operator[](u32 index) { definitelyIdentityMatrix=false; return M[index]; } + + //! Simple operator for linearly accessing every element of the matrix. + const T& operator[](u32 index) const { return M[index]; } + + //! Sets this matrix equal to the other matrix. + inline CMatrix4& operator=(const CMatrix4 &other); + + //! Sets all elements of this matrix to the value. + inline CMatrix4& operator=(const T& scalar); + + //! Returns pointer to internal array + const T* pointer() const { return M; } + T* pointer() { definitelyIdentityMatrix=false; return M; } + + //! Returns true if other matrix is equal to this matrix. + bool operator==(const CMatrix4 &other) const; + + //! Returns true if other matrix is not equal to this matrix. + bool operator!=(const CMatrix4 &other) const; + + //! Add another matrix. + CMatrix4 operator+(const CMatrix4& other) const; + + //! Add another matrix. + CMatrix4& operator+=(const CMatrix4& other); + + //! Subtract another matrix. + CMatrix4 operator-(const CMatrix4& other) const; + + //! Subtract another matrix. + CMatrix4& operator-=(const CMatrix4& other); + + //! set this matrix to the product of two matrices + inline void setbyproduct(const CMatrix4& other_a,const CMatrix4& other_b ); + + //! set this matrix to the product of two matrices, no logical optimation + //! use it if you know you never have a identity matrix + void setbyproduct_nocheck(const CMatrix4& other_a,const CMatrix4& other_b ); + + //! Multiply by another matrix. + CMatrix4 operator*(const CMatrix4& other) const; + + //! Multiply by another matrix. + CMatrix4& operator*=(const CMatrix4& other); + + //! Multiply by scalar. + CMatrix4 operator*(const T& scalar) const; + + //! Multiply by scalar. + CMatrix4& operator*=(const T& scalar); + + //! Set matrix to identity. + inline void makeIdentity(); + + //! Returns true if the matrix is the identity matrix + inline bool isIdentity() const; + + //! Returns true if the matrix is the identity matrix + bool isIdentity_integer_base () const; + + //! Set the translation of the current matrix. Will erase any previous values. + void setTranslation( const vector3d& translation ); + + //! Gets the current translation + vector3d getTranslation() const; + + //! Set the inverse translation of the current matrix. Will erase any previous values. + void setInverseTranslation( const vector3d& translation ); + + //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. + inline void setRotationRadians( const vector3d& rotation ); + + //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. + void setRotationDegrees( const vector3d& rotation ); + + //! Returns the rotation, as set by setRotation(). This code was orginally written by by Chev. + core::vector3d getRotationDegrees() const; + + //! Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified. + inline void setInverseRotationRadians( const vector3d& rotation ); + + //! Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified. + void setInverseRotationDegrees( const vector3d& rotation ); + + //! Set Scale + void setScale( const vector3d& scale ); + + //! Get Scale + core::vector3d getScale() const; + + //! Translate a vector by the inverse of the translation part of this matrix. + void inverseTranslateVect( vector3df& vect ) const; + + //! Rotate a vector by the inverse of the rotation part of this matrix. + void inverseRotateVect( vector3df& vect ) const; + + //! Rotate a vector by the rotation part of this matrix. + void rotateVect( vector3df& vect ) const; + + //! An alternate transform vector method, writing into a second vector + void rotateVect(vector3df& out,const core::vector3df& in) const; + + //! An alternate transform vector method, writing into an array of 3 floats + void rotateVect(T *out,const core::vector3df &in) const; + + //! Transforms the vector by this matrix + void transformVect( vector3df& vect) const; + + //! Transforms input vector by this matrix and stores result in output vector + void transformVect( vector3df& out, const vector3df& in ) const; + + //! An alternate transform vector method, writing into an array of 4 floats + void transformVect(T *out,const core::vector3df &in) const; + + //! Translate a vector by the translation part of this matrix. + void translateVect( vector3df& vect ) const; + + //! Transforms a plane by this matrix + void transformPlane( core::plane3d &plane) const; + + //! Transforms a plane by this matrix ( some problems to solve..) + void transformPlane_new( core::plane3d &plane) const; + + //! Transforms a plane by this matrix + void transformPlane( const core::plane3d &in, core::plane3d &out) const; + + //! Transforms a axis aligned bounding box + /** The result box of this operation may not be very accurate. For + accurate results, use transformBoxEx() */ + void transformBox(core::aabbox3d& box) const; + + //! Transforms a axis aligned bounding box more accurately than transformBox() + /** The result box of this operation should by quite accurate, but this operation + is slower than transformBox(). */ + void transformBoxEx(core::aabbox3d& box) const; + + //! Multiplies this matrix by a 1x4 matrix + void multiplyWith1x4Matrix(T* matrix) const; + + //! Calculates inverse of matrix. Slow. + //! \return Returns false if there is no inverse matrix. + bool makeInverse(); + + + //! Inverts a primitive matrix which only contains a translation and a rotation + //! \param out: where result matrix is written to. + bool getInversePrimitive ( CMatrix4& out ) const; + + //! returns the inversed matrix of this one + //! \param out: where result matrix is written to. + //! \return Returns false if there is no inverse matrix. + bool getInverse(CMatrix4& out) const; + + //! Builds a right-handed perspective projection matrix based on a field of view + void buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar); + + //! Builds a left-handed perspective projection matrix based on a field of view + void buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar); + + //! Builds a right-handed perspective projection matrix. + void buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed perspective projection matrix. + void buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed orthogonal projection matrix. + void buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a right-handed orthogonal projection matrix. + void buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar); + + //! Builds a left-handed look-at matrix. + void buildCameraLookAtMatrixLH(const vector3df& position, const vector3df& target, const vector3df& upVector); + + //! Builds a right-handed look-at matrix. + void buildCameraLookAtMatrixRH(const vector3df& position, const vector3df& target, const vector3df& upVector); + + //! Builds a matrix that flattens geometry into a plane. + //! \param light: light source + //! \param plane: plane into which the geometry if flattened into + //! \param point: value between 0 and 1, describing the light source. + //! If this is 1, it is a point light, if it is 0, it is a directional light. + void buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f); + + //! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates. + /** Used to scale <-1,-1><1,1> to viewport, for example from von <-1,-1> <1,1> to the viewport <0,0><0,640> */ + void buildNDCToDCMatrix( const core::rect& area, f32 zScale); + + //! creates a new matrix as interpolated matrix from two other ones. + //! \param b: other matrix to interpolate with + //! \param time: Must be a value between 0 and 1. + CMatrix4 interpolate(const core::CMatrix4& b, f32 time) const; + + //! returns transposed matrix + CMatrix4 getTransposed() const; + + //! returns transposed matrix to a plain 4x4 float matrix + inline void getTransposed( CMatrix4& dest ) const; + + /*! + construct 2D Texture transformations + rotate about center, scale, and transform. + */ + void setTextureScale( f32 sx, f32 sy ); + + void setTextureRotationCenter( f32 radAngle ); + void setTextureScaleCenter( f32 sx, f32 sy ); + + void setTextureTranslate( f32 x, f32 y ); + + void buildTextureTransform( f32 rotateRad, + const core::vector2df &rotatecenter, + const core::vector2df &translate, + const core::vector2df &scale); + + //! sets all matrix data members at once + void setM(const T* data); + + //! sets if the matrix is definitely identity matrix + void setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix); + + //! gets if the matrix is definitely identity matrix + bool getDefinitelyIdentityMatrix() const; + + private: + //! Matrix data, stored in row-major order + T M[16]; + mutable bool definitelyIdentityMatrix; + }; + + template + inline CMatrix4::CMatrix4( eConstructor constructor ) : definitelyIdentityMatrix(false) + { + switch ( constructor ) + { + case EM4CONST_NOTHING: + case EM4CONST_COPY: + break; + case EM4CONST_IDENTITY: + case EM4CONST_INVERSE: + default: + makeIdentity(); + break; + } + } + + template + inline CMatrix4::CMatrix4( const CMatrix4& other, eConstructor constructor) : definitelyIdentityMatrix(false) + { + switch ( constructor ) + { + case EM4CONST_IDENTITY: + makeIdentity(); + break; + case EM4CONST_NOTHING: + break; + case EM4CONST_COPY: + *this = other; + break; + case EM4CONST_TRANSPOSED: + other.getTransposed(*this); + break; + case EM4CONST_INVERSE: + if (!other.getInverse(*this)) + memset(M, 0, 16*sizeof(T)); + break; + case EM4CONST_INVERSE_TRANSPOSED: + if (!other.getInverse(*this)) + memset(M, 0, 16*sizeof(T)); + else + *this=getTransposed(); + break; + } + } + + //! Add another matrix. + template + inline CMatrix4 CMatrix4::operator+(const CMatrix4& other) const + { + CMatrix4 temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]+other[0]; + temp[1] = M[1]+other[1]; + temp[2] = M[2]+other[2]; + temp[3] = M[3]+other[3]; + temp[4] = M[4]+other[4]; + temp[5] = M[5]+other[5]; + temp[6] = M[6]+other[6]; + temp[7] = M[7]+other[7]; + temp[8] = M[8]+other[8]; + temp[9] = M[9]+other[9]; + temp[10] = M[10]+other[10]; + temp[11] = M[11]+other[11]; + temp[12] = M[12]+other[12]; + temp[13] = M[13]+other[13]; + temp[14] = M[14]+other[14]; + temp[15] = M[15]+other[15]; + + return temp; + } + + //! Add another matrix. + template + inline CMatrix4& CMatrix4::operator+=(const CMatrix4& other) + { + M[0]+=other[0]; + M[1]+=other[1]; + M[2]+=other[2]; + M[3]+=other[3]; + M[4]+=other[4]; + M[5]+=other[5]; + M[6]+=other[6]; + M[7]+=other[7]; + M[8]+=other[8]; + M[9]+=other[9]; + M[10]+=other[10]; + M[11]+=other[11]; + M[12]+=other[12]; + M[13]+=other[13]; + M[14]+=other[14]; + M[15]+=other[15]; + + return *this; + } + + //! Subtract another matrix. + template + inline CMatrix4 CMatrix4::operator-(const CMatrix4& other) const + { + CMatrix4 temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]-other[0]; + temp[1] = M[1]-other[1]; + temp[2] = M[2]-other[2]; + temp[3] = M[3]-other[3]; + temp[4] = M[4]-other[4]; + temp[5] = M[5]-other[5]; + temp[6] = M[6]-other[6]; + temp[7] = M[7]-other[7]; + temp[8] = M[8]-other[8]; + temp[9] = M[9]-other[9]; + temp[10] = M[10]-other[10]; + temp[11] = M[11]-other[11]; + temp[12] = M[12]-other[12]; + temp[13] = M[13]-other[13]; + temp[14] = M[14]-other[14]; + temp[15] = M[15]-other[15]; + + return temp; + } + + //! Subtract another matrix. + template + inline CMatrix4& CMatrix4::operator-=(const CMatrix4& other) + { + M[0]-=other[0]; + M[1]-=other[1]; + M[2]-=other[2]; + M[3]-=other[3]; + M[4]-=other[4]; + M[5]-=other[5]; + M[6]-=other[6]; + M[7]-=other[7]; + M[8]-=other[8]; + M[9]-=other[9]; + M[10]-=other[10]; + M[11]-=other[11]; + M[12]-=other[12]; + M[13]-=other[13]; + M[14]-=other[14]; + M[15]-=other[15]; + + return *this; + } + + //! Multiply by scalar. + template + inline CMatrix4 CMatrix4::operator*(const T& scalar) const + { + CMatrix4 temp ( EM4CONST_NOTHING ); + + temp[0] = M[0]*scalar; + temp[1] = M[1]*scalar; + temp[2] = M[2]*scalar; + temp[3] = M[3]*scalar; + temp[4] = M[4]*scalar; + temp[5] = M[5]*scalar; + temp[6] = M[6]*scalar; + temp[7] = M[7]*scalar; + temp[8] = M[8]*scalar; + temp[9] = M[9]*scalar; + temp[10] = M[10]*scalar; + temp[11] = M[11]*scalar; + temp[12] = M[12]*scalar; + temp[13] = M[13]*scalar; + temp[14] = M[14]*scalar; + temp[15] = M[15]*scalar; + + return temp; + } + + //! Multiply by scalar. + template + inline CMatrix4& CMatrix4::operator*=(const T& scalar) + { + M[0]*=scalar; + M[1]*=scalar; + M[2]*=scalar; + M[3]*=scalar; + M[4]*=scalar; + M[5]*=scalar; + M[6]*=scalar; + M[7]*=scalar; + M[8]*=scalar; + M[9]*=scalar; + M[10]*=scalar; + M[11]*=scalar; + M[12]*=scalar; + M[13]*=scalar; + M[14]*=scalar; + M[15]*=scalar; + + return *this; + } + + //! Multiply by another matrix. + template + inline CMatrix4& CMatrix4::operator*=(const CMatrix4& other) + { + // do chacks on your own in order to avoid copy creation + if ( !other.isIdentity() ) + { + if ( this->isIdentity() ) + { + *this = other; + } + else + { + CMatrix4 temp ( *this ); + setbyproduct_nocheck( temp, other ); + } + } + return *this; + } + + //! multiply by another matrix + // set this matrix to the product of two other matrices + // goal is to reduce stack use and copy + template + inline void CMatrix4::setbyproduct_nocheck(const CMatrix4& other_a,const CMatrix4& other_b ) + { + const T *m1 = other_a.M; + const T *m2 = other_b.M; + + M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; + M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; + M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; + M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; + + M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; + M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; + M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; + M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; + + M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; + M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; + M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; + M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; + + M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; + M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; + M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; + M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; + definitelyIdentityMatrix=false; + } + + + //! multiply by another matrix + // set this matrix to the product of two other matrices + // goal is to reduce stack use and copy + template + inline void CMatrix4::setbyproduct(const CMatrix4& other_a,const CMatrix4& other_b ) + { + if ( other_a.isIdentity () ) + { + *this = other_b; + return; + } + else + if ( other_b.isIdentity () ) + { + *this = other_a; + return; + } + setbyproduct_nocheck(other_a,other_b); + } + + //! multiply by another matrix + template + inline CMatrix4 CMatrix4::operator*(const CMatrix4& m2) const + { + // Testing purpose.. + if ( this->isIdentity() ) + return m2; + if ( m2.isIdentity() ) + return *this; + + CMatrix4 m3 ( EM4CONST_NOTHING ); + + const T *m1 = M; + + m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; + m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; + m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; + m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; + + m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; + m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; + m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; + m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; + + m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; + m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; + m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; + m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; + + m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; + m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; + m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; + m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; + return m3; + } + + + + template + inline vector3d CMatrix4::getTranslation() const + { + return vector3d(M[12], M[13], M[14]); + } + + + template + inline void CMatrix4::setTranslation( const vector3d& translation ) + { + M[12] = translation.X; + M[13] = translation.Y; + M[14] = translation.Z; + definitelyIdentityMatrix=false; + } + + template + inline void CMatrix4::setInverseTranslation( const vector3d& translation ) + { + M[12] = -translation.X; + M[13] = -translation.Y; + M[14] = -translation.Z; + definitelyIdentityMatrix=false; + } + + template + inline void CMatrix4::setScale( const vector3d& scale ) + { + M[0] = scale.X; + M[5] = scale.Y; + M[10] = scale.Z; + definitelyIdentityMatrix=false; + } + + template + inline vector3d CMatrix4::getScale() const + { + return vector3d(M[0],M[5],M[10]); + } + + template + inline void CMatrix4::setRotationDegrees( const vector3d& rotation ) + { + setRotationRadians( rotation * core::DEGTORAD ); + } + + template + inline void CMatrix4::setInverseRotationDegrees( const vector3d& rotation ) + { + setInverseRotationRadians( rotation * core::DEGTORAD ); + } + + template + inline void CMatrix4::setRotationRadians( const vector3d& rotation ) + { + f64 cr = cos( rotation.X ); + f64 sr = sin( rotation.X ); + f64 cp = cos( rotation.Y ); + f64 sp = sin( rotation.Y ); + f64 cy = cos( rotation.Z ); + f64 sy = sin( rotation.Z ); + + M[0] = (T)( cp*cy ); + M[1] = (T)( cp*sy ); + M[2] = (T)( -sp ); + + f64 srsp = sr*sp; + f64 crsp = cr*sp; + + M[4] = (T)( srsp*cy-cr*sy ); + M[5] = (T)( srsp*sy+cr*cy ); + M[6] = (T)( sr*cp ); + + M[8] = (T)( crsp*cy+sr*sy ); + M[9] = (T)( crsp*sy-sr*cy ); + M[10] = (T)( cr*cp ); + definitelyIdentityMatrix=false; + } + + + + //! Returns the rotation, as set by setRotation(). This code was sent + //! in by Chev. + template + inline core::vector3d CMatrix4::getRotationDegrees() const + { + const CMatrix4 &mat = *this; + + f64 Y = -asin(mat(0,2)); + f64 C = cos(Y); + Y *= RADTODEG64; + + f64 rotx, roty, X, Z; + + if (fabs(C)>0.0005f) + { + rotx = mat(2,2) / C; + roty = mat(1,2) / C; + X = atan2( roty, rotx ) * RADTODEG64; + rotx = mat(0,0) / C; + roty = mat(0,1) / C; + Z = atan2( roty, rotx ) * RADTODEG64; + } + else + { + X = 0.0; + rotx = mat(1,1); + roty = -mat(1,0); + Z = atan2( roty, rotx ) * RADTODEG64; + } + + // fix values that get below zero + // before it would set (!) values to 360 + // that where above 360: + if (X < 0.0) X += 360.0; + if (Y < 0.0) Y += 360.0; + if (Z < 0.0) Z += 360.0; + + return vector3d((f32)X,(f32)Y,(f32)Z); + } + + template + inline void CMatrix4::setInverseRotationRadians( const vector3d& rotation ) + { + f64 cr = cos( rotation.X ); + f64 sr = sin( rotation.X ); + f64 cp = cos( rotation.Y ); + f64 sp = sin( rotation.Y ); + f64 cy = cos( rotation.Z ); + f64 sy = sin( rotation.Z ); + + M[0] = (T)( cp*cy ); + M[4] = (T)( cp*sy ); + M[8] = (T)( -sp ); + + f64 srsp = sr*sp; + f64 crsp = cr*sp; + + M[1] = (T)( srsp*cy-cr*sy ); + M[5] = (T)( srsp*sy+cr*cy ); + M[9] = (T)( sr*cp ); + + M[2] = (T)( crsp*cy+sr*sy ); + M[6] = (T)( crsp*sy-sr*cy ); + M[10] = (T)( cr*cp ); + definitelyIdentityMatrix=false; + } + + + /*! + */ + template + inline void CMatrix4::makeIdentity() + { + memset(M, 0, 16*sizeof(T)); + M[0] = M[5] = M[10] = M[15] = (T)1; + definitelyIdentityMatrix=true; + } + + + /* + check identity with epsilon + solve floating range problems.. + */ + template + inline bool CMatrix4::isIdentity() const + { + if (definitelyIdentityMatrix) + return true; + if ( !equals ( M[ 0], (T)1 ) || + !equals ( M[ 5], (T)1 ) || + !equals ( M[10], (T)1 ) || + !equals ( M[15], (T)1 ) + ) + return false; + + for (s32 i=0; i<4; ++i) + for (s32 j=0; j<4; ++j) + if (j != i) + if (!iszero((*this)(i,j))) + return false; + + definitelyIdentityMatrix=true; + return true; + } + + /* + doesn't solve floating range problems.. + but takes care on +/- 0 on translation because we are changing it.. + reducing floating point branches + but it needs the floats in memory.. + */ + template + inline bool CMatrix4::isIdentity_integer_base() const + { + if (definitelyIdentityMatrix) + return true; + if(IR(M[0])!=F32_VALUE_1) return false; + if(IR(M[1])!=0) return false; + if(IR(M[2])!=0) return false; + if(IR(M[3])!=0) return false; + + if(IR(M[4])!=0) return false; + if(IR(M[5])!=F32_VALUE_1) return false; + if(IR(M[6])!=0) return false; + if(IR(M[7])!=0) return false; + + if(IR(M[8])!=0) return false; + if(IR(M[9])!=0) return false; + if(IR(M[10])!=F32_VALUE_1) return false; + if(IR(M[11])!=0) return false; + + if(IR(M[12])!=0) return false; + if(IR(M[13])!=0) return false; + if(IR(M[13])!=0) return false; + if(IR(M[15])!=F32_VALUE_1) return false; + definitelyIdentityMatrix=true; + return true; + } + + + + template + inline void CMatrix4::rotateVect( vector3df& vect ) const + { + vector3df tmp = vect; + vect.X = tmp.X*M[0] + tmp.Y*M[4] + tmp.Z*M[8]; + vect.Y = tmp.X*M[1] + tmp.Y*M[5] + tmp.Z*M[9]; + vect.Z = tmp.X*M[2] + tmp.Y*M[6] + tmp.Z*M[10]; + } + + //! An alternate transform vector method, writing into a second vector + template + inline void CMatrix4::rotateVect(core::vector3df& out, const core::vector3df& in) const + { + out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8]; + out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9]; + out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10]; + } + + //! An alternate transform vector method, writing into an array of 3 floats + template + inline void CMatrix4::rotateVect(T *out, const core::vector3df& in) const + { + out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8]; + out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9]; + out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10]; + } + + template + inline void CMatrix4::inverseRotateVect( vector3df& vect ) const + { + vector3df tmp = vect; + vect.X = tmp.X*M[0] + tmp.Y*M[1] + tmp.Z*M[2]; + vect.Y = tmp.X*M[4] + tmp.Y*M[5] + tmp.Z*M[6]; + vect.Z = tmp.X*M[8] + tmp.Y*M[9] + tmp.Z*M[10]; + } + + template + inline void CMatrix4::transformVect( vector3df& vect) const + { + f32 vector[3]; + + vector[0] = vect.X*M[0] + vect.Y*M[4] + vect.Z*M[8] + M[12]; + vector[1] = vect.X*M[1] + vect.Y*M[5] + vect.Z*M[9] + M[13]; + vector[2] = vect.X*M[2] + vect.Y*M[6] + vect.Z*M[10] + M[14]; + + vect.X = vector[0]; + vect.Y = vector[1]; + vect.Z = vector[2]; + } + + template + inline void CMatrix4::transformVect( vector3df& out, const vector3df& in) const + { + out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12]; + out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13]; + out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14]; + } + + + template + inline void CMatrix4::transformVect(T *out,const vector3df &in) const + { + out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12]; + out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13]; + out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14]; + out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15]; + } + + + //! Transforms a plane by this matrix + template + inline void CMatrix4::transformPlane( core::plane3d &plane) const + { + vector3df member; + transformVect(member, plane.getMemberPoint()); + + vector3df origin(0,0,0); + transformVect(plane.Normal); + transformVect(origin); + + plane.Normal -= origin; + plane.D = - member.dotProduct(plane.Normal); + } + + //! Transforms a plane by this matrix + template + inline void CMatrix4::transformPlane_new( core::plane3d &plane) const + { + // rotate normal -> rotateVect ( plane.n ); + vector3df n; + n.X = plane.Normal.X*M[0] + plane.Normal.Y*M[4] + plane.Normal.Z*M[8]; + n.Y = plane.Normal.X*M[1] + plane.Normal.Y*M[5] + plane.Normal.Z*M[9]; + n.Z = plane.Normal.X*M[2] + plane.Normal.Y*M[6] + plane.Normal.Z*M[10]; + + // compute new d. -> getTranslation(). dotproduct ( plane.n ) + plane.D -= M[12] * n.X + M[13] * n.Y + M[14] * n.Z; + plane.Normal.X = n.X; + plane.Normal.Y = n.Y; + plane.Normal.Z = n.Z; + } + + //! Transforms a plane by this matrix + template + inline void CMatrix4::transformPlane( const core::plane3d &in, core::plane3d &out) const + { + out = in; + transformPlane( out ); + } + + //! Transforms a axis aligned bounding box + template + inline void CMatrix4::transformBox(core::aabbox3d& box) const + { + if (isIdentity() ) + return; + + transformVect(box.MinEdge); + transformVect(box.MaxEdge); + box.repair(); + } + + //! Transforms a axis aligned bounding box more accurately than transformBox() + template + inline void CMatrix4::transformBoxEx(core::aabbox3d& box) const + { + f32 Amin[3]; + f32 Amax[3]; + f32 Bmin[3]; + f32 Bmax[3]; + + Amin[0] = box.MinEdge.X; + Amin[1] = box.MinEdge.Y; + Amin[2] = box.MinEdge.Z; + + Amax[0] = box.MaxEdge.X; + Amax[1] = box.MaxEdge.Y; + Amax[2] = box.MaxEdge.Z; + + Bmin[0] = Bmax[0] = M[12]; + Bmin[1] = Bmax[1] = M[13]; + Bmin[2] = Bmax[2] = M[14]; + + u32 i, j; + const CMatrix4 &m = *this; + + for (i = 0; i < 3; ++i) + { + for (j = 0; j < 3; ++j) + { + f32 a = m(j,i) * Amin[j]; + f32 b = m(j,i) * Amax[j]; + + if (a < b) + { + Bmin[i] += a; + Bmax[i] += b; + } + else + { + Bmin[i] += b; + Bmax[i] += a; + } + } + } + + box.MinEdge.X = Bmin[0]; + box.MinEdge.Y = Bmin[1]; + box.MinEdge.Z = Bmin[2]; + + box.MaxEdge.X = Bmax[0]; + box.MaxEdge.Y = Bmax[1]; + box.MaxEdge.Z = Bmax[2]; + } + + + //! Multiplies this matrix by a 1x4 matrix + template + inline void CMatrix4::multiplyWith1x4Matrix(T* matrix) const + { + /* + 0 1 2 3 + 4 5 6 7 + 8 9 10 11 + 12 13 14 15 + */ + + T mat[4]; + mat[0] = matrix[0]; + mat[1] = matrix[1]; + mat[2] = matrix[2]; + mat[3] = matrix[3]; + + matrix[0] = M[0]*mat[0] + M[4]*mat[1] + M[8]*mat[2] + M[12]*mat[3]; + matrix[1] = M[1]*mat[0] + M[5]*mat[1] + M[9]*mat[2] + M[13]*mat[3]; + matrix[2] = M[2]*mat[0] + M[6]*mat[1] + M[10]*mat[2] + M[14]*mat[3]; + matrix[3] = M[3]*mat[0] + M[7]*mat[1] + M[11]*mat[2] + M[15]*mat[3]; + } + + template + inline void CMatrix4::inverseTranslateVect( vector3df& vect ) const + { + vect.X = vect.X-M[12]; + vect.Y = vect.Y-M[13]; + vect.Z = vect.Z-M[14]; + } + + template + inline void CMatrix4::translateVect( vector3df& vect ) const + { + vect.X = vect.X+M[12]; + vect.Y = vect.Y+M[13]; + vect.Z = vect.Z+M[14]; + } + + + template + inline bool CMatrix4::getInverse(CMatrix4& out) const + { + /// Calculates the inverse of this Matrix + /// The inverse is calculated using Cramers rule. + /// If no inverse exists then 'false' is returned. + + if ( this->isIdentity() ) + { + out=*this; + return true; + } + + const CMatrix4 &m = *this; + + f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) - + (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) + + (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) + + (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) - + (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) + + (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)); + + if( core::iszero ( d ) ) + return false; + + d = core::reciprocal ( d ); + + out(0, 0) = d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) + m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) + m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1))); + out(0, 1) = d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) + m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) + m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1))); + out(0, 2) = d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) + m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) + m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1))); + out(0, 3) = d * (m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) + m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) + m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2))); + out(1, 0) = d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) + m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) + m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3))); + out(1, 1) = d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) + m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) + m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3))); + out(1, 2) = d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) + m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) + m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3))); + out(1, 3) = d * (m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) + m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2))); + out(2, 0) = d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) + m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) + m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3))); + out(2, 1) = d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) + m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) + m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3))); + out(2, 2) = d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) + m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) + m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3))); + out(2, 3) = d * (m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) + m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) + m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0))); + out(3, 0) = d * (m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) + m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) + m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1))); + out(3, 1) = d * (m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) + m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) + m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1))); + out(3, 2) = d * (m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) + m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) + m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1))); + out(3, 3) = d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) + m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))); + out.definitelyIdentityMatrix = definitelyIdentityMatrix; + return true; + } + + + //! Inverts a primitive matrix which only contains a translation and a rotation + //! \param out: where result matrix is written to. + template + inline bool CMatrix4::getInversePrimitive ( CMatrix4& out ) const + { + out.M[0 ] = M[0]; + out.M[1 ] = M[4]; + out.M[2 ] = M[8]; + out.M[3 ] = 0; + + out.M[4 ] = M[1]; + out.M[5 ] = M[5]; + out.M[6 ] = M[9]; + out.M[7 ] = 0; + + out.M[8 ] = M[2]; + out.M[9 ] = M[6]; + out.M[10] = M[10]; + out.M[11] = 0; + + out.M[12] = (T)-(M[12]*M[0] + M[13]*M[1] + M[14]*M[2]); + out.M[13] = (T)-(M[12]*M[4] + M[13]*M[5] + M[14]*M[6]); + out.M[14] = (T)-(M[12]*M[8] + M[13]*M[9] + M[14]*M[10]); + out.M[15] = 1; + out.definitelyIdentityMatrix = definitelyIdentityMatrix; + return true; + } + + /*! + */ + template + inline bool CMatrix4::makeInverse() + { + if (definitelyIdentityMatrix) + return true; + + CMatrix4 temp ( EM4CONST_NOTHING ); + + if (getInverse(temp)) + { + *this = temp; + return true; + } + + return false; + } + + + + template + inline CMatrix4& CMatrix4::operator=(const CMatrix4 &other) + { + if (this==&other) + return *this; + memcpy(M, other.M, 16*sizeof(T)); + definitelyIdentityMatrix=other.definitelyIdentityMatrix; + return *this; + } + + + + template + inline CMatrix4& CMatrix4::operator=(const T& scalar) + { + for (s32 i = 0; i < 16; ++i) + M[i]=scalar; + definitelyIdentityMatrix=false; + return *this; + } + + + + template + inline bool CMatrix4::operator==(const CMatrix4 &other) const + { + if (definitelyIdentityMatrix && other.definitelyIdentityMatrix) + return true; + for (s32 i = 0; i < 16; ++i) + if (M[i] != other.M[i]) + return false; + + return true; + } + + + + template + inline bool CMatrix4::operator!=(const CMatrix4 &other) const + { + return !(*this == other); + } + + + + //! Builds a right-handed perspective projection matrix based on a field of view + template + inline void CMatrix4::buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar) + { + f64 h = 1.0/tan(fieldOfViewRadians/2.0); + T w = h / aspectRatio; + + M[0] = w; + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)h; + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zNear-zFar)); // DirectX version +// M[10] = (T)(zFar+zNear/(zNear-zFar)); // OpenGL version + M[11] = -1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); // DirectX version +// M[14] = (T)(2.0f*zNear*zFar/(zNear-zFar)); // OpenGL version + M[15] = 0; + definitelyIdentityMatrix=false; + } + + + + //! Builds a left-handed perspective projection matrix based on a field of view + template + inline void CMatrix4::buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar) + { + f64 h = 1.0/tan(fieldOfViewRadians/2.0); + T w = (T)(h / aspectRatio); + + M[0] = w; + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)h; + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zFar-zNear)); + M[11] = 1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(-zNear*zFar/(zFar-zNear)); + M[15] = 0; + definitelyIdentityMatrix=false; + } + + + + //! Builds a left-handed orthogonal projection matrix. + template + inline void CMatrix4::buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + M[0] = (T)(2/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(1/(zFar-zNear)); + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear/(zNear-zFar)); + M[15] = 1; + definitelyIdentityMatrix=false; + } + + + + //! Builds a right-handed orthogonal projection matrix. + template + inline void CMatrix4::buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + M[0] = (T)(2/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(1/(zNear-zFar)); + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear/(zNear-zFar)); + M[15] = -1; + definitelyIdentityMatrix=false; + } + + + //! Builds a right-handed perspective projection matrix. + template + inline void CMatrix4::buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + M[0] = (T)(2*zNear/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2*zNear/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zNear-zFar)); + M[11] = -1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); + M[15] = 0; + definitelyIdentityMatrix=false; + } + + + //! Builds a left-handed perspective projection matrix. + template + inline void CMatrix4::buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar) + { + M[0] = (T)(2*zNear/widthOfViewVolume); + M[1] = 0; + M[2] = 0; + M[3] = 0; + + M[4] = 0; + M[5] = (T)(2*zNear/heightOfViewVolume); + M[6] = 0; + M[7] = 0; + + M[8] = 0; + M[9] = 0; + M[10] = (T)(zFar/(zFar-zNear)); + M[11] = 1; + + M[12] = 0; + M[13] = 0; + M[14] = (T)(zNear*zFar/(zNear-zFar)); + M[15] = 0; + definitelyIdentityMatrix=false; + } + + + //! Builds a matrix that flattens geometry into a plane. + template + inline void CMatrix4::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point) + { + plane.Normal.normalize(); + f32 d = plane.Normal.dotProduct(light); + + M[ 0] = (T)(-plane.Normal.X * light.X + d); + M[ 1] = (T)(-plane.Normal.X * light.Y); + M[ 2] = (T)(-plane.Normal.X * light.Z); + M[ 3] = (T)(-plane.Normal.X * point); + + M[ 4] = (T)(-plane.Normal.Y * light.X); + M[ 5] = (T)(-plane.Normal.Y * light.Y + d); + M[ 6] = (T)(-plane.Normal.Y * light.Z); + M[ 7] = (T)(-plane.Normal.Y * point); + + M[ 8] = (T)(-plane.Normal.Z * light.X); + M[ 9] = (T)(-plane.Normal.Z * light.Y); + M[10] = (T)(-plane.Normal.Z * light.Z + d); + M[11] = (T)(-plane.Normal.Z * point); + + M[12] = (T)(-plane.D * light.X); + M[13] = (T)(-plane.D * light.Y); + M[14] = (T)(-plane.D * light.Z); + M[15] = (T)(-plane.D * point + d); + definitelyIdentityMatrix=false; + } + + //! Builds a left-handed look-at matrix. + template + inline void CMatrix4::buildCameraLookAtMatrixLH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector) + { + vector3df zaxis = target - position; + zaxis.normalize(); + + vector3df xaxis = upVector.crossProduct(zaxis); + xaxis.normalize(); + + vector3df yaxis = zaxis.crossProduct(xaxis); + + M[0] = (T)xaxis.X; + M[1] = (T)yaxis.X; + M[2] = (T)zaxis.X; + M[3] = 0; + + M[4] = (T)xaxis.Y; + M[5] = (T)yaxis.Y; + M[6] = (T)zaxis.Y; + M[7] = 0; + + M[8] = (T)xaxis.Z; + M[9] = (T)yaxis.Z; + M[10] = (T)zaxis.Z; + M[11] = 0; + + M[12] = (T)-xaxis.dotProduct(position); + M[13] = (T)-yaxis.dotProduct(position); + M[14] = (T)-zaxis.dotProduct(position); + M[15] = 1; + definitelyIdentityMatrix=false; + } + + + + //! Builds a right-handed look-at matrix. + template + inline void CMatrix4::buildCameraLookAtMatrixRH( + const vector3df& position, + const vector3df& target, + const vector3df& upVector) + { + vector3df zaxis = position - target; + zaxis.normalize(); + + vector3df xaxis = upVector.crossProduct(zaxis); + xaxis.normalize(); + + vector3df yaxis = zaxis.crossProduct(xaxis); + + M[0] = (T)xaxis.X; + M[1] = (T)yaxis.X; + M[2] = (T)zaxis.X; + M[3] = 0; + + M[4] = (T)xaxis.Y; + M[5] = (T)yaxis.Y; + M[6] = (T)zaxis.Y; + M[7] = 0; + + M[8] = (T)xaxis.Z; + M[9] = (T)yaxis.Z; + M[10] = (T)zaxis.Z; + M[11] = 0; + + M[12] = (T)-xaxis.dotProduct(position); + M[13] = (T)-yaxis.dotProduct(position); + M[14] = (T)-zaxis.dotProduct(position); + M[15] = 1; + definitelyIdentityMatrix=false; + } + + + //! creates a new matrix as interpolated matrix from to other ones. + //! \param time: Must be a value between 0 and 1. + template + inline CMatrix4 CMatrix4::interpolate(const core::CMatrix4& b, f32 time) const + { + CMatrix4 mat ( EM4CONST_NOTHING ); + + for (u32 i=0; i < 16; i += 4) + { + mat.M[i+0] = (T)(M[i+0] + ( b.M[i+0] - M[i+0] ) * time); + mat.M[i+1] = (T)(M[i+1] + ( b.M[i+1] - M[i+1] ) * time); + mat.M[i+2] = (T)(M[i+2] + ( b.M[i+2] - M[i+2] ) * time); + mat.M[i+3] = (T)(M[i+3] + ( b.M[i+3] - M[i+3] ) * time); + } + return mat; + } + + //! returns transposed matrix + template + inline CMatrix4 CMatrix4::getTransposed() const + { + CMatrix4 t ( EM4CONST_NOTHING ); + getTransposed ( t ); + return t; + } + + //! returns transposed matrix + template + inline void CMatrix4::getTransposed( CMatrix4& o ) const + { + o[ 0] = M[ 0]; + o[ 1] = M[ 4]; + o[ 2] = M[ 8]; + o[ 3] = M[12]; + + o[ 4] = M[ 1]; + o[ 5] = M[ 5]; + o[ 6] = M[ 9]; + o[ 7] = M[13]; + + o[ 8] = M[ 2]; + o[ 9] = M[ 6]; + o[10] = M[10]; + o[11] = M[14]; + + o[12] = M[ 3]; + o[13] = M[ 7]; + o[14] = M[11]; + o[15] = M[15]; + o.definitelyIdentityMatrix=definitelyIdentityMatrix; + } + + + // used to scale <-1,-1><1,1> to viewport + template + inline void CMatrix4::buildNDCToDCMatrix( const core::rect& viewport, f32 zScale) + { + f32 scaleX = (viewport.getWidth() - 0.75f ) / 2.0f; + f32 scaleY = -(viewport.getHeight() - 0.75f ) / 2.0f; + + f32 dx = -0.5f + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) / 2.0f ); + f32 dy = -0.5f + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) / 2.0f ); + + makeIdentity(); + M[0] = (T)scaleX; + M[5] = (T)scaleY; + M[10] = (T)zScale; + M[12] = (T)dx; + M[13] = (T)dy; + definitelyIdentityMatrix=false; + } + + /*! + Generate texture coordinates as linear functions so that: + u = Ux*x + Uy*y + Uz*z + Uw + v = Vx*x + Vy*y + Vz*z + Vw + The matrix M for this case is: + Ux Vx 0 0 + Uy Vy 0 0 + Uz Vz 0 0 + Uw Vw 0 0 + */ + + template + inline void CMatrix4::buildTextureTransform( f32 rotateRad, + const core::vector2df &rotatecenter, + const core::vector2df &translate, + const core::vector2df &scale) + { + const f32 c = cosf(rotateRad); + const f32 s = sinf(rotateRad); + + M[0] = (T)(c * scale.X); + M[1] = (T)(s * scale.Y); + M[2] = 0; + M[3] = 0; + + M[4] = (T)(-s * scale.X); + M[5] = (T)(c * scale.Y); + M[6] = 0; + M[7] = 0; + + M[8] = (T)(c * scale.X * rotatecenter.X + -s * rotatecenter.Y + translate.X); + M[9] = (T)(s * scale.Y * rotatecenter.X + c * rotatecenter.Y + translate.Y); + M[10] = 1; + M[11] = 0; + + M[12] = 0; + M[13] = 0; + M[14] = 0; + M[15] = 1; + definitelyIdentityMatrix=false; + } + + //! rotate about z axis, center ( 0.5, 0.5 ) + template + inline void CMatrix4::setTextureRotationCenter( f32 rotateRad ) + { + const f32 c = cosf(rotateRad); + const f32 s = sinf(rotateRad); + M[0] = (T)c; + M[1] = (T)s; + M[2] = (T)(-0.5f * ( c + s) + 0.5f); + + M[4] = (T)-s; + M[5] = (T)c; + M[6] = (T)(-0.5f * (-s + c) + 0.5f); + definitelyIdentityMatrix=false; + } + + template + inline void CMatrix4::setTextureTranslate ( f32 x, f32 y ) + { + M[8] = (T)x; + M[9] = (T)y; + definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ; + } + + template + inline void CMatrix4::setTextureScale ( f32 sx, f32 sy ) + { + M[0] = (T)sx; + M[5] = (T)sy; + definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f) ; + } + + template + inline void CMatrix4::setTextureScaleCenter( f32 sx, f32 sy ) + { + M[0] = (T)sx; + M[2] = (T)(-0.5f * sx + 0.5f); + M[5] = (T)sy; + M[6] = (T)(-0.5f * sy + 0.5f); + definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f) ; + } + + //! sets all matrix data members at once + template + inline void CMatrix4::setM(const T* data) + { + for (u32 i = 0; i < 16; ++i) + M[i] = data[i]; + + definitelyIdentityMatrix = false; + } + + //! sets if the matrix is definitely identity matrix + template + inline void CMatrix4::setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix) + { + definitelyIdentityMatrix = isDefinitelyIdentityMatrix; + } + + //! gets if the matrix is definitely identity matrix + template + inline bool CMatrix4::getDefinitelyIdentityMatrix() const + { + return definitelyIdentityMatrix; + } + + //! Multiply by scalar. + template + inline CMatrix4 operator*(const T scalar, const CMatrix4& mat) + { + return mat*scalar; + } + + typedef CMatrix4 matrix4; + const matrix4 IdentityMatrix(matrix4::EM4CONST_IDENTITY); + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/plane3d.h b/src/dep/include/irrlicht/plane3d.h new file mode 100644 index 0000000..d4d9526 --- /dev/null +++ b/src/dep/include/irrlicht/plane3d.h @@ -0,0 +1,224 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_PLANE_3D_H_INCLUDED__ +#define __IRR_PLANE_3D_H_INCLUDED__ + +#include "irrMath.h" +#include "vector3d.h" + +namespace irr +{ +namespace core +{ + +//! Enumeration for intersection relations of 3d objects +enum EIntersectionRelation3D +{ + ISREL3D_FRONT = 0, + ISREL3D_BACK, + ISREL3D_PLANAR, + ISREL3D_SPANNING, + ISREL3D_CLIPPED +}; + +//! Template plane class with some intersection testing methods. +template +class plane3d +{ + public: + + // Constructors + + plane3d(): Normal(0,1,0) { recalculateD(vector3d(0,0,0)); } + plane3d(const vector3d& MPoint, const vector3d& Normal) : Normal(Normal) { recalculateD(MPoint); } + plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d(px, py, pz)); } + plane3d(const vector3d& point1, const vector3d& point2, const vector3d& point3) { setPlane(point1, point2, point3); } + + // operators + + inline bool operator==(const plane3d& other) const { return (D==other.D && Normal==other.Normal);} + inline bool operator!=(const plane3d& other) const { return !(D==other.D && Normal==other.Normal);} + + // functions + + void setPlane(const vector3d& point, const vector3d& nvector) + { + Normal = nvector; + recalculateD(point); + } + + void setPlane(const vector3d& nvect, T d) + { + Normal = nvect; + D = d; + } + + void setPlane(const vector3d& point1, const vector3d& point2, const vector3d& point3) + { + // creates the plane from 3 memberpoints + Normal = (point2 - point1).crossProduct(point3 - point1); + Normal.normalize(); + + recalculateD(point1); + } + + + //! Returns an intersection with a 3d line. + //! \param lineVect: Vector of the line to intersect with. + //! \param linePoint: Point of the line to intersect with. + //! \param outIntersection: Place to store the intersection point, if there is one. + //! \return Returns true if there was an intersection, false if there was not. + bool getIntersectionWithLine(const vector3d& linePoint, const vector3d& lineVect, + vector3d& outIntersection) const + { + T t2 = Normal.dotProduct(lineVect); + + if (t2 == 0) + return false; + + T t =- (Normal.dotProduct(linePoint) + D) / t2; + outIntersection = linePoint + (lineVect * t); + return true; + } + + //! Returns where on a line between two points an intersection with this plane happened. + //! Only useful if known that there is an intersection. + //! \param linePoint1: Point1 of the line to intersect with. + //! \param linePoint2: Point2 of the line to intersect with. + //! \return Returns where on a line between two points an intersection with this plane happened. + //! For example, 0.5 is returned if the intersection happened exectly in the middle of the two points. + f32 getKnownIntersectionWithLine(const vector3d& linePoint1, + const vector3d& linePoint2) const + { + vector3d vect = linePoint2 - linePoint1; + T t2 = (f32)Normal.dotProduct(vect); + return (f32)-((Normal.dotProduct(linePoint1) + D) / t2); + } + + //! Returns an intersection with a 3d line, limited between two 3d points. + //! \param linePoint1: Point 1 of the line. + //! \param linePoint2: Point 2 of the line. + //! \param outIntersection: Place to store the intersection point, if there is one. + //! \return Returns true if there was an intersection, false if there was not. + bool getIntersectionWithLimitedLine( + const vector3d& linePoint1, + const vector3d& linePoint2, + vector3d& outIntersection) const + { + return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) && + outIntersection.isBetweenPoints(linePoint1, linePoint2)); + } + + //! Classifies the relation of a point to this plane. + //! \param point: Point to classify its relation. + //! \return Returns ISREL3D_FRONT if the point is in front of the plane, + //! ISREL3D_BACK if the point is behind of the plane, and + //! ISREL3D_PLANAR if the point is within the plane. + EIntersectionRelation3D classifyPointRelation(const vector3d& point) const + { + const T d = Normal.dotProduct(point) + D; + + if (d < -ROUNDING_ERROR_32) + return ISREL3D_BACK; + + if (d > ROUNDING_ERROR_32) + return ISREL3D_FRONT; + + return ISREL3D_PLANAR; + } + + //! Recalculates the distance from origin by applying + //! a new member point to the plane. + void recalculateD(const vector3d& MPoint) + { + D = - MPoint.dotProduct(Normal); + } + + //! Returns a member point of the plane. + vector3d getMemberPoint() const + { + return Normal * -D; + } + + //! Tests if there is an intersection between with the other plane + //! \return Returns true if there is a intersection. + bool existsIntersection(const plane3d& other) const + { + vector3d cross = other.Normal.crossProduct(Normal); + return cross.getLength() > core::ROUNDING_ERROR_32; + } + + //! Intersects this plane with another. + //! \return Returns true if there is a intersection, false if not. + bool getIntersectionWithPlane(const plane3d& other, vector3d& outLinePoint, + vector3d& outLineVect) const + { + T fn00 = Normal.getLength(); + T fn01 = Normal.dotProduct(other.Normal); + T fn11 = other.Normal.getLength(); + f64 det = fn00*fn11 - fn01*fn01; + + if (fabs(det) < ROUNDING_ERROR_64 ) + return false; + + det = 1.0 / det; + f64 fc0 = (fn11*-D + fn01*other.D) * det; + f64 fc1 = (fn00*-other.D + fn01*D) * det; + + outLineVect = Normal.crossProduct(other.Normal); + outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1; + return true; + } + + //! Returns the intersection point with two other planes if there is one. + bool getIntersectionWithPlanes(const plane3d& o1, + const plane3d& o2, vector3d& outPoint) const + { + vector3d linePoint, lineVect; + if (getIntersectionWithPlane(o1, linePoint, lineVect)) + return o2.getIntersectionWithLine(linePoint, lineVect, outPoint); + + return false; + } + + //! Test if the triangle would be front or backfacing from any + //! point. Thus, this method assumes a camera position from + //! which the triangle is definitely visible when looking into + //! the given direction. + //! Note that this only works if the normal is Normalized. + //! Do not use this method with points as it will give wrong results! + //! \param lookDirection: Look direction. + //! \return Returns true if the plane is front facing and + //! false if it is backfacing. + bool isFrontFacing(const vector3d& lookDirection) const + { + const f32 d = Normal.dotProduct(lookDirection); + return F32_LOWER_EQUAL_0 ( d ); + } + + //! Returns the distance to a point. Note that this only + //! works if the normal is Normalized. + T getDistanceTo(const vector3d& point) const + { + return point.dotProduct(Normal) + D; + } + + // member variables + + vector3d Normal; // normal vector + T D; // distance from origin +}; + + +//! Typedef for a f32 3d plane. +typedef plane3d plane3df; +//! Typedef for an integer 3d plane. +typedef plane3d plane3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/position2d.h b/src/dep/include/irrlicht/position2d.h new file mode 100644 index 0000000..5eb96c0 --- /dev/null +++ b/src/dep/include/irrlicht/position2d.h @@ -0,0 +1,116 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_POSITION_H_INCLUDED__ +#define __IRR_POSITION_H_INCLUDED__ + +#include "irrTypes.h" +#include "dimension2d.h" + +namespace irr +{ +namespace core +{ + + //! Simple class for holding 2d coordinates. + /** Not supposed for doing geometric calculations. + use vector2d instead for things like that. + */ + template + class position2d + { + public: + position2d() : X(0), Y(0) {} + position2d(T x, T y) : X(x), Y(y) {} + position2d(const position2d& other) + : X(other.X), Y(other.Y) {} + + bool operator == (const position2d& other) const + { + return X == other.X && Y == other.Y; + } + + bool operator != (const position2d& other) const + { + return X != other.X || Y != other.Y; + } + + const position2d& operator+=(const position2d& other) + { + X += other.X; + Y += other.Y; + return *this; + } + + const position2d& operator-=(const position2d& other) + { + X -= other.X; + Y -= other.Y; + return *this; + } + + const position2d& operator+=(const dimension2d& other) + { + X += other.Width; + Y += other.Height; + return *this; + } + + const position2d& operator-=(const dimension2d& other) + { + X -= other.Width; + Y -= other.Height; + return *this; + } + + position2d operator-(const position2d& other) const + { + return position2d(X-other.X, Y-other.Y); + } + + position2d operator+(const position2d& other) const + { + return position2d(X+other.X, Y+other.Y); + } + + position2d operator*(const position2d& other) const + { + return position2d(X*other.X, Y*other.Y); + } + + position2d operator*(const T& scalar) const + { + return position2d(X*scalar, Y*scalar); + } + + position2d operator+(const dimension2d& other) const + { + return position2d(X+other.Width, Y+other.Height); + } + + position2d operator-(const dimension2d& other) const + { + return position2d(X-other.Width, Y-other.Height); + } + + const position2d& operator=(const position2d& other) + { + X = other.X; + Y = other.Y; + return *this; + } + + T X, Y; + }; + + //! Typedef for a f32 position. + typedef position2d position2df; + //! Typedef for an integer position. + typedef position2d position2di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/quaternion.h b/src/dep/include/irrlicht/quaternion.h new file mode 100644 index 0000000..354d6a8 --- /dev/null +++ b/src/dep/include/irrlicht/quaternion.h @@ -0,0 +1,563 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_QUATERNION_H_INCLUDED__ +#define __IRR_QUATERNION_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" +#include "matrix4.h" +#include "vector3d.h" + +namespace irr +{ +namespace core +{ + +//! Quaternion class. +class quaternion +{ + public: + + //! Default Constructor + quaternion() : X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {} + + //! Constructor + quaternion(f32 x, f32 y, f32 z, f32 w) : X(x), Y(y), Z(z), W(w) { } + + //! Constructor which converts euler angles (radians) to a quaternion + quaternion(f32 x, f32 y, f32 z); + + //! Constructor which converts euler angles (radians) to a quaternion + quaternion(const vector3df& vec); + + //! Constructor which converts a matrix to a quaternion + quaternion(const matrix4& mat); + + //! equal operator + bool operator==(const quaternion& other) const; + + //! assignment operator + inline quaternion& operator=(const quaternion& other); + + //! matrix assignment operator + inline quaternion& operator=(const matrix4& other); + + //! add operator + quaternion operator+(const quaternion& other) const; + + //! multiplication operator + quaternion operator*(const quaternion& other) const; + + //! multiplication operator + quaternion operator*(f32 s) const; + + //! multiplication operator + quaternion& operator*=(f32 s); + + //! multiplication operator + vector3df operator* (const vector3df& v) const; + + //! multiplication operator + quaternion& operator*=(const quaternion& other); + + //! calculates the dot product + inline f32 getDotProduct(const quaternion& other) const; + + //! sets new quaternion + inline void set(f32 x, f32 y, f32 z, f32 w); + + //! sets new quaternion based on euler angles (radians) + inline void set(f32 x, f32 y, f32 z); + + //! sets new quaternion based on euler angles (radians) + inline void set(const core::vector3df& vec); + + //! normalizes the quaternion + inline quaternion& normalize(); + + //! Creates a matrix from this quaternion + matrix4 getMatrix() const; + + //! Creates a matrix from this quaternion + void getMatrix( matrix4 &dest ) const; + + //! Creates a matrix from this quaternion + void getMatrix_transposed( matrix4 &dest ) const; + + //! Inverts this quaternion + void makeInverse(); + + //! set this quaternion to the result of the interpolation between two quaternions + void slerp( quaternion q1, quaternion q2, f32 interpolate ); + + //! axis must be unit length + //! The quaternion representing the rotation is + //! q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k) + void fromAngleAxis (f32 angle, const vector3df& axis); + + //! Fills an angle (radians) around an axis (unit vector) + void toAngleAxis (f32 &angle, vector3df& axis) const; + + //! Output this quaternion to an euler angle (radians) + void toEuler(vector3df& euler) const; + + //! set quaternion to identity + void makeIdentity(); + + //! sets quaternion to represent a rotation from one angle to another + void rotationFromTo(const vector3df& from, const vector3df& to); + + f32 X, Y, Z, W; +}; + + +//! Constructor which converts euler angles to a quaternion +inline quaternion::quaternion(f32 x, f32 y, f32 z) +{ + set(x,y,z); +} + + +//! Constructor which converts euler angles to a quaternion +inline quaternion::quaternion(const vector3df& vec) +{ + set(vec.X,vec.Y,vec.Z); +} + + +//! Constructor which converts a matrix to a quaternion +inline quaternion::quaternion(const matrix4& mat) +{ + (*this) = mat; +} + + +//! equal operator +inline bool quaternion::operator==(const quaternion& other) const +{ + if(X != other.X) + return false; + if(Y != other.Y) + return false; + if(Z != other.Z) + return false; + if(W != other.W) + return false; + + return true; +} + + +//! assignment operator +inline quaternion& quaternion::operator=(const quaternion& other) +{ + X = other.X; + Y = other.Y; + Z = other.Z; + W = other.W; + return *this; +} + + +//! matrix assignment operator +inline quaternion& quaternion::operator=(const matrix4& m) +{ + f32 diag = m(0,0) + m(1,1) + m(2,2) + 1; + f32 scale = 0.0f; + + if( diag > 0.0f ) + { + scale = sqrtf(diag) * 2.0f; // get scale from diagonal + + // TODO: speed this up + X = ( m(2,1) - m(1,2)) / scale; + Y = ( m(0,2) - m(2,0)) / scale; + Z = ( m(1,0) - m(0,1)) / scale; + W = 0.25f * scale; + } + else + { + if ( m(0,0) > m(1,1) && m(0,0) > m(2,2)) + { + // 1st element of diag is greatest value + // find scale according to 1st element, and double it + scale = sqrtf( 1.0f + m(0,0) - m(1,1) - m(2,2)) * 2.0f; + + // TODO: speed this up + X = 0.25f * scale; + Y = (m(0,1) + m(1,0)) / scale; + Z = (m(2,0) + m(0,2)) / scale; + W = (m(2,1) - m(1,2)) / scale; + } + else if ( m(1,1) > m(2,2)) + { + // 2nd element of diag is greatest value + // find scale according to 2nd element, and double it + scale = sqrtf( 1.0f + m(1,1) - m(0,0) - m(2,2)) * 2.0f; + + // TODO: speed this up + X = (m(0,1) + m(1,0) ) / scale; + Y = 0.25f * scale; + Z = (m(1,2) + m(2,1) ) / scale; + W = (m(0,2) - m(2,0) ) / scale; + } + else + { + // 3rd element of diag is greatest value + // find scale according to 3rd element, and double it + scale = sqrtf( 1.0f + m(2,2) - m(0,0) - m(1,1)) * 2.0f; + + // TODO: speed this up + X = (m(0,2) + m(2,0)) / scale; + Y = (m(1,2) + m(2,1)) / scale; + Z = 0.25f * scale; + W = (m(1,0) - m(0,1)) / scale; + } + } + + normalize(); + return *this; +} + + +//! multiplication operator +inline quaternion quaternion::operator*(const quaternion& other) const +{ + quaternion tmp; + + tmp.W = (other.W * W) - (other.X * X) - (other.Y * Y) - (other.Z * Z); + tmp.X = (other.W * X) + (other.X * W) + (other.Y * Z) - (other.Z * Y); + tmp.Y = (other.W * Y) + (other.Y * W) + (other.Z * X) - (other.X * Z); + tmp.Z = (other.W * Z) + (other.Z * W) + (other.X * Y) - (other.Y * X); + + return tmp; +} + + +//! multiplication operator +inline quaternion quaternion::operator*(f32 s) const +{ + return quaternion(s*X, s*Y, s*Z, s*W); +} + +//! multiplication operator +inline quaternion& quaternion::operator*=(f32 s) +{ + X *= s; Y*=s; Z*=s; W*=s; + return *this; +} + +//! multiplication operator +inline quaternion& quaternion::operator*=(const quaternion& other) +{ + *this = other * (*this); + return *this; +} + +//! add operator +inline quaternion quaternion::operator+(const quaternion& b) const +{ + return quaternion(X+b.X, Y+b.Y, Z+b.Z, W+b.W); +} + + +//! Creates a matrix from this quaternion +inline matrix4 quaternion::getMatrix() const +{ + core::matrix4 m; + + m(0,0) = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + m(1,0) = 2.0f*X*Y + 2.0f*Z*W; + m(2,0) = 2.0f*X*Z - 2.0f*Y*W; + m(3,0) = 0.0f; + + m(0,1) = 2.0f*X*Y - 2.0f*Z*W; + m(1,1) = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + m(2,1) = 2.0f*Z*Y + 2.0f*X*W; + m(3,1) = 0.0f; + + m(0,2) = 2.0f*X*Z + 2.0f*Y*W; + m(1,2) = 2.0f*Z*Y - 2.0f*X*W; + m(2,2) = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + m(3,2) = 0.0f; + + m(0,3) = 0.0f; + m(1,3) = 0.0f; + m(2,3) = 0.0f; + m(3,3) = 1.0f; + + return m; +} + + +//! Creates a matrix from this quaternion +inline void quaternion::getMatrix( matrix4 &dest ) const +{ + dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + dest[1] = 2.0f*X*Y + 2.0f*Z*W; + dest[2] = 2.0f*X*Z - 2.0f*Y*W; + dest[3] = 0.0f; + + dest[4] = 2.0f*X*Y - 2.0f*Z*W; + dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + dest[6] = 2.0f*Z*Y + 2.0f*X*W; + dest[7] = 0.0f; + + dest[8] = 2.0f*X*Z + 2.0f*Y*W; + dest[9] = 2.0f*Z*Y - 2.0f*X*W; + dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + dest[11] = 0.0f; + + dest[12] = 0.f; + dest[13] = 0.f; + dest[14] = 0.f; + dest[15] = 1.f; +} + +//! Creates a matrix from this quaternion +inline void quaternion::getMatrix_transposed( matrix4 &dest ) const +{ + dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z; + dest[4] = 2.0f*X*Y + 2.0f*Z*W; + dest[8] = 2.0f*X*Z - 2.0f*Y*W; + dest[12] = 0.0f; + + dest[1] = 2.0f*X*Y - 2.0f*Z*W; + dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z; + dest[9] = 2.0f*Z*Y + 2.0f*X*W; + dest[13] = 0.0f; + + dest[2] = 2.0f*X*Z + 2.0f*Y*W; + dest[6] = 2.0f*Z*Y - 2.0f*X*W; + dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y; + dest[14] = 0.0f; + + dest[3] = 0.f; + dest[7] = 0.f; + dest[11] = 0.f; + dest[15] = 1.f; +} + + + +//! Inverts this quaternion +inline void quaternion::makeInverse() +{ + X = -X; Y = -Y; Z = -Z; +} + +//! sets new quaternion +inline void quaternion::set(f32 x, f32 y, f32 z, f32 w) +{ + X = x; + Y = y; + Z = z; + W = w; +} + + +//! sets new quaternion based on euler angles +inline void quaternion::set(f32 x, f32 y, f32 z) +{ + f64 angle; + + angle = x * 0.5; + f64 sr = (f32)sin(angle); + f64 cr = (f32)cos(angle); + + angle = y * 0.5; + f64 sp = (f32)sin(angle); + f64 cp = (f32)cos(angle); + + angle = z * 0.5; + f64 sy = (f32)sin(angle); + f64 cy = (f32)cos(angle); + + f64 cpcy = cp * cy; + f64 spcy = sp * cy; + f64 cpsy = cp * sy; + f64 spsy = sp * sy; + + X = (f32)(sr * cpcy - cr * spsy); + Y = (f32)(cr * spcy + sr * cpsy); + Z = (f32)(cr * cpsy - sr * spcy); + W = (f32)(cr * cpcy + sr * spsy); + + normalize(); +} + +//! sets new quaternion based on euler angles +inline void quaternion::set(const core::vector3df& vec) +{ + set(vec.X, vec.Y, vec.Z); +} + +//! normalizes the quaternion +inline quaternion& quaternion::normalize() +{ + f32 n = X*X + Y*Y + Z*Z + W*W; + + if (n == 1) + return *this; + + //n = 1.0f / sqrtf(n); + n = reciprocal_squareroot ( n ); + X *= n; + Y *= n; + Z *= n; + W *= n; + + return *this; +} + + +// set this quaternion to the result of the interpolation between two quaternions +inline void quaternion::slerp( quaternion q1, quaternion q2, f32 time) +{ + f32 angle = q1.getDotProduct(q2); + + if (angle < 0.0f) + { + q1 *= -1.0f; + angle *= -1.0f; + } + + f32 scale; + f32 invscale; + + if ((angle + 1.0f) > 0.05f) + { + if ((1.0f - angle) >= 0.05f) // spherical interpolation + { + f32 theta = (f32)acos(angle); + f32 invsintheta = 1.0f / (f32)sin(theta); + scale = (f32)sin(theta * (1.0f-time)) * invsintheta; + invscale = (f32)sin(theta * time) * invsintheta; + } + else // linear interploation + { + scale = 1.0f - time; + invscale = time; + } + } + else + { + q2.set(-q1.Y, q1.X, -q1.W, q1.Z); + scale = (f32)sin(PI * (0.5f - time)); + invscale = (f32)sin(PI * time); + } + + *this = (q1*scale) + (q2*invscale); +} + + +//! calculates the dot product +inline f32 quaternion::getDotProduct(const quaternion& q2) const +{ + return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W); +} + + +inline void quaternion::fromAngleAxis(f32 angle, const vector3df& axis) +{ + f32 fHalfAngle = 0.5f*angle; + f32 fSin = (f32)sin(fHalfAngle); + W = (f32)cos(fHalfAngle); + X = fSin*axis.X; + Y = fSin*axis.Y; + Z = fSin*axis.Z; +} + +inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const +{ + f32 scale = sqrtf(X*X + Y*Y + Z*Z); + + if (core::iszero(scale) || W > 1.0f || W < -1.0f) + { + angle = 0.0f; + axis.X = 0.0f; + axis.Y = 1.0f; + axis.Z = 0.0f; + } + else + { + angle = 2.0f * acos(W); + axis.X = X / scale; + axis.Y = Y / scale; + axis.Z = Z / scale; + } +} + +inline void quaternion::toEuler(vector3df& euler) const +{ + double sqw = W*W; + double sqx = X*X; + double sqy = Y*Y; + double sqz = Z*Z; + + // heading = rotation about z-axis + euler.Z = (f32) (atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw))); + + // bank = rotation about x-axis + euler.X = (f32) (atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw))); + + // attitude = rotation about y-axis + euler.Y = (f32) (asin( clamp(-2.0 * (X*Z - Y*W), -1.0, 1.0) )); +} + +inline vector3df quaternion::operator* (const vector3df& v) const +{ + // nVidia SDK implementation + + vector3df uv, uuv; + vector3df qvec(X, Y, Z); + uv = qvec.crossProduct(v); + uuv = qvec.crossProduct(uv); + uv *= (2.0f * W); + uuv *= 2.0f; + + return v + uv + uuv; +} + +//! set quaterion to identity +inline void quaternion::makeIdentity() +{ + W = 1.f; + X = 0.f; + Y = 0.f; + Z = 0.f; +} + +inline void quaternion::rotationFromTo(const vector3df& from, const vector3df& to) +{ + // Based on Stan Melax's article in Game Programming Gems + // Copy, since cannot modify local + vector3df v0 = from; + vector3df v1 = to; + v0.normalize(); + v1.normalize(); + + vector3df c = v0.crossProduct(v1); + + f32 d = v0.dotProduct(v1); + if (d >= 1.0f) // If dot == 1, vectors are the same + { + *this=quaternion(0,0,0,1); //IDENTITY; + } + f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt + f32 invs = 1 / s; + + X = c.X * invs; + Y = c.Y * invs; + Z = c.Z * invs; + W = s * 0.5f; +} + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/rect.h b/src/dep/include/irrlicht/rect.h new file mode 100644 index 0000000..d145132 --- /dev/null +++ b/src/dep/include/irrlicht/rect.h @@ -0,0 +1,257 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_RECT_H_INCLUDED__ +#define __IRR_RECT_H_INCLUDED__ + +#include "irrTypes.h" +#include "dimension2d.h" +#include "position2d.h" + +namespace irr +{ +namespace core +{ + + //! Rectangle template. + /** Mostly used by 2D GUI elements and for 2D drawing methods. + It has 2 positions instead of position and dimension and a fast + method for collision detection with other rectangles and points. + */ + template + class rect + { + public: + + rect() : UpperLeftCorner(0,0), LowerRightCorner(0,0) {} + + rect(T x, T y, T x2, T y2) + : UpperLeftCorner(x,y), LowerRightCorner(x2,y2) {} + + rect(const position2d& upperLeft, const position2d& lowerRight) + : UpperLeftCorner(upperLeft), LowerRightCorner(lowerRight) {} + + rect(const position2d& pos, const dimension2d& size) + : UpperLeftCorner(pos), LowerRightCorner(pos.X + size.Width, pos.Y + size.Height) {} + + + rect operator+(const position2d& pos) const + { + rect ret(*this); + return ret+=pos; + } + + rect& operator+=(const position2d& pos) + { + UpperLeftCorner += pos; + LowerRightCorner += pos; + return *this; + } + + rect operator-(const position2d& pos) const + { + rect ret(*this); + return ret-=pos; + } + + rect& operator-=(const position2d& pos) + { + UpperLeftCorner -= pos; + LowerRightCorner -= pos; + return *this; + } + + bool operator==(const rect& other) const + { + return (UpperLeftCorner == other.UpperLeftCorner && + LowerRightCorner == other.LowerRightCorner); + } + + + bool operator!=(const rect& other) const + { + return (UpperLeftCorner != other.UpperLeftCorner || + LowerRightCorner != other.LowerRightCorner); + } + + // compares size of rectangles + bool operator<(const rect& other) const + { + return getArea() < other.getArea(); + } + + //! Returns size of rectangle + T getArea() const + { + return getWidth() * getHeight(); + } + + //! Returns if a 2d point is within this rectangle. + //! \param pos: Position to test if it lies within this rectangle. + //! \return Returns true if the position is within the rectangle, false if not. + bool isPointInside(const position2d& pos) const + { + return (UpperLeftCorner.X <= pos.X && + UpperLeftCorner.Y <= pos.Y && + LowerRightCorner.X >= pos.X && + LowerRightCorner.Y >= pos.Y); + } + + //! Returns if the rectangle collides with another rectangle. + bool isRectCollided(const rect& other) const + { + return (LowerRightCorner.Y > other.UpperLeftCorner.Y && + UpperLeftCorner.Y < other.LowerRightCorner.Y && + LowerRightCorner.X > other.UpperLeftCorner.X && + UpperLeftCorner.X < other.LowerRightCorner.X); + } + + //! Clips this rectangle with another one. + void clipAgainst(const rect& other) + { + if (other.LowerRightCorner.X < LowerRightCorner.X) + LowerRightCorner.X = other.LowerRightCorner.X; + if (other.LowerRightCorner.Y < LowerRightCorner.Y) + LowerRightCorner.Y = other.LowerRightCorner.Y; + + if (other.UpperLeftCorner.X > UpperLeftCorner.X) + UpperLeftCorner.X = other.UpperLeftCorner.X; + if (other.UpperLeftCorner.Y > UpperLeftCorner.Y) + UpperLeftCorner.Y = other.UpperLeftCorner.Y; + + // correct possible invalid rect resulting from clipping + if (UpperLeftCorner.Y > LowerRightCorner.Y) + UpperLeftCorner.Y = LowerRightCorner.Y; + if (UpperLeftCorner.X > LowerRightCorner.X) + UpperLeftCorner.X = LowerRightCorner.X; + } + + //! Moves this rectangle to fit inside another one. + //! \return: returns true on success, false if not possible + bool constrainTo(const rect& other) + { + if (other.getWidth() < getWidth() || other.getHeight() < getHeight()) + return false; + + T diff = other.LowerRightCorner.X - LowerRightCorner.X; + if (diff < 0) + { + LowerRightCorner.X += diff; + UpperLeftCorner.X += diff; + } + + diff = other.LowerRightCorner.Y - LowerRightCorner.Y; + if (diff < 0) + { + LowerRightCorner.Y += diff; + UpperLeftCorner.Y += diff; + } + + diff = UpperLeftCorner.X - other.UpperLeftCorner.X; + if (diff < 0) + { + UpperLeftCorner.X -= diff; + LowerRightCorner.X -= diff; + } + + diff = UpperLeftCorner.Y - other.UpperLeftCorner.Y; + if (diff < 0) + { + UpperLeftCorner.Y -= diff; + LowerRightCorner.Y -= diff; + } + + return true; + } + + //! Returns width of rectangle. + T getWidth() const + { + return LowerRightCorner.X - UpperLeftCorner.X; + } + + //! Returns height of rectangle. + T getHeight() const + { + return LowerRightCorner.Y - UpperLeftCorner.Y; + } + + //! If the lower right corner of the rect is smaller then the + //! upper left, the points are swapped. + void repair() + { + if (LowerRightCorner.X < UpperLeftCorner.X) + { + T t = LowerRightCorner.X; + LowerRightCorner.X = UpperLeftCorner.X; + UpperLeftCorner.X = t; + } + + if (LowerRightCorner.Y < UpperLeftCorner.Y) + { + T t = LowerRightCorner.Y; + LowerRightCorner.Y = UpperLeftCorner.Y; + UpperLeftCorner.Y = t; + } + } + + //! Returns if the rect is valid to draw. It could be invalid + //! if the UpperLeftCorner is lower or more right than the + //! LowerRightCorner, or if any dimension is 0. + bool isValid() const + { + return ((LowerRightCorner.X >= UpperLeftCorner.X) && + (LowerRightCorner.Y >= UpperLeftCorner.Y)); + } + + //! Returns the center of the rectangle + position2d getCenter() const + { + return position2d((UpperLeftCorner.X + LowerRightCorner.X) / 2, + (UpperLeftCorner.Y + LowerRightCorner.Y) / 2); + } + + //! Returns the dimensions of the rectangle + dimension2d getSize() const + { + return dimension2d(getWidth(), getHeight()); + } + + + //! Adds a point to the rectangle, causing it to grow bigger, + //! if point is outside of the box + //! \param p: Point to add into the box. + void addInternalPoint(const position2d& p) + { + addInternalPoint(p.X, p.Y); + } + + //! Adds a point to the bounding rectangle, causing it to grow bigger, + //! if point is outside of the box. + //! \param x: X Coordinate of the point to add to this box. + //! \param y: Y Coordinate of the point to add to this box. + void addInternalPoint(T x, T y) + { + if (x>LowerRightCorner.X) + LowerRightCorner.X = x; + if (y>LowerRightCorner.Y) + LowerRightCorner.Y = y; + + if (x UpperLeftCorner; + position2d LowerRightCorner; + }; + + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/triangle3d.h b/src/dep/include/irrlicht/triangle3d.h new file mode 100644 index 0000000..dcfc45d --- /dev/null +++ b/src/dep/include/irrlicht/triangle3d.h @@ -0,0 +1,235 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TRIANGLE_3D_H_INCLUDED__ +#define __IRR_TRIANGLE_3D_H_INCLUDED__ + +#include "vector3d.h" +#include "line3d.h" +#include "plane3d.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace core +{ + + //! 3d triangle template class for doing collision detection and other things. + template + class triangle3d + { + public: + + //! Constructor for an all 0 triangle + triangle3d() {} + //! Constructor for triangle with given three vertices + triangle3d(vector3d v1, vector3d v2, vector3d v3) : pointA(v1), pointB(v2), pointC(v3) {} + + //! Equality operator + bool operator==(const triangle3d& other) const + { + return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC; + } + + //! Inequality operator + bool operator!=(const triangle3d& other) const + { + return !(*this==other); + } + + //! Determines if the triangle is totally inside a bounding box. + //! \param box: Box to check. + //! \return Returns true if the triangle is within the box, + //! and false otherwise. + bool isTotalInsideBox(const aabbox3d& box) const + { + return (box.isPointInside(pointA) && + box.isPointInside(pointB) && + box.isPointInside(pointC)); + } + + //! Get the closest point on a triangle to a point on the same plane. + //! \param p: Point which must be on the same plane as the triangle. + //! \return The closest point of the triangle + core::vector3d closestPointOnTriangle(const core::vector3d& p) const + { + const core::vector3d rab = line3d(pointA, pointB).getClosestPoint(p); + const core::vector3d rbc = line3d(pointB, pointC).getClosestPoint(p); + const core::vector3d rca = line3d(pointC, pointA).getClosestPoint(p); + + const T d1 = rab.getDistanceFrom(p); + const T d2 = rbc.getDistanceFrom(p); + const T d3 = rca.getDistanceFrom(p); + + if (d1 < d2) + return d1 < d3 ? rab : rca; + + return d2 < d3 ? rbc : rca; + } + + //! Check if a point is inside the triangle + //! \param p: Point to test. Assumes that this point is already on the plane + //! of the triangle. + //! \return Returns true if the point is inside the triangle, otherwise false. + bool isPointInside(const vector3d& p) const + { + return (isOnSameSide(p, pointA, pointB, pointC) && + isOnSameSide(p, pointB, pointA, pointC) && + isOnSameSide(p, pointC, pointA, pointB)); + } + + //! Check if a point is inside the triangle. This method is an + //! implementation of the example used in a paper by Kasper + //! Fauerby original written by Keidy from Mr-Gamemaker. + //! \param p: Point to test. Assumes that this point is already + //! on the plane of the triangle. + //! \return Returns true if the point is inside the triangle, + //! otherwise false. + bool isPointInsideFast(const vector3d& p) const + { + const vector3d f = pointB - pointA; + const vector3d g = pointC - pointA; + + const f32 a = f.dotProduct(f); + const f32 b = f.dotProduct(g); + const f32 c = g.dotProduct(g); + + const vector3d vp = p - pointA; + const f32 d = vp.dotProduct(f); + const f32 e = vp.dotProduct(g); + + f32 x = (d*c)-(e*b); + f32 y = (e*a)-(d*b); + const f32 ac_bb = (a*c)-(b*b); + f32 z = x+y-ac_bb; + + return (( (IR(z)) & ~((IR(x))|(IR(y))) ) & 0x80000000)!=0; + } + + + //! Get an intersection with a 3d line. + //! \param line: Line to intersect with. + //! \param outIntersection: Place to store the intersection point, if there is one. + //! \return Returns true if there was an intersection, false if not. + bool getIntersectionWithLimitedLine(const line3d& line, + vector3d& outIntersection) const + { + return getIntersectionWithLine(line.start, + line.getVector(), outIntersection) && + outIntersection.isBetweenPoints(line.start, line.end); + } + + + //! Returns an intersection with a 3d line. + //! Please note that also points are returned as intersection which + //! are on the line, but not between the start and end point of the line. + //! If you want the returned point be between start and end + //! use getIntersectionWithLimitedLine(). + //! \param linePoint: Point of the line to intersect with. + //! \param lineVect: Vector of the line to intersect with. + //! \param outIntersection: Place to store the intersection point, if there is one. + //! \return Returns true if there was an intersection, false if there was not. + bool getIntersectionWithLine(const vector3d& linePoint, + const vector3d& lineVect, vector3d& outIntersection) const + { + if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection)) + return isPointInside(outIntersection); + + return false; + } + + + //! Calculates the intersection between a 3d line and + //! the plane the triangle is on. + //! \param lineVect: Vector of the line to intersect with. + //! \param linePoint: Point of the line to intersect with. + //! \param outIntersection: Place to store the intersection point, if there is one. + //! \return Returns true if there was an intersection, false if there was not. + bool getIntersectionOfPlaneWithLine(const vector3d& linePoint, + const vector3d& lineVect, vector3d& outIntersection) const + { + const vector3d normal = getNormal().normalize(); + T t2; + + if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) ) + return false; + + T d = pointA.dotProduct(normal); + T t = -(normal.dotProduct(linePoint) - d) / t2; + outIntersection = linePoint + (lineVect * t); + return true; + } + + + //! Returns the normal of the triangle. + //! Please note: The normal is not normalized. + vector3d getNormal() const + { + return (pointB - pointA).crossProduct(pointC - pointA); + } + + //! Test if the triangle would be front or backfacing from any + //! point. Thus, this method assumes a camera position from + //! which the triangle is definitely visible when looking into + //! the given direction. + //! Do not use this method with points as it will give wrong results! + //! \param lookDirection: Look direction. + //! \return Returns true if the plane is front facing and + //! false if it is backfacing. + bool isFrontFacing(const vector3d& lookDirection) const + { + const vector3d n = getNormal().normalize(); + const f32 d = (f32)n.dotProduct(lookDirection); + return F32_LOWER_EQUAL_0(d); + } + + //! Returns the plane of this triangle. + plane3d getPlane() const + { + return plane3d(pointA, pointB, pointC); + } + + //! Returns the area of the triangle + T getArea() const + { + return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5; + + } + + //! sets the triangle's points + void set(const core::vector3d& a, const core::vector3d& b, const core::vector3d& c) + { + pointA = a; + pointB = b; + pointC = c; + } + + //! the three points of the triangle + vector3d pointA; + vector3d pointB; + vector3d pointC; + + private: + bool isOnSameSide(const vector3d& p1, const vector3d& p2, + const vector3d& a, const vector3d& b) const + { + vector3d bminusa = b - a; + vector3d cp1 = bminusa.crossProduct(p1 - a); + vector3d cp2 = bminusa.crossProduct(p2 - a); + return (cp1.dotProduct(cp2) >= 0.0f); + } + }; + + + //! Typedef for a f32 3d triangle. + typedef triangle3d triangle3df; + + //! Typedef for an integer 3d triangle. + typedef triangle3d triangle3di; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/vector2d.h b/src/dep/include/irrlicht/vector2d.h new file mode 100644 index 0000000..5ab78d3 --- /dev/null +++ b/src/dep/include/irrlicht/vector2d.h @@ -0,0 +1,256 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_POINT_2D_H_INCLUDED__ +#define __IRR_POINT_2D_H_INCLUDED__ + +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + + +//! 2d vector template class with lots of operators and methods. +template +class vector2d +{ +public: + + vector2d() : X(0), Y(0) {} + vector2d(T nx, T ny) : X(nx), Y(ny) {} + vector2d(const vector2d& other) : X(other.X), Y(other.Y) {} + + // operators + + vector2d operator-() const { return vector2d(-X, -Y); } + + vector2d& operator=(const vector2d& other) { X = other.X; Y = other.Y; return *this; } + + vector2d operator+(const vector2d& other) const { return vector2d(X + other.X, Y + other.Y); } + vector2d& operator+=(const vector2d& other) { X+=other.X; Y+=other.Y; return *this; } + vector2d operator+(const T v) const { return vector2d(X + v, Y + v); } + vector2d& operator+=(const T v) { X+=v; Y+=v; return *this; } + + vector2d operator-(const vector2d& other) const { return vector2d(X - other.X, Y - other.Y); } + vector2d& operator-=(const vector2d& other) { X-=other.X; Y-=other.Y; return *this; } + vector2d operator-(const T v) const { return vector2d(X - v, Y - v); } + vector2d& operator-=(const T v) { X-=v; Y-=v; return *this; } + + vector2d operator*(const vector2d& other) const { return vector2d(X * other.X, Y * other.Y); } + vector2d& operator*=(const vector2d& other) { X*=other.X; Y*=other.Y; return *this; } + vector2d operator*(const T v) const { return vector2d(X * v, Y * v); } + vector2d& operator*=(const T v) { X*=v; Y*=v; return *this; } + + vector2d operator/(const vector2d& other) const { return vector2d(X / other.X, Y / other.Y); } + vector2d& operator/=(const vector2d& other) { X/=other.X; Y/=other.Y; return *this; } + vector2d operator/(const T v) const { return vector2d(X / v, Y / v); } + vector2d& operator/=(const T v) { X/=v; Y/=v; return *this; } + + bool operator<=(const vector2d&other) const { return X<=other.X && Y<=other.Y; } + bool operator>=(const vector2d&other) const { return X>=other.X && Y>=other.Y; } + + bool operator<(const vector2d&other) const { return X(const vector2d&other) const { return X>other.X && Y>other.Y; } + + bool operator==(const vector2d& other) const { return other.X==X && other.Y==Y; } + bool operator!=(const vector2d& other) const { return other.X!=X || other.Y!=Y; } + + // functions + + //! returns if this vector equals the other one, taking floating point rounding errors into account + bool equals(const vector2d& other) const + { + return core::equals(X, other.X) && core::equals(Y, other.Y); + } + + void set(T nx, T ny) {X=nx; Y=ny; } + void set(const vector2d& p) { X=p.X; Y=p.Y;} + + //! Returns the length of the vector + //! \return Returns the length of the vector. + T getLength() const { return (T)sqrt((f64)(X*X + Y*Y)); } + + //! Returns the squared length of this vector + /** This is useful because it is much faster than getLength(). */ + T getLengthSQ() const { return X*X + Y*Y; } + + //! Returns the dot product of this vector with another. + T dotProduct(const vector2d& other) const + { + return X*other.X + Y*other.Y; + } + + //! Returns distance from another point. Here, the vector is interpreted + //! as a point in 2 dimensional space. + T getDistanceFrom(const vector2d& other) const + { + return vector2d(X - other.X, Y - other.Y).getLength(); + } + + //! Returns squared distance from another point. Here, the vector is + //! interpreted as a point in 2 dimensional space. + T getDistanceFromSQ(const vector2d& other) const + { + return vector2d(X - other.X, Y - other.Y).getLengthSQ(); + } + + //! rotates the point around a center by an amount of degrees. + void rotateBy(f64 degrees, const vector2d& center) + { + degrees *= DEGTORAD64; + T cs = (T)cos(degrees); + T sn = (T)sin(degrees); + + X -= center.X; + Y -= center.Y; + + set(X*cs - Y*sn, X*sn + Y*cs); + + X += center.X; + Y += center.Y; + } + + //! normalizes the vector. + vector2d& normalize() + { + T l = X*X + Y*Y; + if (l == 0) + return *this; + l = core::reciprocal_squareroot ( (f32)l ); + X *= l; + Y *= l; + return *this; + } + + //! Calculates the angle of this vector in grad in the trigonometric sense. + //! This method has been suggested by Pr3t3nd3r. + //! \return Returns a value between 0 and 360. + f64 getAngleTrig() const + { + if (X == 0) + return Y < 0 ? 270 : 90; + else + if (Y == 0) + return X < 0 ? 180 : 0; + + if ( Y > 0) + if (X > 0) + return atan(Y/X) * RADTODEG64; + else + return 180.0-atan(Y/-X) * RADTODEG64; + else + if (X > 0) + return 360.0-atan(-Y/X) * RADTODEG64; + else + return 180.0+atan(-Y/-X) * RADTODEG64; + } + + //! Calculates the angle of this vector in grad in the counter trigonometric sense. + //! \return Returns a value between 0 and 360. + inline f64 getAngle() const + { + if (Y == 0) // corrected thanks to a suggestion by Jox + return X < 0 ? 180 : 0; + else if (X == 0) + return Y < 0 ? 90 : 270; + + f64 tmp = Y / getLength(); + tmp = atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64; + + if (X>0 && Y>0) + return tmp + 270; + else + if (X>0 && Y<0) + return tmp + 90; + else + if (X<0 && Y<0) + return 90 - tmp; + else + if (X<0 && Y>0) + return 270 - tmp; + + return tmp; + } + + //! Calculates the angle between this vector and another one in grad. + //! \return Returns a value between 0 and 90. + inline f64 getAngleWith(const vector2d& b) const + { + f64 tmp = X*b.X + Y*b.Y; + + if (tmp == 0.0) + return 90.0; + + tmp = tmp / sqrt((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y))); + if (tmp < 0.0) + tmp = -tmp; + + return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64; + } + + //! Returns if this vector interpreted as a point is on a line between two other points. + /** It is assumed that the point is on the line. */ + //! \param begin: Beginning vector to compare between. + //! \param end: Ending vector to compare between. + //! \return True if this vector is between begin and end. False if not. + bool isBetweenPoints(const vector2d& begin, const vector2d& end) const + { + T f = (end - begin).getLengthSQ(); + return getDistanceFromSQ(begin) < f && + getDistanceFromSQ(end) < f; + } + + //! returns interpolated vector + //! \param other: other vector to interpolate between + //! \param d: value between 0.0f and 1.0f. + vector2d getInterpolated(const vector2d& other, f32 d) const + { + T inv = (T) 1.0 - d; + return vector2d(other.X*inv + X*d, other.Y*inv + Y*d); + } + + //! Returns (quadratically) interpolated vector between this and the two given ones. + /** \param v2: second vector to interpolate with + \param v3: third vector to interpolate with + \param d: value between 0.0f and 1.0f. */ + vector2d getInterpolated_quadratic(const vector2d& v2, const vector2d& v3, const T d) const + { + // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; + const T inv = (T) 1.0 - d; + const T mul0 = inv * inv; + const T mul1 = (T) 2.0 * d * inv; + const T mul2 = d * d; + + return vector2d ( X * mul0 + v2.X * mul1 + v3.X * mul2, + Y * mul0 + v2.Y * mul1 + v3.Y * mul2); + } + + //! sets this vector to the linearly interpolated vector between a and b. + /** \param a: first vector to interpolate with + \param b: second vector to interpolate with + \param t: value between 0.0f and 1.0f. */ + void interpolate(const vector2d& a, const vector2d& b, const f32 t) + { + X = b.X + ( ( a.X - b.X ) * t ); + Y = b.Y + ( ( a.Y - b.Y ) * t ); + } + + // member variables + T X, Y; +}; + + //! Typedef for f32 2d vector. + typedef vector2d vector2df; + //! Typedef for integer 2d vector. + typedef vector2d vector2di; + + template vector2d operator*(const S scalar, const vector2d& vector) { return vector*scalar; } + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/include/irrlicht/vector3d.h b/src/dep/include/irrlicht/vector3d.h new file mode 100644 index 0000000..85a3ee3 --- /dev/null +++ b/src/dep/include/irrlicht/vector3d.h @@ -0,0 +1,286 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_POINT_3D_H_INCLUDED__ +#define __IRR_POINT_3D_H_INCLUDED__ + +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + + //! 3d vector template class with lots of operators and methods. + template + class vector3d + { + public: + + vector3d() : X(0), Y(0), Z(0) {} + vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {} + vector3d(const vector3d& other) : X(other.X), Y(other.Y), Z(other.Z) {} + + // operators + + vector3d operator-() const { return vector3d(-X, -Y, -Z); } + + vector3d& operator=(const vector3d& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; } + + vector3d operator+(const vector3d& other) const { return vector3d(X + other.X, Y + other.Y, Z + other.Z); } + vector3d& operator+=(const vector3d& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; } + + vector3d operator-(const vector3d& other) const { return vector3d(X - other.X, Y - other.Y, Z - other.Z); } + vector3d& operator-=(const vector3d& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; } + + vector3d operator*(const vector3d& other) const { return vector3d(X * other.X, Y * other.Y, Z * other.Z); } + vector3d& operator*=(const vector3d& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; } + vector3d operator*(const T v) const { return vector3d(X * v, Y * v, Z * v); } + vector3d& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; } + + vector3d operator/(const vector3d& other) const { return vector3d(X / other.X, Y / other.Y, Z / other.Z); } + vector3d& operator/=(const vector3d& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; } + vector3d operator/(const T v) const { T i=(T)1.0/v; return vector3d(X * i, Y * i, Z * i); } + vector3d& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; } + + bool operator<=(const vector3d&other) const { return X<=other.X && Y<=other.Y && Z<=other.Z;}; + bool operator>=(const vector3d&other) const { return X>=other.X && Y>=other.Y && Z>=other.Z;}; + bool operator<(const vector3d&other) const { return X(const vector3d&other) const { return X>other.X && Y>other.Y && Z>other.Z;}; + + //! use week float compare + //bool operator==(const vector3d& other) const { return other.X==X && other.Y==Y && other.Z==Z; } + //bool operator!=(const vector3d& other) const { return other.X!=X || other.Y!=Y || other.Z!=Z; } + + bool operator==(const vector3d& other) const + { + return this->equals(other); + } + + bool operator!=(const vector3d& other) const + { + return !this->equals(other); + } + + // functions + + //! returns if this vector equals the other one, taking floating point rounding errors into account + bool equals(const vector3d& other, const T tolerance = (T)ROUNDING_ERROR_32 ) const + { + return core::equals(X, other.X, tolerance) && + core::equals(Y, other.Y, tolerance) && + core::equals(Z, other.Z, tolerance); + } + + void set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; } + void set(const vector3d& p) { X=p.X; Y=p.Y; Z=p.Z;} + + //! Returns length of the vector. + T getLength() const { return (T) sqrt((f64)(X*X + Y*Y + Z*Z)); } + + //! Returns squared length of the vector. + /** This is useful because it is much faster than + getLength(). */ + T getLengthSQ() const { return X*X + Y*Y + Z*Z; } + + //! Returns the dot product with another vector. + T dotProduct(const vector3d& other) const + { + return X*other.X + Y*other.Y + Z*other.Z; + } + + //! Returns distance from another point. + /** Here, the vector is interpreted as point in 3 dimensional space. */ + T getDistanceFrom(const vector3d& other) const + { + return vector3d(X - other.X, Y - other.Y, Z - other.Z).getLength(); + } + + //! Returns squared distance from another point. + /** Here, the vector is interpreted as point in 3 dimensional space. */ + T getDistanceFromSQ(const vector3d& other) const + { + return vector3d(X - other.X, Y - other.Y, Z - other.Z).getLengthSQ(); + } + + //! Calculates the cross product with another vector + //! \param p: vector to multiply with. + //! \return Crossproduct of this vector with p. + vector3d crossProduct(const vector3d& p) const + { + return vector3d(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X); + } + + //! Returns if this vector interpreted as a point is on a line between two other points. + /** It is assumed that the point is on the line. */ + //! \param begin: Beginning vector to compare between. + //! \param end: Ending vector to compare between. + //! \return True if this vector is between begin and end. False if not. + bool isBetweenPoints(const vector3d& begin, const vector3d& end) const + { + T f = (end - begin).getLengthSQ(); + return getDistanceFromSQ(begin) < f && + getDistanceFromSQ(end) < f; + } + + //! Normalizes the vector. In case of the 0 vector the result + //! is still 0, otherwise the length of the vector will be 1. + //! Todo: 64 Bit template doesnt work.. need specialized template + vector3d& normalize() + { + T l = X*X + Y*Y + Z*Z; + if (l == 0) + return *this; + l = (T) reciprocal_squareroot ( (f32)l ); + X *= l; + Y *= l; + Z *= l; + return *this; + } + + //! Sets the length of the vector to a new value + void setLength(T newlength) + { + normalize(); + *this *= newlength; + } + + //! Inverts the vector. + void invert() + { + X *= -1.0f; + Y *= -1.0f; + Z *= -1.0f; + } + + //! Rotates the vector by a specified number of degrees around the Y + //! axis and the specified center. + //! \param degrees: Number of degrees to rotate around the Y axis. + //! \param center: The center of the rotation. + void rotateXZBy(f64 degrees, const vector3d& center) + { + degrees *= DEGTORAD64; + T cs = (T)cos(degrees); + T sn = (T)sin(degrees); + X -= center.X; + Z -= center.Z; + set(X*cs - Z*sn, Y, X*sn + Z*cs); + X += center.X; + Z += center.Z; + } + + //! Rotates the vector by a specified number of degrees around the Z + //! axis and the specified center. + //! \param degrees: Number of degrees to rotate around the Z axis. + //! \param center: The center of the rotation. + void rotateXYBy(f64 degrees, const vector3d& center) + { + degrees *= DEGTORAD64; + T cs = (T)cos(degrees); + T sn = (T)sin(degrees); + X -= center.X; + Y -= center.Y; + set(X*cs - Y*sn, X*sn + Y*cs, Z); + X += center.X; + Y += center.Y; + } + + //! Rotates the vector by a specified number of degrees around the X + //! axis and the specified center. + //! \param degrees: Number of degrees to rotate around the X axis. + //! \param center: The center of the rotation. + void rotateYZBy(f64 degrees, const vector3d& center) + { + degrees *= DEGTORAD64; + T cs = (T)cos(degrees); + T sn = (T)sin(degrees); + Z -= center.Z; + Y -= center.Y; + set(X, Y*cs - Z*sn, Y*sn + Z*cs); + Z += center.Z; + Y += center.Y; + } + + //! Returns interpolated vector. + /** \param other: other vector to interpolate between + \param d: value between 0.0f and 1.0f. */ + vector3d getInterpolated(const vector3d& other, const T d) const + { + const T inv = (T) 1.0 - d; + return vector3d(other.X*inv + X*d, other.Y*inv + Y*d, other.Z*inv + Z*d); + } + + //! Returns interpolated vector. ( quadratic ) + /** \param v2: second vector to interpolate with + \param v3: third vector to interpolate with + \param d: value between 0.0f and 1.0f. */ + vector3d getInterpolated_quadratic(const vector3d& v2, const vector3d& v3, const T d) const + { + // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d; + const T inv = (T) 1.0 - d; + const T mul0 = inv * inv; + const T mul1 = (T) 2.0 * d * inv; + const T mul2 = d * d; + + return vector3d ( X * mul0 + v2.X * mul1 + v3.X * mul2, + Y * mul0 + v2.Y * mul1 + v3.Y * mul2, + Z * mul0 + v2.Z * mul1 + v3.Z * mul2); + } + + //! Gets the Y and Z rotations of a vector. + /** Thanks to Arras on the Irrlicht forums to add this method. + \return A vector representing the rotation in degrees of + this vector. The Z component of the vector will always be 0. */ + vector3d getHorizontalAngle() + { + vector3d angle; + + angle.Y = (T)atan2(X, Z); + angle.Y *= (f32)RADTODEG64; + + if (angle.Y < 0.0f) angle.Y += 360.0f; + if (angle.Y >= 360.0f) angle.Y -= 360.0f; + + f32 z1 = sqrtf(X*X + Z*Z); + + angle.X = (T)atan2(z1, Y); + angle.X *= (f32)RADTODEG64; + angle.X -= 90.0f; + + if (angle.X < 0.0f) angle.X += 360.0f; + if (angle.X >= 360.0f) angle.X -= 360.0f; + + return angle; + } + + //! Fills an array of 4 values with the vector data (usually floats). + /** Useful for setting in shader constants for example. The fourth value + will always be 0. */ + void getAs4Values(T* array) const + { + array[0] = X; + array[1] = Y; + array[2] = Z; + array[3] = 0; + } + + + // member variables + + T X, Y, Z; + }; + + + //! Typedef for a f32 3d vector. + typedef vector3d vector3df; + //! Typedef for an integer 3d vector. + typedef vector3d vector3di; + + template vector3d operator*(const S scalar, const vector3d& vector) { return vector*scalar; } + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/BuiltInFont.h b/src/dep/src/irrlicht/BuiltInFont.h new file mode 100644 index 0000000..bc0a4c2 --- /dev/null +++ b/src/dep/src/irrlicht/BuiltInFont.h @@ -0,0 +1,1065 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __BUILD_IN_FONT_H_INCLUDED__ +#define __BUILD_IN_FONT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +// header file generated by Bin2H, copyright 2002 by N.Gebhardt. +// Bin2H is Freeware. Download it freely from www.code3d.com. +// for the source bitmap, see builtInFont.bmp + +namespace irr +{ +namespace gui +{ + +u8 BuiltInFontData[] = +{ + 0x42, 0x4d, 0x4a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x63, 0x0b, + 0x00, 0x00, 0x63, 0x0b, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x44, 0x42, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x40, 0x22, 0x20, 0x00, 0x02, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x02, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x42, 0x24, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x24, 0x42, + 0x22, 0x24, 0x42, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x44, 0x22, 0x44, + 0x42, 0x22, 0x22, 0x44, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x24, + 0x42, 0x44, 0x22, 0x22, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x24, 0x42, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x44, 0x42, 0x24, 0x42, + 0x44, 0x22, 0x22, 0x24, 0x42, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x42, 0x44, 0x42, 0x24, 0x44, 0x44, 0x22, 0x24, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, 0x22, 0x24, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x42, 0x22, 0x44, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x44, 0x44, 0x24, 0x42, 0x44, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x42, 0x22, + 0x44, 0x44, 0x24, 0x42, 0x24, 0x42, 0x22, 0x22, + 0x44, 0x22, 0x44, 0x24, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x22, 0x24, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x24, 0x44, 0x44, 0x44, 0x22, 0x44, + 0x42, 0x44, 0x42, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x44, 0x44, 0x22, 0x44, 0x22, 0x44, 0x22, 0x24, + 0x42, 0x24, 0x42, 0x24, 0x42, 0x44, 0x22, 0x44, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x44, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x42, 0x22, 0x24, 0x42, 0x24, 0x42, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x44, 0x42, 0x24, 0x42, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x42, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, 0x24, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, + 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x21, 0x22, 0x12, 0x22, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x44, 0x22, 0x24, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x42, 0x42, 0x22, 0x44, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x44, 0x42, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x44, 0x22, 0x42, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x42, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x24, 0x24, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, 0x44, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x44, 0x22, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x44, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x22, 0x42, 0x42, 0x24, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x44, 0x42, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, 0x24, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x24, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, + 0x22, 0x44, 0x42, 0x22, 0x42, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x42, + 0x22, 0x42, 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x24, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, + 0x42, 0x22, 0x23, 0x22, 0x24, 0x22, 0x32, 0x24, + 0x22, 0x23, 0x24, 0x24, 0x22, 0x32, 0x22, 0x42, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x24, 0x22, 0x42, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, + 0x44, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, + 0x42, 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, 0x42, + 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, 0x22, 0x22, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x44, 0x44, 0x42, + 0x24, 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x44, + 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x42, 0x23, 0x22, 0x42, + 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x24, 0x22, + 0x32, 0x24, 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x42, 0x22, 0x32, 0x24, + 0x22, 0x32, 0x24, 0x22, 0x34, 0x22, 0x42, 0x32, + 0x23, 0x24, 0x23, 0x42, 0x23, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x22, + 0x22, 0x32, 0x22, 0x42, 0x23, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x21, 0x22, 0x21, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x42, 0x42, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x44, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x24, 0x42, 0x22, 0x42, 0x44, + 0x22, 0x24, 0x24, 0x42, 0x22, 0x42, 0x22, 0x44, + 0x44, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x22, 0x42, 0x42, 0x24, + 0x44, 0x42, 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x42, + 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x44, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x32, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x22, 0x32, + 0x22, 0x23, 0x22, 0x32, 0x22, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x32, 0x22, 0x32, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x23, 0x24, + 0x22, 0x22, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, + 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, + 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, + 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, + 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x44, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x24, 0x22, 0x22, 0x42, 0x42, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, + 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, + 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, + 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, + 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x22, 0x12, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x12, 0x21, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x22, 0x42, 0x22, 0x24, + 0x44, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x24, 0x22, 0x24, 0x42, 0x22, 0x24, + 0x22, 0x24, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x24, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x24, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x42, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x44, 0x22, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x44, 0x42, 0x22, 0x44, + 0x22, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x22, 0x23, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x32, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x44, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x22, 0x44, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x42, 0x22, 0x44, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x24, 0x24, 0x24, + 0x22, 0x44, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x42, 0x22, 0x44, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x22, 0x44, 0x22, 0x44, + 0x44, 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x44, 0x44, 0x22, + 0x44, 0x22, 0x42, 0x22, 0x44, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x42, 0x22, 0x22, 0x24, + 0x44, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x44, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x44, 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x24, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, + 0x42, 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x44, 0x42, 0x22, 0x44, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x24, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x44, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x24, 0x42, 0x24, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x21, 0x22, 0x21, 0x22, + 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, 0x21, 0x22, + 0x21, 0x22, 0x12, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x44, 0x44, 0x22, 0x24, 0x42, 0x22, + 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x42, 0x22, 0x44, 0x22, 0x42, 0x44, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, + 0x44, 0x44, 0x22, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, + 0x44, 0x44, 0x42, 0x24, 0x44, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x44, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, + 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, 0x44, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, 0x22, + 0x22, 0x42, 0x22, 0x44, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x44, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x31, 0x23, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x32, 0x22, 0x32, + 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, 0x22, 0x32, + 0x22, 0x32, 0x23, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x32, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22 +}; + + u32 BuiltInFontDataSize = sizeof(BuiltInFontData); +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/C3DSMeshFileLoader.cpp b/src/dep/src/irrlicht/C3DSMeshFileLoader.cpp new file mode 100644 index 0000000..b1b4ab6 --- /dev/null +++ b/src/dep/src/irrlicht/C3DSMeshFileLoader.cpp @@ -0,0 +1,1268 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_3DS_LOADER_ + +#include "C3DSMeshFileLoader.h" +#include "os.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" + +namespace irr +{ +namespace scene +{ + + +// Primary chunk +const u16 C3DS_MAIN3DS = 0x4D4D; + +// Main Chunks +const u16 C3DS_EDIT3DS = 0x3D3D; +const u16 C3DS_KEYF3DS = 0xB000; +const u16 C3DS_VERSION = 0x0002; +const u16 C3DS_MESHVERSION = 0x3D3E; + +// sub chunks of C3DS_EDIT3DS +const u16 C3DS_EDIT_MATERIAL = 0xAFFF; +const u16 C3DS_EDIT_OBJECT = 0x4000; + +// sub chunks of C3DS_EDIT_MATERIAL +const u16 C3DS_MATNAME = 0xA000; +const u16 C3DS_MATAMBIENT = 0xA010; +const u16 C3DS_MATDIFFUSE = 0xA020; +const u16 C3DS_MATSPECULAR = 0xA030; +const u16 C3DS_MATSHININESS = 0xA040; +const u16 C3DS_MATSHIN2PCT = 0xA041; +const u16 C3DS_TRANSPARENCY = 0xA050; +const u16 C3DS_TWO_SIDE = 0xA081; +const u16 C3DS_WIRE = 0xA085; +const u16 C3DS_SHADING = 0xA100; +const u16 C3DS_MATTEXMAP = 0xA200; +const u16 C3DS_MATSPECMAP = 0xA204; +const u16 C3DS_MATOPACMAP = 0xA210; +const u16 C3DS_MATREFLMAP = 0xA220; +const u16 C3DS_MATBUMPMAP = 0xA230; +const u16 C3DS_MATMAPFILE = 0xA300; +const u16 C3DS_MAT_TEXTILING = 0xA351; +const u16 C3DS_MAT_USCALE = 0xA354; +const u16 C3DS_MAT_VSCALE = 0xA356; +const u16 C3DS_MAT_UOFFSET = 0xA358; +const u16 C3DS_MAT_VOFFSET = 0xA35A; + +// subs of C3DS_EDIT_OBJECT +const u16 C3DS_OBJTRIMESH = 0x4100; + +// subs of C3DS_OBJTRIMESH +const u16 C3DS_TRIVERT = 0x4110; +const u16 C3DS_POINTFLAGARRAY= 0x4111; +const u16 C3DS_TRIFACE = 0x4120; +const u16 C3DS_TRIFACEMAT = 0x4130; +const u16 C3DS_TRIUV = 0x4140; +const u16 C3DS_TRISMOOTH = 0x4150; +const u16 C3DS_TRIMATRIX = 0x4160; +const u16 C3DS_MESHCOLOR = 0x4165; +const u16 C3DS_DIRECT_LIGHT = 0x4600; +const u16 C3DS_DL_INNER_RANGE= 0x4659; +const u16 C3DS_DL_OUTER_RANGE= 0x465A; +const u16 C3DS_DL_MULTIPLIER = 0x465B; +const u16 C3DS_CAMERA = 0x4700; +const u16 C3DS_CAM_SEE_CONE = 0x4710; +const u16 C3DS_CAM_RANGES = 0x4720; + +// subs of C3DS_KEYF3DS +const u16 C3DS_KF_HDR = 0xB00A; +const u16 C3DS_AMBIENT_TAG = 0xB001; +const u16 C3DS_OBJECT_TAG = 0xB002; +const u16 C3DS_CAMERA_TAG = 0xB003; +const u16 C3DS_TARGET_TAG = 0xB004; +const u16 C3DS_LIGHTNODE_TAG = 0xB005; +const u16 C3DS_KF_SEG = 0xB008; +const u16 C3DS_KF_CURTIME = 0xB009; +const u16 C3DS_KF_NODE_HDR = 0xB010; +const u16 C3DS_PIVOTPOINT = 0xB013; +const u16 C3DS_BOUNDBOX = 0xB014; +const u16 C3DS_POS_TRACK_TAG = 0xB020; +const u16 C3DS_ROT_TRACK_TAG = 0xB021; +const u16 C3DS_SCL_TRACK_TAG = 0xB022; +const u16 C3DS_NODE_ID = 0xB030; + +// different color chunk types +const u16 C3DS_COL_RGB = 0x0010; +const u16 C3DS_COL_TRU = 0x0011; +const u16 C3DS_COL_LIN_24 = 0x0012; +const u16 C3DS_COL_LIN_F = 0x0013; + +// percentage chunk types +const u16 C3DS_PERCENTAGE_I = 0x0030; +const u16 C3DS_PERCENTAGE_F = 0x0031; + + +//! Constructor +C3DSMeshFileLoader::C3DSMeshFileLoader(IMeshManipulator* manip,io::IFileSystem* fs, video::IVideoDriver* driver) +: FileSystem(fs), Driver(driver), Vertices(0), Indices(0), SmoothingGroups(0), TCoords(0), + CountVertices(0), CountFaces(0), CountTCoords(0), Mesh(0), Manipulator(manip) +{ + TransformationMatrix.makeIdentity(); + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + + +//! destructor +C3DSMeshFileLoader::~C3DSMeshFileLoader() +{ + cleanUp(); + + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); + + if (Mesh) + Mesh->drop(); +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool C3DSMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".3ds")!=0; +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* C3DSMeshFileLoader::createMesh(io::IReadFile* file) +{ + ChunkData data; + + readChunkData(file, data); + + if (data.header.id != C3DS_MAIN3DS ) + return 0; + + CurrentMaterial.clear(); + Materials.clear(); + MeshBufferNames.clear(); + cleanUp(); + + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + + if (readChunk(file, &data)) + { + // success + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + SMeshBuffer* mb = ((SMeshBuffer*)Mesh->getMeshBuffer(i)); + // drop empty buffers + if (mb->getIndexCount() == 0 || mb->getVertexCount() == 0) + { + Mesh->MeshBuffers.erase(i--); + mb->drop(); + } + else + mb->recalculateBoundingBox(); + } + + Mesh->recalculateBoundingBox(); + + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + return am; + } + + Mesh->drop(); + Mesh = 0; + + return 0; +} + + +bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file, + ChunkData* chunk, f32& percentage) +{ + ChunkData data; + readChunkData(file, data); + + short intpercentage; + float fpercentage; + + switch(data.header.id) + { + case C3DS_PERCENTAGE_I: + { + // read short + file->read(&intpercentage, 2); +#ifdef __BIG_ENDIAN__ + intpercentage = os::Byteswap::byteswap(intpercentage); +#endif + percentage=intpercentage/100.0f; + data.read += 2; + } + break; + case C3DS_PERCENTAGE_F: + { + // read float + file->read(&fpercentage, sizeof(float)); + data.read += sizeof(float); +#ifdef __BIG_ENDIAN__ + percentage = os::Byteswap::byteswap(fpercentage); +#else + percentage = (f32)fpercentage; +#endif + } + break; + default: + { + // unknown percentage chunk + os::Printer::log("Unknown percentage chunk in 3Ds file.", ELL_WARNING); + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + } + + chunk->read += data.read; + + return true; +} + +bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk, + video::SColor& out) +{ + ChunkData data; + readChunkData(file, data); + + u8 c[3]; + f32 cf[3]; + + switch(data.header.id) + { + case C3DS_COL_TRU: + case C3DS_COL_LIN_24: + { + // read 8 bit data + file->read(c, sizeof(c)); + out.set(255, c[0], c[1], c[2]); + data.read += sizeof(c); + } + break; + case C3DS_COL_RGB: + case C3DS_COL_LIN_F: + { + // read float data + file->read(cf, sizeof(cf)); +#ifdef __BIG_ENDIAN__ + cf[0] = os::Byteswap::byteswap(cf[0]); + cf[1] = os::Byteswap::byteswap(cf[1]); + cf[2] = os::Byteswap::byteswap(cf[2]); +#endif + out.set(255, (s32)(cf[0]*255.0f), (s32)(cf[1]*255.0f), (s32)(cf[2]*255.0f)); + data.read += sizeof(cf); + } + break; + default: + { + // unknown color chunk size + os::Printer::log("Unknown size of color chunk in 3Ds file.", ELL_WARNING); + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + } + + chunk->read += data.read; + + return true; +} + + +bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent) +{ + u16 matSection=0; + + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_MATNAME: + { + c8* c = new c8[data.header.length - data.read]; + file->read(c, data.header.length - data.read); + + if (strlen(c)) + CurrentMaterial.Name = c; + + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_MATAMBIENT: + readColorChunk(file, &data, CurrentMaterial.Material.AmbientColor); + break; + case C3DS_MATDIFFUSE: + readColorChunk(file, &data, CurrentMaterial.Material.DiffuseColor); + break; + case C3DS_MATSPECULAR: + readColorChunk(file, &data, CurrentMaterial.Material.SpecularColor); + break; + case C3DS_MATSHININESS: + readPercentageChunk(file, &data, CurrentMaterial.Material.Shininess); + break; + case C3DS_TRANSPARENCY: + { + f32 percentage; + readPercentageChunk(file, &data, percentage); + if (percentage>0.0f) + { + CurrentMaterial.Material.MaterialTypeParam=percentage; + CurrentMaterial.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + else + { + CurrentMaterial.Material.MaterialType=video::EMT_SOLID; + } + } + break; + case C3DS_WIRE: + CurrentMaterial.Material.Wireframe=true; + break; + case C3DS_TWO_SIDE: + CurrentMaterial.Material.BackfaceCulling=false; + break; + case C3DS_SHADING: + { + s16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + switch (flags) + { + case 0: + CurrentMaterial.Material.Wireframe=true; + break; + case 1: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=false; + break; + case 2: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=true; + break; + default: + // phong and metal missing + break; + } + data.read += data.header.length - data.read; + } + break; + case C3DS_MATTEXMAP: + case C3DS_MATSPECMAP: + case C3DS_MATOPACMAP: + case C3DS_MATREFLMAP: + case C3DS_MATBUMPMAP: + { + matSection=data.header.id; +#if 0 // Should contain a percentage chunk, but does not work with the meshes + f32 percentage=0; + if (matSection!=C3DS_MATREFLMAP) + readPercentageChunk(file, &data, percentage); +#endif + } + break; + case C3DS_MATMAPFILE: + { + // read texture file name + c8* c = new c8[data.header.length - data.read]; + file->read(c, data.header.length - data.read); + if (matSection == C3DS_MATTEXMAP) + CurrentMaterial.Filename[0] = c; + else if (matSection == C3DS_MATSPECMAP) + CurrentMaterial.Filename[1] = c; + else if (matSection == C3DS_MATOPACMAP) + CurrentMaterial.Filename[2] = c; + else if (matSection == C3DS_MATREFLMAP) + CurrentMaterial.Filename[3] = c; + else if (matSection == C3DS_MATBUMPMAP) + CurrentMaterial.Filename[4] = c; + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_MAT_TEXTILING: + { + s16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 2; + } + break; + case C3DS_MAT_USCALE: + case C3DS_MAT_VSCALE: + case C3DS_MAT_UOFFSET: + case C3DS_MAT_VOFFSET: + { + f32 value; + file->read(&value, 4); +#ifdef __BIG_ENDIAN__ + value = os::Byteswap::byteswap(value); +#endif + data.read += 4; + } + break; + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + Materials.push_back(CurrentMaterial); + CurrentMaterial.clear(); + + return true; +} + + + +bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data, + IMeshBuffer* mb, const core::vector3df& pivot) +{ + u16 flags; + u32 flags2; + // Track flags + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + // Num keys + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + // TCB flags + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 20; + + f32 angle=0.0f; + if (data.header.id== C3DS_ROT_TRACK_TAG) + { + // Angle + file->read(&angle, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + angle = os::Byteswap::byteswap(angle); +#endif + data.read += sizeof(f32); + } + core::vector3df vec; + file->read(&vec.X, sizeof(f32)); + file->read(&vec.Y, sizeof(f32)); + file->read(&vec.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + vec.X = os::Byteswap::byteswap(vec.X); + vec.Y = os::Byteswap::byteswap(vec.X); + vec.Z = os::Byteswap::byteswap(vec.X); +#endif + data.read += 12; + vec-=pivot; + + // apply transformation to mesh buffer + if (false)//mb) + { + video::S3DVertex *vertices=(video::S3DVertex*)mb->getVertices(); + if (data.header.id==C3DS_POS_TRACK_TAG) + { + for (u32 i=0; igetVertexCount(); ++i) + vertices[i].Pos+=vec; + } + else if (data.header.id==C3DS_ROT_TRACK_TAG) + { + //TODO + } + else if (data.header.id==C3DS_SCL_TRACK_TAG) + { + //TODO + } + } + // skip further frames + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + return true; +} + + + +bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent) +{ + ChunkData data; + + //KF_HDR is always at the beginning + readChunkData(file, data); + if (data.header.id != C3DS_KF_HDR) + return false; + else + { + u16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + c8* c = new c8[data.header.length - data.read-4]; + file->read(c, data.header.length - data.read-4); + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + + data.read += data.header.length - data.read; + parent->read += data.read; + delete [] c; + } + + IMeshBuffer* mb=0; + core::vector3df pivot,bboxCenter; + while(parent->read < parent->header.length) + { + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_OBJECT_TAG: + { + mb=0; + pivot.set(0.0f, 0.0f, 0.0f); + } + break; + case C3DS_KF_SEG: + { + u32 flags; + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 8; + } + break; + case C3DS_KF_NODE_HDR: + { + s16 flags; + c8* c = new c8[data.header.length - data.read-6]; + file->read(c, data.header.length - data.read-6); + + // search mesh buffer to apply these transformations to + for (u32 i=0; igetMeshBuffer(i); + break; + } + } + + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_KF_CURTIME: + { + u32 flags; + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 4; + } + break; + case C3DS_NODE_ID: + { + u16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 2; + } + break; + case C3DS_PIVOTPOINT: + { + file->read(&pivot.X, sizeof(f32)); + file->read(&pivot.Y, sizeof(f32)); + file->read(&pivot.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + pivot.X = os::Byteswap::byteswap(pivot.X); + pivot.Y = os::Byteswap::byteswap(pivot.Y); + pivot.Z = os::Byteswap::byteswap(pivot.Z); +#endif + data.read += 12; + } + break; + case C3DS_BOUNDBOX: + { + core::aabbox3df bbox; + // abuse bboxCenter as temporary variable + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); + bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); + bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); +#endif + bbox.reset(bboxCenter); + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); + bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); + bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); +#endif + bbox.addInternalPoint(bboxCenter); + bboxCenter=bbox.getCenter(); + data.read += 24; + } + break; + case C3DS_POS_TRACK_TAG: + case C3DS_ROT_TRACK_TAG: + case C3DS_SCL_TRACK_TAG: + readTrackChunk(file, data, mb, bboxCenter-pivot); + break; + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + data.read=0; + } + + return true; +} + + + +bool C3DSMeshFileLoader::readChunk(io::IReadFile* file, ChunkData* parent) +{ + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_VERSION: + { + u16 version; + file->read(&version, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + version = os::Byteswap::byteswap(version); +#endif + file->seek(data.header.length - data.read - 2, true); + data.read += data.header.length - data.read; + if (version != 0x03) + os::Printer::log("3ds file version is other than 3.", ELL_ERROR); + } + break; + case C3DS_EDIT_MATERIAL: + readMaterialChunk(file, &data); + break; + case C3DS_KEYF3DS: + readFrameChunk(file, &data); + break; + case C3DS_EDIT3DS: + break; + case C3DS_MESHVERSION: + case 0x01: + { + u32 version; + file->read(&version, sizeof(u32)); +#ifdef __BIG_ENDIAN__ + version = os::Byteswap::byteswap(version); +#endif + data.read += sizeof(u32); + } + break; + case C3DS_EDIT_OBJECT: + { + core::stringc name; + readString(file, data, name); + readObjectChunk(file, &data); + composeObject(file, name); + } + break; + + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + return true; +} + + + +bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent) +{ + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_OBJTRIMESH: + readObjectChunk(file, &data); + break; + + case C3DS_TRIVERT: + readVertices(file, data); + break; + + case C3DS_POINTFLAGARRAY: + { + u16 numVertex, flags; + file->read(&numVertex, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + numVertex= os::Byteswap::byteswap(numVertex); +#endif + for (u16 i=0; iread(&flags, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + } + data.read += (numVertex+1)*sizeof(u16); + } + break; + + case C3DS_TRIFACE: + readIndices(file, data); + readObjectChunk(file, &data); // read smooth and material groups + break; + + case C3DS_TRIFACEMAT: + readMaterialGroup(file, data); + break; + + case C3DS_TRIUV: // getting texture coordinates + readTextureCoords(file, data); + break; + + case C3DS_TRIMATRIX: + { + f32 mat[4][3]; + file->read(&mat, 12*sizeof(f32)); + TransformationMatrix.makeIdentity(); + for (int i=0; i<4; ++i) + { + for (int j=0; j<3; ++j) + { +#ifdef __BIG_ENDIAN__ + TransformationMatrix(i,j)=os::Byteswap::byteswap(mat[i][j]); +#else + TransformationMatrix(i,j)=mat[i][j]; +#endif + } + } + data.read += 12*sizeof(f32); + } + break; + case C3DS_MESHCOLOR: + { + u8 flag; + file->read(&flag, sizeof(u8)); + ++data.read; + } + break; + case C3DS_TRISMOOTH: // TODO + { + SmoothingGroups = new u32[CountFaces]; + file->read(SmoothingGroups, CountFaces*sizeof(u32)); +#ifdef __BIG_ENDIAN__ + for (u16 i=0; iseek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + return true; +} + + +void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name) +{ + if (Mesh->getMeshBufferCount() != Materials.size()) + loadMaterials(file); + + if (MaterialGroups.empty()) + { + // no material group, so add all + SMaterialGroup group; + group.faceCount = CountFaces; + group.faces = new u16[group.faceCount]; + for (u32 i=0; iaddMeshBuffer(mb); + mb->getMaterial() = Materials[0].Material; + mb->drop(); + // add an empty mesh buffer name + core::stringc c = ""; + MeshBufferNames.push_back(c); + } + } + + for (u32 i=0; igetMaximalPrimitiveCount(), (u32)((1<<16)-1))-3; // currently hardcoded s16 max value for index pointers + + // find mesh buffer for this group + for (mbPos=0; mbPosgetMeshBuffer(mbPos); + mat=&Materials[mbPos].Material; + MeshBufferNames[mbPos]=name; + break; + } + } + + if (mb != 0) + { + // add geometry to the buffer. + + video::S3DVertex vtx; + core::vector3df vec; + vtx.Color=mat->DiffuseColor; + if (mat->MaterialType==video::EMT_TRANSPARENT_VERTEX_ALPHA) + { + vtx.Color.setAlpha((int)(255.0f*mat->MaterialTypeParam)); + } + vtx.Normal.set(0,0,0); + + for (s32 f=0; fVertices.size(); + if (vtxCount>maxPrimitives) + { + IMeshBuffer* tmp = mb; + mb = new SMeshBuffer(); + Mesh->addMeshBuffer(mb); + mb->drop(); + Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast(); + Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp; + mb->getMaterial() = *mat; + vtxCount=0; + } + + for (s32 v=0; v<3; ++v) + { + s32 idx = Indices[MaterialGroups[i].faces[f]*4 +v]; + + if (CountVertices > idx) + { + vtx.Pos.X = Vertices[idx*3 + 0]; + vtx.Pos.Z = Vertices[idx*3 + 1]; + vtx.Pos.Y = Vertices[idx*3 + 2]; +// TransformationMatrix.transformVect(vtx.Pos); + } + + if (CountTCoords > idx) + { + vtx.TCoords.X = TCoords[idx*2 + 0]; + vtx.TCoords.Y = 1.0f -TCoords[idx*2 + 1]; + } + + mb->Vertices.push_back(vtx); + } + + // compute normal + core::plane3d pl(mb->Vertices[vtxCount].Pos, mb->Vertices[vtxCount+2].Pos, + mb->Vertices[vtxCount+1].Pos); + + mb->Vertices[vtxCount].Normal = pl.Normal; + mb->Vertices[vtxCount+1].Normal = pl.Normal; + mb->Vertices[vtxCount+2].Normal = pl.Normal; + + // add indices + + mb->Indices.push_back(vtxCount); + mb->Indices.push_back(vtxCount+2); + mb->Indices.push_back(vtxCount+1); + } + } + else + os::Printer::log("Found no matching material for Group in 3ds file.", ELL_WARNING); + } + + cleanUp(); +} + + +core::stringc C3DSMeshFileLoader::getTextureFileName(const core::stringc& texture, + core::stringc& model) +{ + s32 idx = -1; + idx = model.findLast('/'); + + if (idx == -1) + idx = model.findLast('\\'); + + if (idx == -1) + return core::stringc(); + + core::stringc p = model.subString(0, idx+1); + p.append(texture); + return p; +} + + +void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file) +{ + // create a mesh buffer for every material + core::stringc modelFilename = file->getFileName(); + + if (Materials.empty()) + os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION); + + MeshBufferNames.reallocate(Materials.size()); + for (u32 i=0; iaddMeshBuffer(m); + + m->getMaterial() = Materials[i].Material; + if (Materials[i].Filename[0].size()) + { + video::ITexture* texture = Driver->getTexture(Materials[i].Filename[0].c_str()); + if (!texture) + { + core::stringc fname = getTextureFileName( + Materials[i].Filename[0], modelFilename); + if (fname.size()) + texture = Driver->getTexture(fname.c_str()); + } + + if (!texture) + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[0].c_str(), ELL_WARNING); + else + m->getMaterial().setTexture(0, texture); + } + + if (Materials[i].Filename[2].size()) + { + video::ITexture* texture = Driver->getTexture(Materials[i].Filename[2].c_str()); + + if (!texture) + { + core::stringc fname = getTextureFileName( + Materials[i].Filename[2], modelFilename); + if (fname.size()) + texture = Driver->getTexture(fname.c_str()); + } + + if (!texture) + { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[2].c_str(), ELL_WARNING); + } + else + { + m->getMaterial().setTexture(0, texture); + m->getMaterial().MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + } + } + + if (Materials[i].Filename[3].size()) + { + video::ITexture* texture = Driver->getTexture(Materials[i].Filename[3].c_str()); + + if (!texture) + { + core::stringc fname = getTextureFileName( + Materials[i].Filename[3], modelFilename); + if (fname.size()) + texture = Driver->getTexture(fname.c_str()); + } + + if (!texture) + { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[3].c_str(), ELL_WARNING); + } + else + { + m->getMaterial().setTexture(1, m->getMaterial().getTexture(0)); + m->getMaterial().setTexture(0, texture); + m->getMaterial().MaterialType = video::EMT_REFLECTION_2_LAYER; + } + } + + if (Materials[i].Filename[4].size()) + { + video::ITexture* texture = Driver->getTexture(Materials[i].Filename[4].c_str()); + + if (!texture) + { + core::stringc fname = getTextureFileName( + Materials[i].Filename[4], modelFilename); + if (fname.size()) + texture = Driver->getTexture(fname.c_str()); + } + + if (!texture) + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[4].c_str(), ELL_WARNING); + else + { + m->getMaterial().setTexture(1, texture); + Driver->makeNormalMapTexture(texture, 9.0f); + m->getMaterial().MaterialType=video::EMT_PARALLAX_MAP_SOLID; + m->getMaterial().MaterialTypeParam=0.035f; + } + } + + m->drop(); + } +} + + +void C3DSMeshFileLoader::cleanUp() +{ + delete [] Vertices; + CountVertices = 0; + Vertices = 0; + delete [] Indices; + Indices = 0; + CountFaces = 0; + delete [] SmoothingGroups; + SmoothingGroups = 0; + delete [] TCoords; + TCoords = 0; + CountTCoords = 0; + + MaterialGroups.clear(); +} + + + + +void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data) +{ + file->read(&CountTCoords, sizeof(CountTCoords)); +#ifdef __BIG_ENDIAN__ + CountTCoords = os::Byteswap::byteswap(CountTCoords); +#endif + data.read += sizeof(CountTCoords); + + s32 tcoordsBufferByteSize = CountTCoords * sizeof(f32) * 2; + + if (data.header.length - data.read != tcoordsBufferByteSize) + { + os::Printer::log("Invalid size of tcoords found in 3ds file.", ELL_WARNING); + return; + } + + TCoords = new f32[CountTCoords * 3]; + file->read(TCoords, tcoordsBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&group.faceCount, sizeof(group.faceCount)); +#ifdef __BIG_ENDIAN__ + group.faceCount = os::Byteswap::byteswap(group.faceCount); +#endif + data.read += sizeof(group.faceCount); + + // read faces + group.faces = new u16[group.faceCount]; + file->read(group.faces, sizeof(u16) * group.faceCount); +#ifdef __BIG_ENDIAN__ + for (u32 i=0;iread(&CountFaces, sizeof(CountFaces)); +#ifdef __BIG_ENDIAN__ + CountFaces = os::Byteswap::byteswap(CountFaces); +#endif + data.read += sizeof(CountFaces); + + s32 indexBufferByteSize = CountFaces * sizeof(u16) * 4; + + // Indices are u16s. + // After every 3 Indices in the array, there follows an edge flag. + Indices = new u16[CountFaces * 4]; + file->read(Indices, indexBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&CountVertices, sizeof(CountVertices)); +#ifdef __BIG_ENDIAN__ + CountVertices = os::Byteswap::byteswap(CountVertices); +#endif + data.read += sizeof(CountVertices); + + s32 vertexBufferByteSize = CountVertices * sizeof(f32) * 3; + + if (data.header.length - data.read != vertexBufferByteSize) + { + os::Printer::log("Invalid size of vertices found in 3ds file.", ELL_WARNING); + return; + } + + Vertices = new f32[CountVertices * 3]; + file->read(Vertices, vertexBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&data.header, sizeof(ChunkHeader)); +#ifdef __BIG_ENDIAN__ + data.header.id = os::Byteswap::byteswap(data.header.id); + data.header.length = os::Byteswap::byteswap(data.header.length); +#endif + data.read += sizeof(ChunkHeader); +} + + +void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) +{ + c8 c = 1; + out = ""; + + while (c) + { + file->read(&c, sizeof(c8)); + if (c) + out.append(c); + + ++data.read; + } +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_3DS_LOADER_ diff --git a/src/dep/src/irrlicht/C3DSMeshFileLoader.h b/src/dep/src/irrlicht/C3DSMeshFileLoader.h new file mode 100644 index 0000000..63820ca --- /dev/null +++ b/src/dep/src/irrlicht/C3DSMeshFileLoader.h @@ -0,0 +1,177 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_3DS_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_3DS_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMesh.h" +#include "IMeshManipulator.h" +#include "matrix4.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading 3ds meshes. +class C3DSMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + C3DSMeshFileLoader(IMeshManipulator* manip,io::IFileSystem* fs, video::IVideoDriver* driver); + + //! destructor + virtual ~C3DSMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + // byte-align structures + #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) + # pragma pack( push, packing ) + # pragma pack( 1 ) + # define PACK_STRUCT + #elif defined( __GNUC__ ) + # define PACK_STRUCT __attribute__((packed)) + #else + # error compiler not supported + #endif + + struct ChunkHeader + { + u16 id; + s32 length; + } PACK_STRUCT; + + // Default alignment + #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) + # pragma pack( pop, packing ) + #endif + + #undef PACK_STRUCT + + + struct ChunkData + { + ChunkData() : read(0) {} + + ChunkHeader header; + s32 read; + }; + + struct SCurrentMaterial + { + void clear() { + Material=video::SMaterial(); + Name=""; + Filename[0]=""; + Filename[1]=""; + Filename[2]=""; + Filename[3]=""; + Filename[4]=""; + } + + video::SMaterial Material; + core::stringc Name; + core::stringc Filename[5]; + }; + + struct SMaterialGroup + { + SMaterialGroup() : faceCount(0), faces(0) {}; + + SMaterialGroup(const SMaterialGroup& o) + { + *this = o; + } + + ~SMaterialGroup() + { + clear(); + } + + void clear() + { + delete [] faces; + faces = 0; + faceCount = 0; + } + + void operator =(const SMaterialGroup& o) + { + MaterialName = o.MaterialName; + faceCount = o.faceCount; + faces = new u16[faceCount]; + for (u32 i=0; i TempIndices; + f32* TCoords; + u16 CountVertices; + u16 CountFaces; // = CountIndices/4 + u16 CountTCoords; + core::array MaterialGroups; + + SCurrentMaterial CurrentMaterial; + core::array Materials; + core::array MeshBufferNames; + core::matrix4 TransformationMatrix; + + SMesh* Mesh; + + IMeshManipulator* Manipulator; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CAnimatedMeshMD2.cpp b/src/dep/src/irrlicht/CAnimatedMeshMD2.cpp new file mode 100644 index 0000000..b01a49e --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshMD2.cpp @@ -0,0 +1,759 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + +#include "CAnimatedMeshMD2.h" +#include "os.h" +#include "SColor.h" +#include "IReadFile.h" +#include "irrMath.h" + +namespace irr +{ +namespace scene +{ + +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + // structs needed to load the md2-format + + const s32 MD2_MAGIC_NUMBER = 844121161; + const s32 MD2_VERSION = 8; + const s32 MD2_MAX_VERTS = 2048; + + // TA: private + const s32 MD2_FRAME_SHIFT = 2; + const f32 MD2_FRAME_SHIFT_RECIPROCAL = 1.f / ( 1 << MD2_FRAME_SHIFT ); + + struct SMD2Header + { + s32 magic; + s32 version; + s32 skinWidth; + s32 skinHeight; + s32 frameSize; + s32 numSkins; + s32 numVertices; + s32 numTexcoords; + s32 numTriangles; + s32 numGlCommands; + s32 numFrames; + s32 offsetSkins; + s32 offsetTexcoords; + s32 offsetTriangles; + s32 offsetFrames; + s32 offsetGlCommands; + s32 offsetEnd; + } PACK_STRUCT; + + struct SMD2Vertex + { + u8 vertex[3]; + u8 lightNormalIndex; + } PACK_STRUCT; + + struct SMD2Frame + { + f32 scale[3]; + f32 translate[3]; + c8 name[16]; + SMD2Vertex vertices[1]; + } PACK_STRUCT; + + struct SMD2Triangle + { + u16 vertexIndices[3]; + u16 textureIndices[3]; + } PACK_STRUCT; + + struct SMD2TextureCoordinate + { + s16 s; + s16 t; + } PACK_STRUCT; + + struct SMD2GLCommand + { + f32 s, t; + s32 vertexIndex; + } PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + +const s32 Q2_VERTEX_NORMAL_TABLE_SIZE = 162; + +static const f32 Q2_VERTEX_NORMAL_TABLE[Q2_VERTEX_NORMAL_TABLE_SIZE][3] = { + {-0.525731f, 0.000000f, 0.850651f}, + {-0.442863f, 0.238856f, 0.864188f}, + {-0.295242f, 0.000000f, 0.955423f}, + {-0.309017f, 0.500000f, 0.809017f}, + {-0.162460f, 0.262866f, 0.951056f}, + {0.000000f, 0.000000f, 1.000000f}, + {0.000000f, 0.850651f, 0.525731f}, + {-0.147621f, 0.716567f, 0.681718f}, + {0.147621f, 0.716567f, 0.681718f}, + {0.000000f, 0.525731f, 0.850651f}, + {0.309017f, 0.500000f, 0.809017f}, + {0.525731f, 0.000000f, 0.850651f}, + {0.295242f, 0.000000f, 0.955423f}, + {0.442863f, 0.238856f, 0.864188f}, + {0.162460f, 0.262866f, 0.951056f}, + {-0.681718f, 0.147621f, 0.716567f}, + {-0.809017f, 0.309017f, 0.500000f}, + {-0.587785f, 0.425325f, 0.688191f}, + {-0.850651f, 0.525731f, 0.000000f}, + {-0.864188f, 0.442863f, 0.238856f}, + {-0.716567f, 0.681718f, 0.147621f}, + {-0.688191f, 0.587785f, 0.425325f}, + {-0.500000f, 0.809017f, 0.309017f}, + {-0.238856f, 0.864188f, 0.442863f}, + {-0.425325f, 0.688191f, 0.587785f}, + {-0.716567f, 0.681718f, -0.147621f}, + {-0.500000f, 0.809017f, -0.309017f}, + {-0.525731f, 0.850651f, 0.000000f}, + {0.000000f, 0.850651f, -0.525731f}, + {-0.238856f, 0.864188f, -0.442863f}, + {0.000000f, 0.955423f, -0.295242f}, + {-0.262866f, 0.951056f, -0.162460f}, + {0.000000f, 1.000000f, 0.000000f}, + {0.000000f, 0.955423f, 0.295242f}, + {-0.262866f, 0.951056f, 0.162460f}, + {0.238856f, 0.864188f, 0.442863f}, + {0.262866f, 0.951056f, 0.162460f}, + {0.500000f, 0.809017f, 0.309017f}, + {0.238856f, 0.864188f, -0.442863f}, + {0.262866f, 0.951056f, -0.162460f}, + {0.500000f, 0.809017f, -0.309017f}, + {0.850651f, 0.525731f, 0.000000f}, + {0.716567f, 0.681718f, 0.147621f}, + {0.716567f, 0.681718f, -0.147621f}, + {0.525731f, 0.850651f, 0.000000f}, + {0.425325f, 0.688191f, 0.587785f}, + {0.864188f, 0.442863f, 0.238856f}, + {0.688191f, 0.587785f, 0.425325f}, + {0.809017f, 0.309017f, 0.500000f}, + {0.681718f, 0.147621f, 0.716567f}, + {0.587785f, 0.425325f, 0.688191f}, + {0.955423f, 0.295242f, 0.000000f}, + {1.000000f, 0.000000f, 0.000000f}, + {0.951056f, 0.162460f, 0.262866f}, + {0.850651f, -0.525731f, 0.000000f}, + {0.955423f, -0.295242f, 0.000000f}, + {0.864188f, -0.442863f, 0.238856f}, + {0.951056f, -0.162460f, 0.262866f}, + {0.809017f, -0.309017f, 0.500000f}, + {0.681718f, -0.147621f, 0.716567f}, + {0.850651f, 0.000000f, 0.525731f}, + {0.864188f, 0.442863f, -0.238856f}, + {0.809017f, 0.309017f, -0.500000f}, + {0.951056f, 0.162460f, -0.262866f}, + {0.525731f, 0.000000f, -0.850651f}, + {0.681718f, 0.147621f, -0.716567f}, + {0.681718f, -0.147621f, -0.716567f}, + {0.850651f, 0.000000f, -0.525731f}, + {0.809017f, -0.309017f, -0.500000f}, + {0.864188f, -0.442863f, -0.238856f}, + {0.951056f, -0.162460f, -0.262866f}, + {0.147621f, 0.716567f, -0.681718f}, + {0.309017f, 0.500000f, -0.809017f}, + {0.425325f, 0.688191f, -0.587785f}, + {0.442863f, 0.238856f, -0.864188f}, + {0.587785f, 0.425325f, -0.688191f}, + {0.688191f, 0.587785f, -0.425325f}, + {-0.147621f, 0.716567f, -0.681718f}, + {-0.309017f, 0.500000f, -0.809017f}, + {0.000000f, 0.525731f, -0.850651f}, + {-0.525731f, 0.000000f, -0.850651f}, + {-0.442863f, 0.238856f, -0.864188f}, + {-0.295242f, 0.000000f, -0.955423f}, + {-0.162460f, 0.262866f, -0.951056f}, + {0.000000f, 0.000000f, -1.000000f}, + {0.295242f, 0.000000f, -0.955423f}, + {0.162460f, 0.262866f, -0.951056f}, + {-0.442863f, -0.238856f, -0.864188f}, + {-0.309017f, -0.500000f, -0.809017f}, + {-0.162460f, -0.262866f, -0.951056f}, + {0.000000f, -0.850651f, -0.525731f}, + {-0.147621f, -0.716567f, -0.681718f}, + {0.147621f, -0.716567f, -0.681718f}, + {0.000000f, -0.525731f, -0.850651f}, + {0.309017f, -0.500000f, -0.809017f}, + {0.442863f, -0.238856f, -0.864188f}, + {0.162460f, -0.262866f, -0.951056f}, + {0.238856f, -0.864188f, -0.442863f}, + {0.500000f, -0.809017f, -0.309017f}, + {0.425325f, -0.688191f, -0.587785f}, + {0.716567f, -0.681718f, -0.147621f}, + {0.688191f, -0.587785f, -0.425325f}, + {0.587785f, -0.425325f, -0.688191f}, + {0.000000f, -0.955423f, -0.295242f}, + {0.000000f, -1.000000f, 0.000000f}, + {0.262866f, -0.951056f, -0.162460f}, + {0.000000f, -0.850651f, 0.525731f}, + {0.000000f, -0.955423f, 0.295242f}, + {0.238856f, -0.864188f, 0.442863f}, + {0.262866f, -0.951056f, 0.162460f}, + {0.500000f, -0.809017f, 0.309017f}, + {0.716567f, -0.681718f, 0.147621f}, + {0.525731f, -0.850651f, 0.000000f}, + {-0.238856f, -0.864188f, -0.442863f}, + {-0.500000f, -0.809017f, -0.309017f}, + {-0.262866f, -0.951056f, -0.162460f}, + {-0.850651f, -0.525731f, 0.000000f}, + {-0.716567f, -0.681718f, -0.147621f}, + {-0.716567f, -0.681718f, 0.147621f}, + {-0.525731f, -0.850651f, 0.000000f}, + {-0.500000f, -0.809017f, 0.309017f}, + {-0.238856f, -0.864188f, 0.442863f}, + {-0.262866f, -0.951056f, 0.162460f}, + {-0.864188f, -0.442863f, 0.238856f}, + {-0.809017f, -0.309017f, 0.500000f}, + {-0.688191f, -0.587785f, 0.425325f}, + {-0.681718f, -0.147621f, 0.716567f}, + {-0.442863f, -0.238856f, 0.864188f}, + {-0.587785f, -0.425325f, 0.688191f}, + {-0.309017f, -0.500000f, 0.809017f}, + {-0.147621f, -0.716567f, 0.681718f}, + {-0.425325f, -0.688191f, 0.587785f}, + {-0.162460f, -0.262866f, 0.951056f}, + {0.442863f, -0.238856f, 0.864188f}, + {0.162460f, -0.262866f, 0.951056f}, + {0.309017f, -0.500000f, 0.809017f}, + {0.147621f, -0.716567f, 0.681718f}, + {0.000000f, -0.525731f, 0.850651f}, + {0.425325f, -0.688191f, 0.587785f}, + {0.587785f, -0.425325f, 0.688191f}, + {0.688191f, -0.587785f, 0.425325f}, + {-0.955423f, 0.295242f, 0.000000f}, + {-0.951056f, 0.162460f, 0.262866f}, + {-1.000000f, 0.000000f, 0.000000f}, + {-0.850651f, 0.000000f, 0.525731f}, + {-0.955423f, -0.295242f, 0.000000f}, + {-0.951056f, -0.162460f, 0.262866f}, + {-0.864188f, 0.442863f, -0.238856f}, + {-0.951056f, 0.162460f, -0.262866f}, + {-0.809017f, 0.309017f, -0.500000f}, + {-0.864188f, -0.442863f, -0.238856f}, + {-0.951056f, -0.162460f, -0.262866f}, + {-0.809017f, -0.309017f, -0.500000f}, + {-0.681718f, 0.147621f, -0.716567f}, + {-0.681718f, -0.147621f, -0.716567f}, + {-0.850651f, 0.000000f, -0.525731f}, + {-0.688191f, 0.587785f, -0.425325f}, + {-0.587785f, 0.425325f, -0.688191f}, + {-0.425325f, 0.688191f, -0.587785f}, + {-0.425325f, -0.688191f, -0.587785f}, + {-0.587785f, -0.425325f, -0.688191f}, + {-0.688191f, -0.587785f, -0.425325f}, + }; + +struct SMD2AnimationType +{ + s32 begin; + s32 end; + s32 fps; +}; + +static const SMD2AnimationType MD2AnimationTypeList[21] = +{ + { 0, 39, 9 }, // STAND + { 40, 45, 10 }, // RUN + { 46, 53, 10 }, // ATTACK + { 54, 57, 7 }, // PAIN_A + { 58, 61, 7 }, // PAIN_B + { 62, 65, 7 }, // PAIN_C + { 66, 71, 7 }, // JUMP + { 72, 83, 7 }, // FLIP + { 84, 94, 7 }, // SALUTE + { 95, 111, 10 }, // FALLBACK + { 112, 122, 7 }, // WAVE + { 123, 134, 6 }, // POINT + { 135, 153, 10 }, // CROUCH_STAND + { 154, 159, 7 }, // CROUCH_WALK + { 160, 168, 10 }, // CROUCH_ATTACK + { 169, 172, 7 }, // CROUCH_PAIN + { 173, 177, 5 }, // CROUCH_DEATH + { 178, 183, 7 }, // DEATH_FALLBACK + { 184, 189, 7 }, // DEATH_FALLFORWARD + { 190, 197, 7 }, // DEATH_FALLBACKSLOW + { 198, 198, 5 }, // BOOM +}; + + +//! constructor +CAnimatedMeshMD2::CAnimatedMeshMD2() +: FrameList(0), FrameCount(0), TriangleCount(0) +{ + #ifdef _DEBUG + IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh"); + IMesh::setDebugName("CAnimatedMeshMD2 IMesh"); + #endif +} + + + +//! destructor +CAnimatedMeshMD2::~CAnimatedMeshMD2() +{ + if (FrameList) + delete [] FrameList; +} + + + +//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CAnimatedMeshMD2::getFrameCount() const +{ + return FrameCount< (FrameCount<(reinterpret_cast(&InterpolationBuffer)); +} + + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const +{ + if (InterpolationBuffer.Material == material) + return const_cast(reinterpret_cast(&InterpolationBuffer)); + else + return 0; +} + + +// updates the interpolation buffer +void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop, s32 endFrameLoop) +{ + u32 firstFrame, secondFrame; + f32 div; + + // TA: resolve missing ipol in loop between end-start + + if (endFrameLoop - startFrameLoop == 0) + { + firstFrame = frame>>MD2_FRAME_SHIFT; + secondFrame = frame>>MD2_FRAME_SHIFT; + div = 1.0f; + } + else + { + // key frames + u32 s = startFrameLoop >> MD2_FRAME_SHIFT; + u32 e = endFrameLoop >> MD2_FRAME_SHIFT; + + firstFrame = frame >> MD2_FRAME_SHIFT; + secondFrame = core::if_c_a_else_b ( firstFrame + 1 > e, s, firstFrame + 1 ); + + firstFrame = core::s32_min ( FrameCount - 1, firstFrame ); + secondFrame = core::s32_min ( FrameCount - 1, secondFrame ); + + //div = (frame % (1<(InterpolationBuffer.getVertices()); + video::S3DVertex* first = FrameList[firstFrame].pointer(); + video::S3DVertex* second = FrameList[secondFrame].pointer(); + + s32 count = FrameList[firstFrame].size(); + + // interpolate both frames + for (s32 i=0; iPos = (second->Pos - first->Pos) * div + first->Pos; + target->Normal = (second->Normal - first->Normal) * div + first->Normal; + + ++target; + ++first; + ++second; + } + + //update bounding box + InterpolationBuffer.setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div)); +} + + +//! loads an md2 file +bool CAnimatedMeshMD2::loadFile(io::IReadFile* file) +{ + if (!file) + return false; + + SMD2Header header; + + file->read(&header, sizeof(SMD2Header)); + +#ifdef __BIG_ENDIAN__ + header.magic = os::Byteswap::byteswap(header.magic); + header.version = os::Byteswap::byteswap(header.version); + header.skinWidth = os::Byteswap::byteswap(header.skinWidth); + header.skinHeight = os::Byteswap::byteswap(header.skinHeight); + header.frameSize = os::Byteswap::byteswap(header.frameSize); + header.numSkins = os::Byteswap::byteswap(header.numSkins); + header.numVertices = os::Byteswap::byteswap(header.numVertices); + header.numTexcoords = os::Byteswap::byteswap(header.numTexcoords); + header.numTriangles = os::Byteswap::byteswap(header.numTriangles); + header.numGlCommands = os::Byteswap::byteswap(header.numGlCommands); + header.numFrames = os::Byteswap::byteswap(header.numFrames); + header.offsetSkins = os::Byteswap::byteswap(header.offsetSkins); + header.offsetTexcoords = os::Byteswap::byteswap(header.offsetTexcoords); + header.offsetTriangles = os::Byteswap::byteswap(header.offsetTriangles); + header.offsetFrames = os::Byteswap::byteswap(header.offsetFrames); + header.offsetGlCommands = os::Byteswap::byteswap(header.offsetGlCommands); + header.offsetEnd = os::Byteswap::byteswap(header.offsetEnd); +#endif + + if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION) + { + os::Printer::log("MD2 Loader: Wrong file header", file->getFileName(), ELL_WARNING); + return false; + } + + // create Memory for indices and frames + + TriangleCount = header.numTriangles; + if (FrameList) + delete [] FrameList; + FrameList = new core::array[header.numFrames]; + FrameCount = header.numFrames; + + s32 i; + + for (i=0; iseek(header.offsetTexcoords); + SMD2TextureCoordinate* textureCoords = new SMD2TextureCoordinate[header.numTexcoords]; + + if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords)) + { + os::Printer::log("MD2 Loader: Error reading TextureCoords.", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + for (i=0; iseek(header.offsetTriangles); + + SMD2Triangle *triangles = new SMD2Triangle[header.numTriangles]; + if (!file->read(triangles, header.numTriangles *sizeof(SMD2Triangle))) + { + os::Printer::log("MD2 Loader: Error reading triangles.", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + for (i=0; i* vertices = new core::array< core::vector3df >[header.numFrames]; + core::array< core::vector3df >* normals = new core::array< core::vector3df >[header.numFrames]; + + file->seek(header.offsetFrames); + + for (i = 0; iread(frame, header.frameSize); + +#ifdef __BIG_ENDIAN__ + frame->scale[0] = os::Byteswap::byteswap(frame->scale[0]); + frame->scale[1] = os::Byteswap::byteswap(frame->scale[1]); + frame->scale[2] = os::Byteswap::byteswap(frame->scale[2]); + frame->translate[0] = os::Byteswap::byteswap(frame->translate[0]); + frame->translate[1] = os::Byteswap::byteswap(frame->translate[1]); + frame->translate[2] = os::Byteswap::byteswap(frame->translate[2]); +#endif + // store frame data + + SFrameData fdata; + fdata.begin = i; + fdata.end = i; + fdata.fps = 7; + + if (frame->name[0]) + { + for (s32 s = 0; frame->name[s]!=0 && (frame->name[s] < '0' || + frame->name[s] > '9'); ++s) + fdata.name += frame->name[s]; + + if (!FrameData.empty() && FrameData[FrameData.size()-1].name == fdata.name) + ++FrameData[FrameData.size()-1].end; + else + FrameData.push_back(fdata); + } + + // add vertices + + vertices[i].reallocate(header.numVertices); + for (s32 j=0; jvertices[j].vertex[0] * frame->scale[0] + frame->translate[0]; + v.Z = frame->vertices[j].vertex[1] * frame->scale[1] + frame->translate[1]; + v.Y = frame->vertices[j].vertex[2] * frame->scale[2] + frame->translate[2]; + + vertices[i].push_back(v); + + u8 normalidx = frame->vertices[j].lightNormalIndex; + if (normalidx < Q2_VERTEX_NORMAL_TABLE_SIZE) + { + v.X = Q2_VERTEX_NORMAL_TABLE[normalidx][0]; + v.Z = Q2_VERTEX_NORMAL_TABLE[normalidx][1]; + v.Y = Q2_VERTEX_NORMAL_TABLE[normalidx][2]; + } + + normals[i].push_back(v); + } + + // calculate bounding boxes + if (header.numVertices) + { + core::aabbox3d box; + box.reset(vertices[i][0]); + + for (s32 j=1; j& vert = vertices[f]; + + for (s32 t=0; t=FrameCount) + defaultFrame = 0; + + for (u32 j=0; j& CAnimatedMeshMD2::getBoundingBox() const +{ + return InterpolationBuffer.BoundingBox; +} + + +//! set user axis aligned bounding box +void CAnimatedMeshMD2::setBoundingBox( const core::aabbox3df& box) +{ + InterpolationBuffer.BoundingBox = box; +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CAnimatedMeshMD2::getMeshType() const +{ + return EAMT_MD2; +} + + +//! Returns frame loop data for a special MD2 animation type. +void CAnimatedMeshMD2::getFrameLoop(EMD2_ANIMATION_TYPE l, + s32& outBegin, s32& outEnd, s32& outFPS) const +{ + if (l < 0 || l >= EMAT_COUNT) + return; + + outBegin = MD2AnimationTypeList[l].begin << MD2_FRAME_SHIFT; + outEnd = MD2AnimationTypeList[l].end << MD2_FRAME_SHIFT; + + // correct to anim between last->first frame + outEnd += MD2_FRAME_SHIFT == 0 ? 1 : ( 1 << MD2_FRAME_SHIFT ) - 1; + outFPS = MD2AnimationTypeList[l].fps << MD2_FRAME_SHIFT; +} + + +//! Returns frame loop data for a special MD2 animation type. +bool CAnimatedMeshMD2::getFrameLoop(const c8* name, + s32& outBegin, s32&outEnd, s32& outFPS) const +{ + for (s32 i=0; i<(s32)FrameData.size(); ++i) + if (FrameData[i].name == name) + { + outBegin = FrameData[i].begin << MD2_FRAME_SHIFT; + outEnd = FrameData[i].end << MD2_FRAME_SHIFT; + outEnd += MD2_FRAME_SHIFT == 0 ? 1 : ( 1 << MD2_FRAME_SHIFT ) - 1; + outFPS = FrameData[i].fps << MD2_FRAME_SHIFT; + return true; + } + + return false; +} + + +//! Returns amount of md2 animations in this file. +s32 CAnimatedMeshMD2::getAnimationCount() const +{ + return FrameData.size(); +} + + +//! Returns name of md2 animation. +const c8* CAnimatedMeshMD2::getAnimationName(s32 nr) const +{ + if (nr < 0 || nr >= (s32)FrameData.size()) + return 0; + + return FrameData[nr].name.c_str(); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD2_LOADER_ + diff --git a/src/dep/src/irrlicht/CAnimatedMeshMD2.h b/src/dep/src/irrlicht/CAnimatedMeshMD2.h new file mode 100644 index 0000000..6cef904 --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshMD2.h @@ -0,0 +1,109 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_MD2_H_INCLUDED__ +#define __C_ANIMATED_MESH_MD2_H_INCLUDED__ + +#include "IAnimatedMeshMD2.h" +#include "IMesh.h" +#include "CMeshBuffer.h" +#include "IReadFile.h" +#include "S3DVertex.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + + class CAnimatedMeshMD2 : public IAnimatedMeshMD2 + { + public: + + //! constructor + CAnimatedMeshMD2(); + + //! destructor + virtual ~CAnimatedMeshMD2(); + + //! loads an md2 file + virtual bool loadFile(io::IReadFile* file); + + //! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. + virtual u32 getFrameCount() const; + + //! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1); + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const; + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box); + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! Returns frame loop data for a special MD2 animation type. + virtual void getFrameLoop(EMD2_ANIMATION_TYPE, + s32& outBegin, s32& outEnd, s32& outFps) const; + + //! Returns frame loop data for a special MD2 animation type. + virtual bool getFrameLoop(const c8* name, + s32& outBegin, s32& outEnd, s32& outFps) const; + + //! Returns amount of md2 animations in this file. + virtual s32 getAnimationCount() const; + + //! Returns name of md2 animation. + //! \param nr: Zero based index of animation. + virtual const c8* getAnimationName(s32 nr) const; + + private: + + //! updates the interpolation buffer + void updateInterpolationBuffer(s32 frame, s32 startFrame, s32 endFrame); + + //! calculates the bounding box + virtual void calculateBoundingBox(); + + core::array *FrameList; + core::array > BoxList; + u32 FrameCount; + s32 TriangleCount; + + SMeshBuffer InterpolationBuffer; + + struct SFrameData + { + core::stringc name; + s32 begin; + s32 end; + s32 fps; + }; + + core::array< SFrameData > FrameData; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CAnimatedMeshMD3.cpp b/src/dep/src/irrlicht/CAnimatedMeshMD3.cpp new file mode 100644 index 0000000..190987e --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshMD3.cpp @@ -0,0 +1,404 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Fabio Concas / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + +#include "CAnimatedMeshMD3.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + +struct SMD3Bone +{ + f32 Mins[3]; // bounding box per frame + f32 Maxs[3]; + f32 Position[3]; // position of bounding box + f32 scale; + c8 creator[16]; +}; + + +struct SMD3Tag +{ + c8 Name[64]; //name of 'tag' as it's usually called in the md3 files try to see it as a sub-mesh/seperate mesh-part. + f32 position[3]; //relative position of tag + f32 rotationMatrix[9]; //3x3 rotation direction of tag +}; + +struct SMD3Skin +{ + c8 name[68]; // name of skin +}; + + + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + +//! Constructor +CAnimatedMeshMD3::CAnimatedMeshMD3 () +: Mesh ( 0 ) +{ +#ifdef _DEBUG + setDebugName("CAnimatedMeshMD3"); +#endif + + Mesh = new SMD3Mesh (); + memset ( &Mesh->MD3Header, 0, sizeof ( Mesh->MD3Header ) ); + + setInterpolationShift ( 0, 0 ); +} + + +//! Destructor +CAnimatedMeshMD3::~CAnimatedMeshMD3() +{ + if ( Mesh ) + Mesh->drop (); +} + + +//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CAnimatedMeshMD3::getFrameCount() const +{ + return Mesh->MD3Header.numFrames << IPolShift; +} + + +//! Rendering Hint +void CAnimatedMeshMD3::setInterpolationShift ( u32 shift, u32 loopMode ) +{ + IPolShift = shift; +} + + +//! Returns the animated tag list based on a detail level. 0 is the lowest, 255 the highest detail. +SMD3QuaterionTagList *CAnimatedMeshMD3::getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + if ( 0 == Mesh ) + return 0; + + getMesh ( frame, detailLevel, startFrameLoop, endFrameLoop ); + return &TagListIPol; +} + + +//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. +IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + if ( 0 == Mesh ) + return 0; + + u32 i; + + //! check if we have the mesh in our private cache + SCacheInfo candidate ( frame, startFrameLoop, endFrameLoop ); + if ( candidate == Current ) + return &MeshIPol; + + startFrameLoop = core::s32_max ( 0, startFrameLoop >> IPolShift ); + endFrameLoop = core::if_c_a_else_b ( endFrameLoop < 0, Mesh->MD3Header.numFrames - 1, endFrameLoop >> IPolShift ); + + const u32 mask = 1 << IPolShift; + + s32 frameA; + s32 frameB; + f32 iPol; + + if ( LoopMode ) + { + // correct frame to "pixel center" + frame -= mask >> 1; + + // interpolation + iPol = f32(frame & ( mask - 1 )) * core::reciprocal ( f32(mask) ); + + // wrap anim + frame >>= IPolShift; + frameA = core::if_c_a_else_b ( frame < startFrameLoop, endFrameLoop, frame ); + frameB = core::if_c_a_else_b ( frameA + 1 > endFrameLoop, startFrameLoop, frameA + 1 ); + } + else + { + // correct frame to "pixel center" + frame -= mask >> 1; + + iPol = f32(frame & ( mask - 1 )) * core::reciprocal ( f32(mask) ); + + // clamp anim + frame >>= IPolShift; + frameA = core::s32_clamp ( frame, startFrameLoop, endFrameLoop ); + frameB = core::s32_min ( frameA + 1, endFrameLoop ); + } + + // build current vertex + for ( i = 0; i!= Mesh->Buffer.size (); ++i ) + { + buildVertexArray(frameA, frameB, iPol, + Mesh->Buffer[i], + (SMeshBuffer*) MeshIPol.getMeshBuffer(i) + ); + } + MeshIPol.recalculateBoundingBox (); + + // build current tags + buildTagArray ( frameA, frameB, iPol ); + + Current = candidate; + return &MeshIPol; +} + +//! create a Irrlicht MeshBuffer for a MD3 MeshBuffer +IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer ( const SMD3MeshBuffer * source ) +{ + SMeshBuffer * dest = new SMeshBuffer (); + dest->Vertices.set_used ( source->MeshHeader.numVertices ); + dest->Indices.set_used ( source->Indices.size () ); + + u32 i; + + // fill in static face info + for ( i = 0; i < source->Indices.size (); i += 3 ) + { + dest->Indices[i + 0 ] = (u16) source->Indices[i + 0]; + dest->Indices[i + 1 ] = (u16) source->Indices[i + 1]; + dest->Indices[i + 2 ] = (u16) source->Indices[i + 2]; + } + + // fill in static vertex info + for ( i = 0; i!= (u32)source->MeshHeader.numVertices; ++i ) + { + video::S3DVertex &v = dest->Vertices [ i ]; + v.Color = 0xFFFFFFFF; + v.TCoords.X = source->Tex[i].u; + v.TCoords.Y = source->Tex[i].v; + } + return dest; +} + + +//! build final mesh's vertices from frames frameA and frameB with linear interpolation. +void CAnimatedMeshMD3::buildVertexArray ( u32 frameA, u32 frameB, f32 interpolate, + const SMD3MeshBuffer * source, + SMeshBuffer * dest + ) +{ + const u32 frameOffsetA = frameA * source->MeshHeader.numVertices; + const u32 frameOffsetB = frameB * source->MeshHeader.numVertices; + const f32 scale = ( 1.f/ 64.f ); + + for (s32 i = 0; i != source->MeshHeader.numVertices; ++i) + { + video::S3DVertex &v = dest->Vertices [ i ]; + + const SMD3Vertex &vA = source->Vertices [ frameOffsetA + i ]; + const SMD3Vertex &vB = source->Vertices [ frameOffsetB + i ]; + + // position + v.Pos.X = scale * ( vA.position[0] + interpolate * ( vB.position[0] - vA.position[0] ) ); + v.Pos.Y = scale * ( vA.position[2] + interpolate * ( vB.position[2] - vA.position[2] ) ); + v.Pos.Z = scale * ( vA.position[1] + interpolate * ( vB.position[1] - vA.position[1] ) ); + + // normal + const core::vector3df nA(getNormal ( vA.normal[0], vA.normal[1] )); + const core::vector3df nB(getNormal ( vB.normal[0], vB.normal[1] )); + + v.Normal.X = nA.X + interpolate * ( nB.X - nA.X ); + v.Normal.Y = nA.Z + interpolate * ( nB.Z - nA.Z ); + v.Normal.Z = nA.Y + interpolate * ( nB.Y - nA.Y ); + } + + dest->recalculateBoundingBox (); +} + + +//! build final mesh's tag from frames frameA and frameB with linear interpolation. +void CAnimatedMeshMD3::buildTagArray ( u32 frameA, u32 frameB, f32 interpolate ) +{ + const u32 frameOffsetA = frameA * Mesh->MD3Header.numTags; + const u32 frameOffsetB = frameB * Mesh->MD3Header.numTags; + + for ( s32 i = 0; i != Mesh->MD3Header.numTags; ++i ) + { + SMD3QuaterionTag &d = TagListIPol [ i ]; + + const SMD3QuaterionTag &qA = Mesh->TagList.Container[ frameOffsetA + i]; + const SMD3QuaterionTag &qB = Mesh->TagList.Container[ frameOffsetB + i]; + + // rotation + d.rotation.slerp( qA.rotation, qB.rotation, interpolate ); + + // position + d.position.X = qA.position.X + interpolate * ( qB.position.X - qA.position.X ); + d.position.Y = qA.position.Y + interpolate * ( qB.position.Y - qA.position.Y ); + d.position.Z = qA.position.Z + interpolate * ( qB.position.Z - qA.position.Z ); + } +} + + +/*! + loads a model +*/ +bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file) +{ + if (!file) + return false; + + //! Check MD3Header + { + file->read( &Mesh->MD3Header, sizeof(SMD3Header) ); + + if ( strncmp("IDP3", Mesh->MD3Header.headerID, 4) ) + { + os::Printer::log("MD3 Loader: invalid header"); + return false; + } + } + + //! store model name + Mesh->Name = file->getFileName(); + + //! Bone Frames Data ( ignore ) + //! Tag Data + const u32 totalTags = Mesh->MD3Header.numTags * Mesh->MD3Header.numFrames; + + SMD3Tag import; + SMD3QuaterionTag exp; + u32 i; + + file->seek( Mesh->MD3Header.tagStart ); + for (i = 0; i != totalTags; ++i ) + { + file->read(&import, sizeof(import) ); + + //! tag name + exp.Name = import.Name; + + //! position + exp.position.X = import.position[0]; + exp.position.Y = import.position[2]; + exp.position.Z = import.position[1]; + + //! construct quaternion from a RH 3x3 Matrix + exp.rotation.set (import.rotationMatrix[7], + 0.f, + -import.rotationMatrix[6], + 1 + import.rotationMatrix[8]); + exp.rotation.normalize (); + Mesh->TagList.Container.push_back ( exp ); + } + + //! Meshes + u32 offset = Mesh->MD3Header.tagEnd; + + SMD3Skin skin; + + for (i = 0; i != (u32)Mesh->MD3Header.numMeshes; ++i ) + { + //! construct a new mesh buffer + SMD3MeshBuffer * buf = new SMD3MeshBuffer (); + + // !read mesh header info + SMD3MeshHeader &meshHeader = buf->MeshHeader; + + //! read mesh info + file->seek( offset ); + file->read( &meshHeader, sizeof(SMD3MeshHeader) ); + + //! prepare memory + buf->Vertices.set_used ( meshHeader.numVertices * Mesh->MD3Header.numFrames ); + buf->Indices.set_used ( meshHeader.numTriangles * 3 ); + buf->Tex.set_used ( meshHeader.numVertices ); + + + //! read skins (shaders) + file->seek( offset + buf->MeshHeader.offset_shaders ); + for ( s32 g = 0; g != buf->MeshHeader.numShader; ++g ) + { + file->read( &skin, sizeof(skin) ); + buf->Shader.push_back ( skin.name ); + } + + //! read texture coordinates + file->seek( offset + buf->MeshHeader.offset_st); + file->read( buf->Tex.pointer(), buf->MeshHeader.numVertices * sizeof(SMD3TexCoord) ); + + //! read vertices + file->seek(offset + meshHeader.vertexStart); + file->read( buf->Vertices.pointer(), Mesh->MD3Header.numFrames * meshHeader.numVertices * sizeof(SMD3Vertex) ); + + //! read indices + file->seek( offset + meshHeader.offset_triangles ); + file->read( buf->Indices.pointer(), meshHeader.numTriangles * sizeof(SMD3Face) ); + + //! store meshBuffer + Mesh->Buffer.push_back ( buf ); + + offset += meshHeader.offset_end; + } + + // Init Mesh Interpolation + for ( i = 0; i != Mesh->Buffer.size (); ++i ) + { + IMeshBuffer * buffer = createMeshBuffer ( Mesh->Buffer[i] ); + MeshIPol.addMeshBuffer ( buffer ); + buffer->drop (); + } + + // Init Tag Interpolation + for (i = 0; i != (u32)Mesh->MD3Header.numTags; ++i ) + { + TagListIPol.Container.push_back ( Mesh->TagList.Container[i] ); + } + + return true; +} + + +SMD3Mesh * CAnimatedMeshMD3::getOriginalMesh () +{ + return Mesh; +} + + +//! Returns an axis aligned bounding box +const core::aabbox3d& CAnimatedMeshMD3::getBoundingBox() const +{ + return MeshIPol.BoundingBox; +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const +{ + return EAMT_MD3; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD3_LOADER_ + diff --git a/src/dep/src/irrlicht/CAnimatedMeshMD3.h b/src/dep/src/irrlicht/CAnimatedMeshMD3.h new file mode 100644 index 0000000..aec8161 --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshMD3.h @@ -0,0 +1,138 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_MD3_H_INCLUDED__ +#define __C_ANIMATED_MESH_MD3_H_INCLUDED__ + +#include "IAnimatedMeshMD3.h" +#include "IReadFile.h" +#include "IFileSystem.h" +#include "irrArray.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + + class CAnimatedMeshMD3 : public IAnimatedMeshMD3 + { + public: + + //! constructor + CAnimatedMeshMD3(); + + //! destructor + virtual ~CAnimatedMeshMD3(); + + //! loads a quake3 md3 file + virtual bool loadModelFile( u32 modelIndex, io::IReadFile* file); + + // IAnimatedMeshMD3 + virtual void setInterpolationShift ( u32 shift, u32 loopMode ); + virtual SMD3Mesh * getOriginalMesh (); + virtual SMD3QuaterionTagList *getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop); + + //IAnimatedMesh + virtual u32 getFrameCount() const; + virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop); + virtual const core::aabbox3d& getBoundingBox() const; + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + + //link? + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return 0; + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return 0; + } + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const + { + return 0; + } + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + return; + } + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box) + { + return; + } + + + private: + //! animates one frame + inline void Animate (u32 frame); + + video::SMaterial Material; + + //! hold original compressed MD3 Info + SMD3Mesh *Mesh; + + u32 IPolShift; + u32 LoopMode; + f32 Scaling; + + //! Cache Info + struct SCacheInfo + { + SCacheInfo ( s32 frame = -1, s32 start = -1, s32 end = -1 ) + : Frame ( frame ), startFrameLoop ( start ), + endFrameLoop ( end ) {} + + bool operator == ( const SCacheInfo &other ) const + { + return 0 == memcmp ( this, &other, sizeof ( SCacheInfo ) ); + } + s32 Frame; + s32 startFrameLoop; + s32 endFrameLoop; + }; + SCacheInfo Current; + + //! return a Mesh per frame + SMesh MeshIPol; + SMD3QuaterionTagList TagListIPol; + + IMeshBuffer * createMeshBuffer ( const SMD3MeshBuffer *source ); + + void buildVertexArray ( u32 frameA, u32 frameB, f32 interpolate, + const SMD3MeshBuffer * source, + SMeshBuffer * dest + ); + + void buildTagArray ( u32 frameA, u32 frameB, f32 interpolate ); + + core::vector3df getNormal ( u32 i, u32 j ) + { + const f32 lng = i * 2.0f * core::PI / 255.0f; + const f32 lat = j * 2.0f * core::PI / 255.0f; + return core::vector3df(cosf ( lat ) * sinf ( lng ), + sinf ( lat ) * sinf ( lng ), + cos ( lng )); + } + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CAnimatedMeshSceneNode.cpp b/src/dep/src/irrlicht/CAnimatedMeshSceneNode.cpp new file mode 100644 index 0000000..0e8f654 --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshSceneNode.cpp @@ -0,0 +1,1010 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAnimatedMeshSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "os.h" +#include "CShadowVolumeSceneNode.h" +#include "IAnimatedMeshMD3.h" +#include "CSkinnedMesh.h" +#include "IDummyTransformationSceneNode.h" +#include "IBoneSceneNode.h" +#include "IMaterialRenderer.h" +#include "IMesh.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "quaternion.h" + + +namespace irr +{ +namespace scene +{ + + +//! constructor +CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) +: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), + BeginFrameTime(0), StartFrame(0), EndFrame(0), FramesPerSecond(25.f / 1000.f ), + CurrentFrameNr(0.f), JointMode(EJUOR_NONE), JointsUsed(false), + TransitionTime(0), Transiting(0.f), TransitingBlend(0.f), + Looping(true), ReadOnlyMaterials(false), + LoopCallBack(0), PassCount(0), Shadow(0), RenderFromIdentity(0) +{ + #ifdef _DEBUG + setDebugName("CAnimatedMeshSceneNode"); + #endif + + BeginFrameTime = os::Timer::getTime(); + + setMesh(mesh); +} + + +//! destructor +CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode() +{ + if (Mesh) + Mesh->drop(); + + if (Shadow) + Shadow->drop(); + + //for (u32 i=0; idrop(); + + if (LoopCallBack) + LoopCallBack->drop(); +} + + +//! Sets the current frame. From now on the animation is played from this frame. +void CAnimatedMeshSceneNode::setCurrentFrame(f32 frame) +{ + // if you pass an out of range value, we just clamp it + CurrentFrameNr = core::clamp ( frame, (f32)StartFrame, (f32)EndFrame ); + + BeginFrameTime = os::Timer::getTime() - (s32)((CurrentFrameNr - StartFrame) / FramesPerSecond); + + beginTransition(); //transit to this frame if enabled +} + + +//! Returns the current displayed frame number. +f32 CAnimatedMeshSceneNode::getFrameNr() const +{ + return CurrentFrameNr; +} + + +f32 CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs) +{ + if (Transiting!=0.f) + { + TransitingBlend = (f32)(timeMs-BeginFrameTime) * Transiting; + if (TransitingBlend > 1.f) + { + Transiting=0.f; + TransitingBlend=0.f; + } + } + + if (StartFrame==EndFrame) + return (f32)StartFrame; //Support for non animated meshes + if (FramesPerSecond==0.f) + return (f32)StartFrame; + + if (Looping) + { + // play animation looped + + if (FramesPerSecond > 0.f) //forwards... + { + const s32 lenInTime = s32( f32(EndFrame - StartFrame) / FramesPerSecond); + return StartFrame + ( (timeMs - BeginFrameTime) % lenInTime) *FramesPerSecond; + } + else //backwards... + { + const s32 lenInTime = s32( f32(EndFrame - StartFrame) / -FramesPerSecond); + return EndFrame - ( (timeMs - BeginFrameTime) % lenInTime)*-FramesPerSecond; + } + } + else + { + // play animation non looped + + f32 frame; + + if (FramesPerSecond > 0.f) //forwards... + { + const f32 deltaFrame = floorf( f32 ( timeMs - BeginFrameTime ) * FramesPerSecond ); + + frame = StartFrame + deltaFrame; + + if (frame > (f32)EndFrame) + { + frame = (f32)EndFrame; + if (LoopCallBack) + LoopCallBack->OnAnimationEnd(this); + } + } + else //backwards... (untested) + { + const f32 deltaFrame = floorf( f32 ( timeMs - BeginFrameTime ) * -FramesPerSecond ); + + frame = EndFrame - deltaFrame; + + if (frame < (f32)StartFrame) + { + frame = (f32)StartFrame; + if (LoopCallBack) + LoopCallBack->OnAnimationEnd(this); + } + + } + + return frame; + } +} + +//! frame +void CAnimatedMeshSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + int transparentCount = 0; + int solidCount = 0; + + // count transparent and solid materials in this scene node + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + + for (u32 j=0; jOnRegisterSceneNode(); + } +} + + + +//! OnAnimate() is called just before rendering the whole scene. +void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs) +{ + + CurrentFrameNr = buildFrameNr ( timeMs ); + + if ( Mesh ) + { + /* + scene::IMesh *m = Mesh->getMesh(CurrentFrameNr, 255, StartFrame, EndFrame); + if ( m ) + { + Box = m->getBoundingBox(); + } + */ + } + + + IAnimatedMeshSceneNode::OnAnimate ( timeMs ); + +} + + +/* + angle = dotproduct ( v(0,1,0), up ) + axis = crossproduct ( v(0,1,0), up ) +*/ +inline void AlignToUpVector(core::matrix4 &m, const core::vector3df &up ) +{ + core::quaternion quatRot( up.Z, 0.f, -up.X, 1 + up.Y ); + quatRot.normalize(); + quatRot.getMatrix ( m ); +} + + + +//! renders the node. +void CAnimatedMeshSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!Mesh || !driver) + return; + + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + + ++PassCount; + + f32 frame = getFrameNr(); + + scene::IMesh* m; + + if (Mesh->getMeshType() != EAMT_SKINNED) + m = Mesh->getMesh((s32)frame, 255, StartFrame, EndFrame); + else + { + CSkinnedMesh* skinnedMesh = reinterpret_cast(Mesh); + + if (JointMode == EJUOR_CONTROL)//write to mesh + skinnedMesh->transferJointsToMesh(JointChildSceneNodes); + else + skinnedMesh->animateMesh(frame, 1.0f); + + skinnedMesh->skinMesh(); + + if (JointMode == EJUOR_READ)//read from mesh + { + skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes); + + //---slow--- + for (u32 n=0;ngetParent()==this) + { + JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option + } + + } + + + m=skinnedMesh; + } + + + if ( 0 == m ) + { + #ifdef _DEBUG + os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING); + #endif + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + + if (Shadow && PassCount==1) + Shadow->setMeshToRenderFrom(m); + + // for debug purposes only: + + u32 renderMeshes = 1; + video::SMaterial mat; + if (DebugDataVisible && PassCount==1) + { + // overwrite half transparency + if ( DebugDataVisible & scene::EDS_HALF_TRANSPARENCY ) + { + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + mat = Materials[g]; + mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + driver->setMaterial(mat); + driver->drawMeshBuffer ( m->getMeshBuffer(g) ); + } + renderMeshes = 0; + } + } + + // render original meshes + if ( renderMeshes ) + { + for (u32 i=0; igetMeshBufferCount(); ++i) + { + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + + if (RenderFromIdentity) + driver->setTransform(video::ETS_WORLD, core::matrix4() ); + else if (Mesh->getMeshType() == EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); + + + driver->setMaterial(Materials[i]); + driver->drawMeshBuffer(mb); + } + } + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + // for debug purposes only: + if (DebugDataVisible && PassCount==1) + { + mat.Lighting = false; + driver->setMaterial(mat); + + // show bounding box + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + for (u32 g=0; g< m->getMeshBufferCount(); ++g) + { + driver->draw3DBox( m->getMeshBuffer(g)->getBoundingBox(), + video::SColor(0,190,128,128) ); + } + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box, video::SColor(0,255,255,255)); + + // show skeleton + if ( DebugDataVisible & scene::EDS_SKELETON ) + { + if (Mesh->getMeshType() == EAMT_SKINNED) + { + + // draw skeleton + + + for (u32 g=0; g < ((ISkinnedMesh*)Mesh)->getAllJoints().size(); ++g) + { + ISkinnedMesh::SJoint *joint=((ISkinnedMesh*)Mesh)->getAllJoints()[g]; + + for (u32 n=0;nChildren.size();++n) + { + driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(), joint->Children[n]->GlobalAnimatedMatrix.getTranslation(), video::SColor(0,51,66,255)); + } + } + } + + // show tag for quake3 models + if (Mesh->getMeshType() == EAMT_MD3 ) + { + IAnimatedMesh * arrow = + SceneManager->addArrowMesh ( + "__tag_show", + 0xFF0000FF, 0xFF000088, + 4, 8, 5.f, 4.f, 0.5f, + 1.f); + if ( 0 == arrow ) + { + arrow = SceneManager->getMesh ( "__tag_show" ); + } + IMesh *arrowMesh = arrow->getMesh ( 0 ); + + video::SMaterial material; + material.Lighting = false; + driver->setMaterial(material); + + core::matrix4 matr; + + SMD3QuaterionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList ( (s32)getFrameNr(), + 255, + getStartFrame (), + getEndFrame () + ); + if ( taglist ) + { + for ( u32 ts = 0; ts != taglist->size(); ++ts ) + { + (*taglist)[ts].setto ( matr ); + + driver->setTransform(video::ETS_WORLD, matr ); + + for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a ) + driver->drawMeshBuffer ( arrowMesh->getMeshBuffer ( a ) ); + } + } + } + } + + // show normals + if ( DebugDataVisible & scene::EDS_NORMALS ) + { + IAnimatedMesh * arrow = SceneManager->addArrowMesh ( + "__debugnormal", 0xFFECEC00, + 0xFF999900, 4, 8, 1.f, 0.6f, 0.05f, + 0.3f); + if ( 0 == arrow ) + { + arrow = SceneManager->getMesh ( "__debugnormal" ); + } + IMesh *mesh = arrow->getMesh ( 0 ); + + // find a good scaling factor + + core::matrix4 m2; + + // draw normals + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + const scene::IMeshBuffer* mb = m->getMeshBuffer(g); + const u32 vSize = video::getVertexPitchFromType(mb->getVertexType()); + const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices(); + for ( u32 i=0; i != mb->getVertexCount(); ++i ) + { + AlignToUpVector ( m2, v->Normal ); + + m2.setTranslation(v->Pos); + m2*=AbsoluteTransformation; + + driver->setTransform(video::ETS_WORLD, m2 ); + for ( u32 a = 0; a != mesh->getMeshBufferCount(); ++a ) + driver->drawMeshBuffer ( mesh->getMeshBuffer ( a ) ); + + v = (const video::S3DVertex*) ( (u8*) v + vSize ); + } + } + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + } + + // show mesh + if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY ) + { + mat.Lighting = false; + mat.Wireframe = true; + driver->setMaterial(mat); + + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + driver->drawMeshBuffer( m->getMeshBuffer(g) ); + } + } + } +} + + +//! Returns the current start frame number. +s32 CAnimatedMeshSceneNode::getStartFrame() const +{ + return StartFrame; +} + +//! Returns the current start frame number. +s32 CAnimatedMeshSceneNode::getEndFrame() const +{ + return EndFrame; +} + +//! sets the frames between the animation is looped. +//! the default is 0 - MaximalFrameCount of the mesh. +bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end) +{ + const s32 maxFrameCount = Mesh->getFrameCount() - 1; + if ( end < begin ) + { + StartFrame = core::s32_clamp(end, 0, maxFrameCount); + EndFrame = core::s32_clamp(begin, StartFrame, maxFrameCount); + } + else + { + StartFrame = core::s32_clamp(begin, 0, maxFrameCount); + EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount); + } + setCurrentFrame ( (f32)StartFrame ); + + return true; +} + + + +//! sets the speed with witch the animation is played +void CAnimatedMeshSceneNode::setAnimationSpeed(f32 framesPerSecond) +{ + FramesPerSecond = framesPerSecond * 0.001f; +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CAnimatedMeshSceneNode::getBoundingBox() const +{ + return Box; +} + + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CAnimatedMeshSceneNode::getMaterial(u32 i) +{ + if ( i >= Materials.size() ) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + + + +//! returns amount of materials used by this scene node. +u32 CAnimatedMeshSceneNode::getMaterialCount() const +{ + return Materials.size(); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode(s32 id, + bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (Shadow) + { + os::Printer::log("This node already has a shadow.", ELL_WARNING); + return 0; + } + + Shadow = new CShadowVolumeSceneNode(this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName) +{ + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + return 0; + + checkJoints(); + + + ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; + + s32 number = skinnedMesh->getJointNumber(jointName); + + if (number == -1) + { + os::Printer::log("Joint with specified name not found in skinned mesh.", jointName, ELL_WARNING); + return 0; + } + + if ((s32)JointChildSceneNodes.size() <= number) + { + os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING); + return 0; + } + + return getJointNode((u32)number); +} + + +IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(u32 jointID) +{ + if (JointChildSceneNodes.size() <= jointID) + { + os::Printer::log("Joint not loaded into node", ELL_WARNING); + return 0; + } + + return JointChildSceneNodes[jointID]; +} + + +//! Returns a pointer to a child node, which has the same transformation as +//! the corrsesponding joint, if the mesh in this scene node is a ms3d mesh. +ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName) +{ + return getJointNode(jointName); +} + + +//! Returns a pointer to a child node, which has the same transformation as +//! the corrsesponding joint, if the mesh in this scene node is a ms3d mesh. +ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName) +{ + return getJointNode(jointName); +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + return true; + } + + if (ISceneNode::removeChild(child)) + { + if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created + { + for (u32 i=0; igetMeshType() != EAMT_MD2) + return false; + + IAnimatedMeshMD2* m = (IAnimatedMeshMD2*)Mesh; + + s32 begin, end, speed; + m->getFrameLoop(anim, begin, end, speed); + + setAnimationSpeed( f32(speed) ); + setFrameLoop(begin, end); + return true; +} + + +//! Starts a special MD2 animation. +bool CAnimatedMeshSceneNode::setMD2Animation(const c8* animationName) +{ + if (!Mesh || Mesh->getMeshType() != EAMT_MD2) + return false; + + IAnimatedMeshMD2* m = (IAnimatedMeshMD2*)Mesh; + + s32 begin, end, speed; + if (!m->getFrameLoop(animationName, begin, end, speed)) + return false; + + setAnimationSpeed( (f32)speed ); + setFrameLoop(begin, end); + return true; +} + + +//! Sets looping mode which is on by default. If set to false, +//! animations will not be looped. +void CAnimatedMeshSceneNode::setLoopMode(bool playAnimationLooped) +{ + Looping = playAnimationLooped; +} + + +//! Sets a callback interface which will be called if an animation +//! playback has ended. Set this to 0 to disable the callback again. +void CAnimatedMeshSceneNode::setAnimationEndCallback(IAnimationEndCallBack* callback) +{ + if (LoopCallBack) + LoopCallBack->drop(); + + LoopCallBack = callback; + + if (LoopCallBack) + LoopCallBack->grab(); +} + + +//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. +void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly) +{ + ReadOnlyMaterials = readonly; +} + + +//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style +bool CAnimatedMeshSceneNode::isReadOnlyMaterials() const +{ + return ReadOnlyMaterials; +} + + +//! Writes attributes of the scene node. +void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IAnimatedMeshSceneNode::serializeAttributes(out, options); + + out->addString("Mesh", SceneManager->getMeshCache()->getMeshFilename(Mesh)); + out->addBool("Looping", Looping); + out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); + out->addFloat("FramesPerSecond", FramesPerSecond); + + // TODO: write animation names instead of frame begin and ends +} + + +//! Reads attributes of the scene node. +void CAnimatedMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IAnimatedMeshSceneNode::deserializeAttributes(in, options); + + core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh); + core::stringc newMeshStr = in->getAttributeAsString("Mesh"); + + Looping = in->getAttributeAsBool("Looping"); + ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); + FramesPerSecond = in->getAttributeAsFloat("FramesPerSecond"); + + if (newMeshStr != "" && oldMeshStr != newMeshStr) + { + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + setMesh(newAnimatedMesh); + } + + // TODO: read animation names instead of frame begin and ends +} + + +//! Sets a new mesh +void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh) +{ + if (!mesh) + return; // won't set null mesh + + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + + // get materials and bounding box + Box = Mesh->getBoundingBox(); + + IMesh* m = Mesh->getMesh(0,0); + if (m) + { + Materials.clear(); + + video::SMaterial mat; + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* mb = m->getMeshBuffer(i); + if (mb) + mat = mb->getMaterial(); + + Materials.push_back(mat); + } + } + + // get start and begin time + setFrameLoop ( 0, Mesh->getFrameCount() ); + + // grab the mesh + if (Mesh) + Mesh->grab(); +} + +// returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, +// or the absolutetransformation if it's a normal scenenode +const SMD3QuaterionTag& CAnimatedMeshSceneNode::getMD3TagTransformation( const core::stringc & tagname) +{ + SMD3QuaterionTag * tag = MD3Special.AbsoluteTagList.get ( tagname ); + if ( tag ) + return *tag; + + MD3Special.AbsoluteTagList.Container.push_back ( SMD3QuaterionTag ( tagname, AbsoluteTransformation ) ); + return *MD3Special.AbsoluteTagList.get ( tagname ); +} + + +//! updates the absolute position based on the relative and the parents position +void CAnimatedMeshSceneNode::updateAbsolutePosition() +{ + if ( 0 == Mesh || Mesh->getMeshType() != EAMT_MD3 ) + { + IAnimatedMeshSceneNode::updateAbsolutePosition(); + return; + } + + SMD3QuaterionTag parent; + if ( Parent && Parent->getType () == ESNT_ANIMATED_MESH) + { + parent = ((IAnimatedMeshSceneNode*) Parent)->getMD3TagTransformation ( MD3Special.Tagname ); + } + + SMD3QuaterionTag relative( RelativeTranslation, RelativeRotation ); + + SMD3QuaterionTagList *taglist; + taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () ); + if ( taglist ) + { + MD3Special.AbsoluteTagList.Container.set_used ( taglist->size () ); + for ( u32 i=0; i!= taglist->size (); ++i ) + { + MD3Special.AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position; + MD3Special.AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation; + } + } +} + +//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) +void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode) +{ + checkJoints(); + + //if (mode<0) mode=0; + //if (mode>3) mode=3; + + JointMode=mode; +} + + +//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) +//! you must call animateJoints(), or the mesh will not animate +void CAnimatedMeshSceneNode::setTransitionTime(f32 time) +{ + if (time != 0.0f) + { + checkJoints(); + setJointMode(EJUOR_CONTROL); + TransitionTime = (u32)core::floor32(time*1000.0f); + } +} + +//! render mesh ignoring it's transformation. Used with ragdolls. (culling is unaffected) +void CAnimatedMeshSceneNode::setRenderFromIdentity( bool On ) +{ + RenderFromIdentity=On; +} + + + +//! updates the joint positions of this mesh +void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions) +{ + checkJoints(); + + if (Mesh && Mesh->getMeshType() == EAMT_SKINNED ) + { + if (JointsUsed) + { + f32 frame = getFrameNr(); //old? + + CSkinnedMesh* skinnedMesh=reinterpret_cast(Mesh); + + skinnedMesh->animateMesh(frame, 1.0f); + + skinnedMesh->recoverJointsFromMesh( JointChildSceneNodes); + + if (CalculateAbsolutePositions) + { + //---slow--- + for (u32 n=0;ngetParent()==this) + { + JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option + } + } + + //----------------------------------------- + // Transition + //----------------------------------------- + + if (Transiting != 0.f) + { + //Check the array is big enough (not really needed) + if (PretransitingSave.size()setPosition( + core::lerp( + PretransitingSave[n].getTranslation(), + JointChildSceneNodes[n]->getPosition(), + TransitingBlend)); + + //------Rotation------ + + //Code is slow, needs to be fixed up + + const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees()*core::DEGTORAD); + const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation()*core::DEGTORAD); + + core::quaternion QRotation; + QRotation.slerp(RotationStart, RotationEnd, TransitingBlend); + + core::vector3df tmpVector; + QRotation.toEuler(tmpVector); + tmpVector*=core::RADTODEG; //convert from radians back to degrees + JointChildSceneNodes[n]->setRotation( tmpVector ); + + //------Scale------ + + //JointChildSceneNodes[n]->setScale( + // core::lerp( + // PretransitingSave[n].getScale(), + // JointChildSceneNodes[n]->getScale(), + // TransitingBlend)); + } + } + } + } +} + + + + +void CAnimatedMeshSceneNode::checkJoints() +{ + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + return; + + if (!JointsUsed) + { + //Create joints for SkinnedMesh + + ((CSkinnedMesh*)Mesh)->createJoints(JointChildSceneNodes, this, SceneManager); + ((CSkinnedMesh*)Mesh)->recoverJointsFromMesh(JointChildSceneNodes); + + JointsUsed=true; + JointMode=EJUOR_READ; + } +} + +void CAnimatedMeshSceneNode::beginTransition() +{ + if (!JointsUsed) + return; + + if (TransitionTime != 0) + { + //Check the array is big enough + if (PretransitingSave.size()getRelativeTransformation(); + + Transiting = core::reciprocal((f32)TransitionTime); + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CAnimatedMeshSceneNode.h b/src/dep/src/irrlicht/CAnimatedMeshSceneNode.h new file mode 100644 index 0000000..8e9b26c --- /dev/null +++ b/src/dep/src/irrlicht/CAnimatedMeshSceneNode.h @@ -0,0 +1,203 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ +#define __C_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ + +#include "IAnimatedMeshSceneNode.h" +#include "IAnimatedMesh.h" + +#include "matrix4.h" + + +namespace irr +{ +namespace scene +{ + class IDummyTransformationSceneNode; + + class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode + { + public: + + //! constructor + CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CAnimatedMeshSceneNode(); + + //! sets the current frame. from now on the animation is played from this frame. + virtual void setCurrentFrame(f32 frame); + + //! frame + virtual void OnRegisterSceneNode(); + + //! OnAnimate() is called just before rendering the whole scene. + virtual void OnAnimate(u32 timeMs); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the frames between the animation is looped. + //! the default is 0 - MaximalFrameCount of the mesh. + virtual bool setFrameLoop(s32 begin, s32 end); + + //! Sets looping mode which is on by default. If set to false, + //! animations will not be looped. + virtual void setLoopMode(bool playAnimationLooped); + + //! Sets a callback interface which will be called if an animation + //! playback has ended. Set this to 0 to disable the callback again. + virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0); + + //! sets the speed with witch the animation is played + virtual void setAnimationSpeed(f32 framesPerSecond); + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(s32 id, + bool zfailmethod=true, f32 infinity=10000.0f); + + //! Returns a pointer to a child node, which has the same transformation as + //! the corrsesponding joint, if the mesh in this scene node is a skinned mesh. + virtual IBoneSceneNode* getJointNode(const c8* jointName); + + //! same as getJointNode(const c8* jointName), but based on id + virtual IBoneSceneNode* getJointNode(u32 jointID); + + //! Redundant command, please use getJointNode. + virtual ISceneNode* getMS3DJointNode(const c8* jointName); + + //! Redundant command, please use getJointNode. + virtual ISceneNode* getXJointNode(const c8* jointName); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + //! Starts a MD2 animation. + virtual bool setMD2Animation(EMD2_ANIMATION_TYPE anim); + + //! Starts a special MD2 animation. + virtual bool setMD2Animation(const c8* animationName); + + //! Returns the current displayed frame number. + virtual f32 getFrameNr() const; + //! Returns the current start frame number. + virtual s32 getStartFrame() const; + //! Returns the current end frame number. + virtual s32 getEndFrame() const; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly); + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const; + + //! Sets a new mesh + virtual void setMesh(IAnimatedMesh* mesh); + + //! Returns the current mesh + virtual IAnimatedMesh* getMesh(void) { return Mesh; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_ANIMATED_MESH; } + + // returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, + // or the absolutetransformation if it's a normal scenenode + const SMD3QuaterionTag& getMD3TagTransformation( const core::stringc & tagname); + + //! updates the absolute position based on the relative and the parents position + virtual void updateAbsolutePosition(); + + + //! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) + virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode); + + //! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) + //! you must call animateJoints(), or the mesh will not animate + virtual void setTransitionTime(f32 Time); + + //! updates the joint positions of this mesh + virtual void animateJoints(bool CalculateAbsolutePositions=true); + + //! render mesh ignoring it's transformation. Used with ragdolls. (culling is unaffected) + virtual void setRenderFromIdentity( bool On ); + + private: + + f32 buildFrameNr( u32 timeMs); + void checkJoints(); + void beginTransition(); + + core::array Materials; + core::aabbox3d Box; + IAnimatedMesh* Mesh; + + u32 BeginFrameTime; + s32 StartFrame; + s32 EndFrame; + f32 FramesPerSecond; + f32 CurrentFrameNr; + + E_JOINT_UPDATE_ON_RENDER JointMode; //0-unused, 1-get joints only, 2-set joints only, 3-move and set + bool JointsUsed; + + u32 TransitionTime; //Transition time in millisecs + + f32 Transiting; //is mesh transiting (plus cache of TransitionTime) + f32 TransitingBlend; //0-1, calculated on buildFrameNr + + bool Looping; + bool ReadOnlyMaterials; + + IAnimationEndCallBack* LoopCallBack; + s32 PassCount; + + IShadowVolumeSceneNode* Shadow; + + core::array JointChildSceneNodes; + core::array PretransitingSave; + + bool RenderFromIdentity; + + struct SMD3Special + { + core::stringc Tagname; + SMD3QuaterionTagList AbsoluteTagList; + }; + SMD3Special MD3Special; + + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CAttributeImpl.h b/src/dep/src/irrlicht/CAttributeImpl.h new file mode 100644 index 0000000..b7f6a88 --- /dev/null +++ b/src/dep/src/irrlicht/CAttributeImpl.h @@ -0,0 +1,1991 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAttributes.h" +#include "fast_atof.h" +#include "ITexture.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + +/* + basic types +*/ + +// Attribute implemented for boolean values +class CBoolAttribute : public IAttribute +{ +public: + + CBoolAttribute(const char* name, bool value) + { + Name = name; + setBool(value); + } + + virtual s32 getInt() + { + return BoolValue ? 1 : 0; + } + + virtual f32 getFloat() + { + return BoolValue ? 1.0f : 0.0f; + } + + virtual bool getBool() + { + return BoolValue; + } + + virtual core::stringw getStringW() + { + return core::stringw( BoolValue ? L"true" : L"false" ); + } + + virtual void setInt(s32 intValue) + { + BoolValue = (intValue != 0); + } + + virtual void setFloat(f32 floatValue) + { + BoolValue = (floatValue != 0); + } + + virtual void setBool(bool boolValue) + { + BoolValue = boolValue; + } + + virtual void setString(const char* string) + { + BoolValue = strcmp(string, "true") == 0; + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BOOL; + } + + virtual const wchar_t* getTypeString() const + { + return L"bool"; + } + + bool BoolValue; +}; + +// Attribute implemented for integers +class CIntAttribute : public IAttribute +{ +public: + + CIntAttribute(const char* name, s32 value) + { + Name = name; + setInt(value); + } + + virtual s32 getInt() + { + return Value; + } + + virtual f32 getFloat() + { + return (f32)Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + return core::stringw(Value); + } + + virtual void setInt(s32 intValue) + { + Value = intValue; + } + + virtual void setFloat(f32 floatValue) + { + Value = (s32)floatValue; + }; + + virtual void setString(const char* text) + { + Value = atoi(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_INT; + } + + + virtual const wchar_t* getTypeString() const + { + return L"int"; + } + + s32 Value; +}; + +// Attribute implemented for floats +class CFloatAttribute : public IAttribute +{ +public: + + CFloatAttribute(const char* name, f32 value) + { + Name = name; + setFloat(value); + } + + virtual s32 getInt() + { + return (s32)Value; + } + + virtual f32 getFloat() + { + return Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + return core::stringw(Value); + } + + virtual void setInt(s32 intValue) + { + Value = (f32)intValue; + } + + virtual void setFloat(f32 floatValue) + { + Value = floatValue; + } + + virtual void setString(const char* text) + { + Value = core::fast_atof(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_FLOAT; + } + + + virtual const wchar_t* getTypeString() const + { + return L"float"; + } + + f32 Value; +}; + + + +/* + Types which can be represented as a list of numbers +*/ + +// Base class for all attributes which are a list of numbers- +// vectors, colors, positions, triangles, etc +class CNumbersAttribute : public IAttribute +{ +public: + + CNumbersAttribute(const char* name, video::SColorf value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.r); + ValueF.push_back(value.g); + ValueF.push_back(value.b); + ValueF.push_back(value.a); + } + + CNumbersAttribute(const char* name, video::SColor value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.getRed()); + ValueI.push_back(value.getGreen()); + ValueI.push_back(value.getBlue()); + ValueI.push_back(value.getAlpha()); + } + + + CNumbersAttribute(const char* name, core::vector3df value) : + ValueI(), ValueF(), Count(3), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + ValueF.push_back(value.Z); + } + + CNumbersAttribute(const char* name, core::position2df value) : + ValueI(), ValueF(), Count(2), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::position2di value) : + ValueI(), ValueF(), Count(2), IsFloat(false) + { + Name = name; + ValueI.push_back(value.X); + ValueI.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::rect value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.UpperLeftCorner.X); + ValueI.push_back(value.UpperLeftCorner.Y); + ValueI.push_back(value.LowerRightCorner.X); + ValueI.push_back(value.LowerRightCorner.Y); + } + + CNumbersAttribute(const char* name, core::rect value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.UpperLeftCorner.X); + ValueF.push_back(value.UpperLeftCorner.Y); + ValueF.push_back(value.LowerRightCorner.X); + ValueF.push_back(value.LowerRightCorner.Y); + } + + CNumbersAttribute(const char* name, core::matrix4 value) : + ValueI(), ValueF(), Count(16), IsFloat(true) + { + Name = name; + for (s32 r=0; r<4; ++r) + for (s32 c=0; c<4; ++c) + ValueF.push_back(value(r,c)); + } + + CNumbersAttribute(const char* name, core::quaternion value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + ValueF.push_back(value.Z); + ValueF.push_back(value.W); + } + + CNumbersAttribute(const char* name, core::aabbox3d value) : + ValueI(), ValueF(), Count(6), IsFloat(true) + { + Name = name; + ValueF.push_back(value.MinEdge.X); + ValueF.push_back(value.MinEdge.Y); + ValueF.push_back(value.MinEdge.Z); + ValueF.push_back(value.MaxEdge.X); + ValueF.push_back(value.MaxEdge.Y); + ValueF.push_back(value.MaxEdge.Z); + } + + CNumbersAttribute(const char* name, core::plane3df value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.Normal.X); + ValueF.push_back(value.Normal.Y); + ValueF.push_back(value.Normal.Z); + ValueF.push_back(value.D); + } + + CNumbersAttribute(const char* name, core::triangle3df value) : + ValueI(), ValueF(), Count(9), IsFloat(true) + { + Name = name; + ValueF.push_back(value.pointA.X); + ValueF.push_back(value.pointA.Y); + ValueF.push_back(value.pointA.Z); + ValueF.push_back(value.pointB.X); + ValueF.push_back(value.pointB.Y); + ValueF.push_back(value.pointB.Z); + ValueF.push_back(value.pointC.X); + ValueF.push_back(value.pointC.Y); + ValueF.push_back(value.pointC.Z); + } + + CNumbersAttribute(const char* name, core::vector2df value) : + ValueI(), ValueF(), Count(2), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::vector2di value) : + ValueI(), ValueF(), Count(2), IsFloat(false) + { + Name = name; + ValueI.push_back(value.X); + ValueI.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::line2di value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.start.X); + ValueI.push_back(value.start.Y); + ValueI.push_back(value.end.X); + ValueI.push_back(value.end.Y); + } + + CNumbersAttribute(const char* name, core::line2df value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.start.X); + ValueF.push_back(value.start.Y); + ValueF.push_back(value.end.X); + ValueF.push_back(value.end.Y); + } + + CNumbersAttribute(const char* name, core::line3df value) : + ValueI(), ValueF(), Count(6), IsFloat(true) + { + Name = name; + ValueF.push_back(value.start.X); + ValueF.push_back(value.start.Y); + ValueF.push_back(value.start.Z); + ValueF.push_back(value.end.X); + ValueF.push_back(value.end.Y); + ValueF.push_back(value.end.Z); + } + + CNumbersAttribute(const char* name, core::dimension2di value) : + ValueI(), ValueF(), Count(2), IsFloat(false) + { + Name = name; + ValueI.push_back(value.Width); + ValueI.push_back(value.Height); + } + + + CNumbersAttribute(const char* name, core::dimension2df value) : + ValueI(), ValueF(), Count(2), IsFloat(true) + { + Name = name; + ValueF.push_back(value.Width); + ValueF.push_back(value.Height); + } + + + + // getting values + virtual s32 getInt() + { + if (Count==0) + return 0; + + if (IsFloat) + return (s32)ValueF[0]; + else + return ValueI[0]; + } + + virtual f32 getFloat() + { + if (Count==0) + return 0.0f; + + if (IsFloat) + return ValueF[0]; + else + return (f32)ValueI[0]; + } + + virtual bool getBool() + { + // return true if any number is nonzero + bool ret=false; + + for (u32 i=0; i < Count; ++i) + if ( IsFloat ? (ValueF[i] != 0) : (ValueI[i] != 0) ) + { + ret=true; + break; + } + + return ret; + + } + + + virtual core::stringc getString() + { + core::stringc outstr; + + for (u32 i=0; i 0 ? ValueF[0] : 0); + p.Y = (s32)(Count > 1 ? ValueF[1] : 0); + } + else + { + p.X = Count > 0 ? ValueI[0] : 0; + p.Y = Count > 1 ? ValueI[1] : 0; + } + + return p; + } + + virtual core::vector3df getVector() + { + core::vector3df v; + + if (IsFloat) + { + v.X = Count > 0 ? ValueF[0] : 0; + v.Y = Count > 1 ? ValueF[1] : 0; + v.Z = Count > 2 ? ValueF[2] : 0; + } + else + { + v.X = (f32)(Count > 0 ? ValueI[0] : 0); + v.Y = (f32)(Count > 1 ? ValueI[1] : 0); + v.Z = (f32)(Count > 2 ? ValueI[2] : 0); + } + + return v; + } + + virtual video::SColorf getColorf() + { + video::SColorf c; + if (IsFloat) + { + c.setColorComponentValue(0, Count > 0 ? ValueF[0] : 0); + c.setColorComponentValue(1, Count > 1 ? ValueF[1] : 0); + c.setColorComponentValue(2, Count > 2 ? ValueF[2] : 0); + c.setColorComponentValue(3, Count > 3 ? ValueF[3] : 0); + } + else + { + c.setColorComponentValue(0, Count > 0 ? (f32)(ValueI[0]) / 255.0f : 0); + c.setColorComponentValue(1, Count > 1 ? (f32)(ValueI[1]) / 255.0f : 0); + c.setColorComponentValue(2, Count > 2 ? (f32)(ValueI[2]) / 255.0f : 0); + c.setColorComponentValue(3, Count > 3 ? (f32)(ValueI[3]) / 255.0f : 0); + } + + return c; + } + + virtual video::SColor getColor() + { + return getColorf().toSColor(); + } + + + virtual core::rect getRect() + { + core::rect r; + + if (IsFloat) + { + r.UpperLeftCorner.X = (s32)(Count > 0 ? ValueF[0] : 0); + r.UpperLeftCorner.Y = (s32)(Count > 1 ? ValueF[1] : 0); + r.LowerRightCorner.X = (s32)(Count > 2 ? ValueF[2] : r.UpperLeftCorner.X); + r.LowerRightCorner.Y = (s32)(Count > 3 ? ValueF[3] : r.UpperLeftCorner.Y); + } + else + { + r.UpperLeftCorner.X = Count > 0 ? ValueI[0] : 0; + r.UpperLeftCorner.Y = Count > 1 ? ValueI[1] : 0; + r.LowerRightCorner.X = Count > 2 ? ValueI[2] : r.UpperLeftCorner.X; + r.LowerRightCorner.Y = Count > 3 ? ValueI[3] : r.UpperLeftCorner.Y; + } + return r; + } + + virtual core::matrix4 getMatrix() + { + core::matrix4 ret; + if (IsFloat) + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ret(r,c) = ValueF[c+r*4]; + } + else + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ret(r,c) = (f32)ValueI[c+r*4]; + } + return ret; + } + + virtual core::quaternion getQuaternion() + { + core::quaternion ret; + if (IsFloat) + { + ret.X = Count > 0 ? ValueF[0] : 0.0f; + ret.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.W = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.W = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + return ret; + } + + virtual core::triangle3df getTriangle() + { + core::triangle3df ret; + + if (IsFloat) + { + ret.pointA.X = Count > 0 ? ValueF[0] : 0.0f; + ret.pointA.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.pointA.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.pointB.X = Count > 3 ? ValueF[3] : 0.0f; + ret.pointB.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.pointB.Z = Count > 5 ? ValueF[5] : 0.0f; + ret.pointC.X = Count > 6 ? ValueF[6] : 0.0f; + ret.pointC.X = Count > 7 ? ValueF[7] : 0.0f; + ret.pointC.Z = Count > 8 ? ValueF[8] : 0.0f; + } + else + { + ret.pointA.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.pointA.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.pointA.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.pointB.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.pointB.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.pointB.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + ret.pointC.X = Count > 6 ? (f32)ValueI[6] : 0.0f; + ret.pointC.X = Count > 7 ? (f32)ValueI[7] : 0.0f; + ret.pointC.Z = Count > 8 ? (f32)ValueI[8] : 0.0f; + } + + return ret; + } + + virtual core::plane3df getPlane() + { + core::plane3df ret; + + if (IsFloat) + { + ret.Normal.X = Count > 0 ? ValueF[0] : 0.0f; + ret.Normal.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.Normal.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.D = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.Normal.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.Normal.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.Normal.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.D = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + + return ret; + } + + virtual core::aabbox3df getBBox() + { + core::aabbox3df ret; + if (IsFloat) + { + ret.MinEdge.X = Count > 0 ? ValueF[0] : 0.0f; + ret.MinEdge.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.MinEdge.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.MaxEdge.X = Count > 3 ? ValueF[3] : 0.0f; + ret.MaxEdge.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.MaxEdge.Z = Count > 5 ? ValueF[5] : 0.0f; + } + else + { + ret.MinEdge.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.MinEdge.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.MinEdge.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.MaxEdge.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.MaxEdge.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.MaxEdge.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + } + return ret; + + } + + virtual core::line2df getLine2d() + { + core::line2df ret; + if (IsFloat) + { + ret.start.X = Count > 0 ? ValueF[0] : 0.0f; + ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.end.X = Count > 2 ? ValueF[2] : 0.0f; + ret.end.Y = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.end.X = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.end.Y = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + return ret; + } + + virtual core::line3df getLine3d() + { + core::line3df ret; + if (IsFloat) + { + ret.start.X = Count > 0 ? ValueF[0] : 0.0f; + ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.start.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.end.X = Count > 3 ? ValueF[3] : 0.0f; + ret.end.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.end.Z = Count > 5 ? ValueF[5] : 0.0f; + } + else + { + ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.start.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.end.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.end.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.end.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + } + return ret; + } + + //! get float array + virtual core::array getFloatArray() + { + if (!IsFloat) + { + ValueF.clear(); + for (u32 i=0; i getIntArray() + { + if (IsFloat) + { + ValueI.clear(); + for (u32 i=0; i '9') ) ) + ++P; + + // set value + if ( *P) + { + if (IsFloat) + { + f32 c = 0; + P = core::fast_atof_move(P, c); + ValueF[i] = c; + } + else + { + // todo: fix this to read ints properly + f32 c = 0; + P = core::fast_atof_move(P, c); + ValueI[i] = (s32)c; + + } + } + } + // todo: warning message + //if (i < Count-1) + //{ + // + //} + } + + virtual void setPosition(core::position2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.X; + if (Count > 1) ValueF[1] = (f32)v.Y; + } + else + { + if (Count > 0) ValueI[0] = v.X; + if (Count > 1) ValueI[1] = v.Y; + } + } + + virtual void setVector(core::vector3df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.X; + if (Count > 1) ValueF[1] = v.Y; + if (Count > 2) ValueF[2] = v.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.X; + if (Count > 1) ValueI[1] = (s32)v.Y; + if (Count > 2) ValueI[2] = (s32)v.Z; + } + } + + virtual void setColor(video::SColorf color) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = color.r; + if (Count > 1) ValueF[1] = color.g; + if (Count > 2) ValueF[2] = color.b; + if (Count > 3) ValueF[3] = color.a; + } + else + { + if (Count > 0) ValueI[0] = (s32)(color.r * 255); + if (Count > 1) ValueI[1] = (s32)(color.g * 255); + if (Count > 2) ValueI[2] = (s32)(color.b * 255); + if (Count > 3) ValueI[3] = (s32)(color.a * 255); + } + + } + + virtual void setColor(video::SColor color) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)color.getRed() / 255.0f; + if (Count > 1) ValueF[1] = (f32)color.getGreen() / 255.0f; + if (Count > 2) ValueF[2] = (f32)color.getBlue() / 255.0f; + if (Count > 3) ValueF[3] = (f32)color.getAlpha() / 255.0f; + } + else + { + if (Count > 0) ValueI[0] = color.getRed(); + if (Count > 1) ValueI[1] = color.getGreen(); + if (Count > 2) ValueI[2] = color.getBlue(); + if (Count > 3) ValueI[3] = color.getAlpha(); + } + } + + virtual void setRect(core::rect value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)value.UpperLeftCorner.X; + if (Count > 1) ValueF[1] = (f32)value.UpperLeftCorner.Y; + if (Count > 2) ValueF[2] = (f32)value.LowerRightCorner.X; + if (Count > 3) ValueF[3] = (f32)value.LowerRightCorner.Y; + } + else + { + if (Count > 0) ValueI[0] = value.UpperLeftCorner.X; + if (Count > 1) ValueI[1] = value.UpperLeftCorner.Y; + if (Count > 2) ValueI[2] = value.LowerRightCorner.X; + if (Count > 3) ValueI[3] = value.LowerRightCorner.Y; + } + } + + virtual void setMatrix(core::matrix4 value) + { + reset(); + if (IsFloat) + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ValueF[c+r*4] = value(r,c); + } + else + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ValueI[c+r*4] = (s32)value(r,c); + } + } + + virtual void setQuaternion(core::quaternion value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.X; + if (Count > 1) ValueF[1] = value.Y; + if (Count > 2) ValueF[2] = value.Z; + if (Count > 3) ValueF[3] = value.W; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.X; + if (Count > 1) ValueI[1] = (s32)value.Y; + if (Count > 2) ValueI[2] = (s32)value.Z; + if (Count > 3) ValueI[3] = (s32)value.W; + } + } + + virtual void setBoundingBox(core::aabbox3d value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.MinEdge.X; + if (Count > 1) ValueF[1] = value.MinEdge.Y; + if (Count > 2) ValueF[2] = value.MinEdge.Z; + if (Count > 3) ValueF[3] = value.MaxEdge.X; + if (Count > 4) ValueF[4] = value.MaxEdge.Y; + if (Count > 5) ValueF[5] = value.MaxEdge.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.MinEdge.X; + if (Count > 1) ValueI[1] = (s32)value.MinEdge.Y; + if (Count > 2) ValueI[2] = (s32)value.MinEdge.Z; + if (Count > 3) ValueI[3] = (s32)value.MaxEdge.X; + if (Count > 4) ValueI[4] = (s32)value.MaxEdge.Y; + if (Count > 5) ValueI[5] = (s32)value.MaxEdge.Z; + } + } + + virtual void setPlane(core::plane3df value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.Normal.X; + if (Count > 1) ValueF[1] = value.Normal.Y; + if (Count > 2) ValueF[2] = value.Normal.Z; + if (Count > 3) ValueF[3] = value.D; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.Normal.X; + if (Count > 1) ValueI[1] = (s32)value.Normal.Y; + if (Count > 2) ValueI[2] = (s32)value.Normal.Z; + if (Count > 3) ValueI[3] = (s32)value.D; + } + } + + virtual void setTriangle3d(core::triangle3df value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.pointA.X; + if (Count > 1) ValueF[1] = value.pointA.Y; + if (Count > 2) ValueF[2] = value.pointA.Z; + if (Count > 3) ValueF[3] = value.pointB.X; + if (Count > 4) ValueF[4] = value.pointB.Y; + if (Count > 5) ValueF[5] = value.pointB.Z; + if (Count > 6) ValueF[6] = value.pointC.X; + if (Count > 7) ValueF[7] = value.pointC.Y; + if (Count > 8) ValueF[8] = value.pointC.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.pointA.X; + if (Count > 1) ValueI[1] = (s32)value.pointA.Y; + if (Count > 2) ValueI[2] = (s32)value.pointA.Z; + if (Count > 3) ValueI[3] = (s32)value.pointB.X; + if (Count > 4) ValueI[4] = (s32)value.pointB.Y; + if (Count > 5) ValueI[5] = (s32)value.pointB.Z; + if (Count > 6) ValueI[6] = (s32)value.pointC.X; + if (Count > 7) ValueI[7] = (s32)value.pointC.Y; + if (Count > 8) ValueI[8] = (s32)value.pointC.Z; + } + } + + virtual void setVector2d(core::vector2df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.X; + if (Count > 1) ValueF[1] = v.Y; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.X; + if (Count > 1) ValueI[1] = (s32)v.Y; + } + } + + virtual void setVector2d(core::vector2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.X; + if (Count > 1) ValueF[1] = (f32)v.Y; + } + else + { + if (Count > 0) ValueI[0] = v.X; + if (Count > 1) ValueI[1] = v.Y; + } + } + + virtual void setLine2d(core::line2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.start.X; + if (Count > 1) ValueF[1] = (f32)v.start.Y; + if (Count > 2) ValueF[2] = (f32)v.end.X; + if (Count > 3) ValueF[3] = (f32)v.end.Y; + } + else + { + if (Count > 0) ValueI[0] = v.start.X; + if (Count > 1) ValueI[1] = v.start.Y; + if (Count > 2) ValueI[2] = v.end.X; + if (Count > 3) ValueI[3] = v.end.Y; + } + } + + virtual void setLine2d(core::line2df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.start.X; + if (Count > 1) ValueF[1] = v.start.Y; + if (Count > 2) ValueF[2] = v.end.X; + if (Count > 3) ValueF[3] = v.end.Y; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.start.X; + if (Count > 1) ValueI[1] = (s32)v.start.Y; + if (Count > 2) ValueI[2] = (s32)v.end.X; + if (Count > 3) ValueI[3] = (s32)v.end.Y; + } + } + + virtual void setDimension2d(core::dimension2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.Width; + if (Count > 1) ValueF[1] = (f32)v.Height; + } + else + { + if (Count > 0) ValueI[0] = v.Width; + if (Count > 1) ValueI[1] = v.Height; + } + } + + //! set float array + virtual void setFloatArray(core::array &vals) + { + reset(); + + for (u32 i=0; i &vals) + { + reset(); + + for (u32 i=0; i ValueI; + core::array ValueF; + u32 Count; + bool IsFloat; +}; + + +// Attribute implemented for floating point colors +class CColorfAttribute : public CNumbersAttribute +{ +public: + + CColorfAttribute(const char* name, video::SColorf value) : CNumbersAttribute(name, value) {} + + virtual s32 getInt() + { + return getColor().color; + } + + virtual f32 getFloat() + { + return (f32)getColor().color; + } + + virtual void setInt(s32 intValue) + { + video::SColorf c = video::SColor(intValue); + ValueF[0] = c.r; + ValueF[1] = c.g; + ValueF[2] = c.b; + ValueF[3] = c.a; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_COLORF; + } + + + virtual const wchar_t* getTypeString() const + { + return L"colorf"; + } +}; + + + +// Attribute implemented for colors +class CColorAttribute : public CNumbersAttribute +{ +public: + + CColorAttribute(const char* name, video::SColorf value) : CNumbersAttribute(name, value) {} + + virtual s32 getInt() + { + return getColor().color; + } + + virtual f32 getFloat() + { + return (f32)getColor().color; + } + + virtual void setInt(s32 intValue) + { + video::SColorf c = video::SColor(intValue); + ValueF[0] = c.r; + ValueF[1] = c.g; + ValueF[2] = c.b; + ValueF[3] = c.a; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + } + + virtual core::stringw getStringW() + { + char tmp[10]; + video::SColor c = getColor(); + sprintf(tmp, "%08x", c.color); + return core::stringw(tmp); + } + + virtual void setString(const char* text) + { + video::SColor c; + sscanf(text, "%08x", &c.color); + setColor(c); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_COLOR; + } + + + virtual const wchar_t* getTypeString() const + { + return L"color"; + } + +}; + + +// Attribute implemented for 3d vectors +class CVector3DAttribute : public CNumbersAttribute +{ +public: + + CVector3DAttribute(const char* name, core::vector3df value) : CNumbersAttribute(name, value) {} + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_VECTOR3D; + } + + virtual core::matrix4 getMatrix() + { + core::matrix4 ret; + ret.makeIdentity(); + ret.setTranslation( core::vector3df(ValueF[0],ValueF[1],ValueF[2]) ); + return ret; + } + + virtual const wchar_t* getTypeString() const + { + return L"vector3d"; + } +}; + +// Attribute implemented for 2d vectors +class CPosition2DAttribute : public CNumbersAttribute +{ +public: + + CPosition2DAttribute(const char* name, core::position2di value) : CNumbersAttribute(name, value) {} + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_POSITION2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"position"; + } +}; + + + +// Attribute implemented for rectangles +class CRectAttribute : public CNumbersAttribute +{ +public: + + CRectAttribute(const char* name, core::rect value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_RECT; + } + + virtual const wchar_t* getTypeString() const + { + return L"rect"; + } +}; + +// Attribute implemented for matrices +class CMatrixAttribute : public CNumbersAttribute +{ +public: + + CMatrixAttribute(const char* name, core::matrix4 value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_MATRIX; + } + + virtual core::quaternion getQuaternion() + { + return core::quaternion(getMatrix()); + } + + virtual const wchar_t* getTypeString() const + { + return L"matrix"; + } +}; + +// Attribute implemented for quaternions +class CQuaternionAttribute : public CNumbersAttribute +{ +public: + + CQuaternionAttribute(const char* name, core::quaternion value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_QUATERNION; + } + + virtual core::matrix4 getMatrix() + { + return getQuaternion().getMatrix(); + } + + virtual const wchar_t* getTypeString() const + { + return L"quaternion"; + } +}; + + +// Attribute implemented for bounding boxes +class CBBoxAttribute : public CNumbersAttribute +{ +public: + + CBBoxAttribute(const char* name, core::aabbox3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BBOX; + } + + virtual const wchar_t* getTypeString() const + { + return L"box3d"; + } +}; + +// Attribute implemented for planes +class CPlaneAttribute : public CNumbersAttribute +{ +public: + + CPlaneAttribute(const char* name, core::plane3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_PLANE; + } + + virtual const wchar_t* getTypeString() const + { + return L"plane"; + } +}; + +// Attribute implemented for triangles +class CTriangleAttribute : public CNumbersAttribute +{ +public: + + CTriangleAttribute(const char* name, core::triangle3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_TRIANGLE3D; + } + + virtual core::plane3df getPlane() + { + return getTriangle().getPlane(); + } + + virtual const wchar_t* getTypeString() const + { + return L"triangle"; + } +}; + + +// Attribute implemented for 2d lines +class CLine2dAttribute : public CNumbersAttribute +{ +public: + + CLine2dAttribute(const char* name, core::line2df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_LINE2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"line2d"; + } +}; + +// Attribute implemented for 3d lines +class CLine3dAttribute : public CNumbersAttribute +{ +public: + + CLine3dAttribute(const char* name, core::line3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_LINE3D; + } + + virtual const wchar_t* getTypeString() const + { + return L"line3d"; + } +}; + + +// vector2df +// dimension2di + +/* + Special attributes +*/ + +// Attribute implemented for enumeration literals +class CEnumAttribute : public IAttribute +{ +public: + + CEnumAttribute(const char* name, const char* value, const char* const* literals) + { + Name = name; + setEnum(value, literals); + } + + virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) + { + int literalCount = 0; + + if (enumerationLiterals) + { + s32 i; + for (i=0; enumerationLiterals[i]; ++i) + ++literalCount; + + EnumLiterals.reallocate(literalCount); + for (i=0; enumerationLiterals[i]; ++i) + EnumLiterals.push_back(enumerationLiterals[i]); + } + + setString(enumValue); + } + + virtual s32 getInt() + { + for (s32 i=0; EnumLiterals.size(); ++i) + if (Value.equals_ignore_case(EnumLiterals[i])) + { + return i; + } + + return -1; + } + + virtual f32 getFloat() + { + return (f32)getInt(); + } + + virtual bool getBool() + { + return (getInt() != 0); // does not make a lot of sense, I know + } + + virtual core::stringc getString() + { + return Value; + } + + virtual core::stringw getStringW() + { + return core::stringw(Value.c_str()); + } + + virtual void setInt(s32 intValue) + { + if (intValue>=0 && intValue<(s32)EnumLiterals.size()) + Value = EnumLiterals[intValue]; + else + Value = ""; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + }; + + virtual void setString(const char* text) + { + Value = text; + } + + virtual const char* getEnum() + { + return Value.c_str(); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_ENUM; + } + + + virtual const wchar_t* getTypeString() const + { + return L"enum"; + } + + core::stringc Value; + core::array EnumLiterals; +}; + + + + + +// Attribute implemented for strings +class CStringAttribute : public IAttribute +{ +public: + + CStringAttribute(const char* name, const char* value) + { + IsStringW=false; + Name = name; + setString(value); + } + + CStringAttribute(const char* name, const wchar_t* value) + { + IsStringW = true; + Name = name; + setString(value); + } + + CStringAttribute(const char* name, void* binaryData, s32 lenghtInBytes) + { + IsStringW=false; + Name = name; + setBinary(binaryData, lenghtInBytes); + } + + virtual s32 getInt() + { + if (IsStringW) + return atoi(core::stringc(ValueW.c_str()).c_str()); + else + return atoi(Value.c_str()); + } + + virtual f32 getFloat() + { + if (IsStringW) + return core::fast_atof(core::stringc(ValueW.c_str()).c_str()); + else + return core::fast_atof(Value.c_str()); + } + + virtual bool getBool() + { + if (IsStringW) + return Value.equals_ignore_case(L"true"); + else + return Value.equals_ignore_case("true"); + } + + virtual core::stringc getString() + { + if (IsStringW) + return core::stringc(ValueW.c_str()); + else + return Value; + } + virtual core::stringw getStringW() + { + if (IsStringW) + return ValueW; + else + return core::stringw(Value.c_str()); + } + + virtual void setInt(s32 intValue) + { + if (IsStringW) + ValueW = core::stringw(intValue); + else + Value = core::stringc(intValue); + } + + virtual void setFloat(f32 floatValue) + { + if (IsStringW) + { + ValueW = core::stringw(floatValue); + } + else + { + Value = core::stringc(floatValue); + } + }; + + virtual void setString(const char* text) + { + if (IsStringW) + ValueW = core::stringw(text); + else + Value = text; + } + + virtual void setString(const wchar_t* text) + { + if (IsStringW) + ValueW = text; + else + Value = core::stringc(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_STRING; + } + + + virtual const wchar_t* getTypeString() const + { + return L"string"; + } + + virtual void getBinary(void* outdata, s32 maxLenght) + { + s32 dataSize = maxLenght; + c8* datac8 = (c8*)(outdata); + s32 p = 0; + const c8* dataString = Value.c_str(); + + for (s32 i=0; i= '0' && h <='9') + return h-'0'; + + if (h >= 'a' && h <='f') + return h-'a' + 10; + + return 0; + } + + static inline void getHexStrFromByte(c8 byte, c8* out) + { + s32 b = (byte & 0xf0) >> 4; + + for (s32 i=0; i<2; ++i) + { + if (b >=0 && b <= 9) + out[i] = b+'0'; + if (b >=10 && b <= 15) + out[i] = (b-10)+'a'; + + b = byte & 0x0f; + } + } +}; + +// Attribute implemented for binary data +class CBinaryAttribute : public CStringAttribute +{ +public: + + CBinaryAttribute(const char* name, void* binaryData, s32 lenghtInBytes) + : CStringAttribute(name, binaryData, lenghtInBytes) + { + + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BINARY; + } + + + virtual const wchar_t* getTypeString() const + { + return L"binary"; + } +}; + + + +// Attribute implemented for texture references +class CTextureAttribute : public IAttribute +{ +public: + + CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver) + : Value(0), Driver(driver) + { + if (Driver) + Driver->grab(); + + Name = name; + setTexture(value); + } + + ~CTextureAttribute() + { + if (Driver) + Driver->drop(); + + if (Value) + Value->drop(); + } + + virtual video::ITexture* getTexture() + { + return Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + return core::stringw(Value ? Value->getName().c_str() : 0); + } + + virtual core::stringc getString() + { + return Value ? Value->getName() : core::stringc(); + } + + virtual void getString(char* target) + { + if (Value) + strcpy(target, Value->getName().c_str()); + else + target[0] = 0x0; + } + + virtual void setString(const char* text) + { + if (Driver) + { + if (text && *text) + setTexture(Driver->getTexture(text)); + else + setTexture(0); + } + } + + virtual void setTexture(video::ITexture* value) + { + if (Value) + Value->drop(); + + Value = value; + + if (Value) + Value->grab(); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_TEXTURE; + } + + + virtual const wchar_t* getTypeString() const + { + return L"texture"; + } + + video::ITexture* Value; + video::IVideoDriver* Driver; +}; + + + +// Attribute implemented for array of stringw +class CStringWArrayAttribute : public IAttribute +{ +public: + + CStringWArrayAttribute(const char* name, core::array value) + { + Name = name; + setArray(value); + } + + virtual core::array getArray() + { + return Value; + } + + virtual void setArray(core::array value) + { + Value = value; + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_STRINGWARRAY; + } + + virtual const wchar_t* getTypeString() const + { + return L"stringwarray"; + } + + core::array Value; +}; + + +// Attribute implemented for user pointers +class CUserPointerAttribute : public IAttribute +{ +public: + + CUserPointerAttribute(const char* name, void* value) + { + Name = name; + Value = value; + } + + virtual s32 getInt() + { + return *(s32*)(&Value); + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual void getString(char* target) + { + sprintf(target, "0x%x", *(int*)(&Value)); + } + + virtual void setString(const char* text) + { + sscanf(text, "0x%x", (unsigned int*)(&Value)); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_USER_POINTER; + } + + virtual void setUserPointer(void* v) + { + Value = v; + } + + virtual void* getUserPointer() + { + return Value; + } + + + virtual const wchar_t* getTypeString() const + { + return L"userPointer"; + } + + void* Value; +}; + + +// todo: CGUIFontAttribute + +} // end namespace io +} // end namespace irr diff --git a/src/dep/src/irrlicht/CAttributes.cpp b/src/dep/src/irrlicht/CAttributes.cpp new file mode 100644 index 0000000..9718ea7 --- /dev/null +++ b/src/dep/src/irrlicht/CAttributes.cpp @@ -0,0 +1,1553 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAttributes.h" +#include "CAttributeImpl.h" +#include "ITexture.h" +#include "IXMLWriter.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + +CAttributes::CAttributes(video::IVideoDriver* driver) +: Driver(driver) +{ + #ifdef _DEBUG + setDebugName("CAttributes"); + #endif + + if (Driver) + Driver->grab(); +} + +CAttributes::~CAttributes() +{ + clear(); + + if (Driver) + Driver->drop(); +} + + +//! Removes all attributes +void CAttributes::clear() +{ + for (u32 i=0; idrop(); + + Attributes.clear(); +} + + +//! Sets a string attribute. +//! \param attributeName: Name for the attribute +//! \param value: Value for the attribute. Set this to 0 to delete the attribute +void CAttributes::setAttribute(const c8* attributeName, const c8* value) +{ + for (u32 i=0; iName == attributeName) + { + if (!value) + { + Attributes[i]->drop(); + Attributes.erase(i); + } + else + Attributes[i]->setString(value); + + return; + } + + if (value) + { + Attributes.push_back(new CStringAttribute(attributeName, value)); + } +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setStringAttribute() +//! or 0 if attribute is not set. +core::stringc CAttributes::getAttributeAsString(const c8* attributeName) +{ + core::stringc str; + + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getString(); + else + return str; +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \param target: Buffer where the string is copied to. +void CAttributes::getAttributeAsString(const c8* attributeName, char* target) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + { + core::stringc str = att->getString(); + strcpy(target,str.c_str()); + } + else + target[0] = 0; +} + +//! Returns string attribute value by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::stringc CAttributes::getAttributeAsString(s32 index) +{ + core::stringc str; + + if ((u32)index < Attributes.size()) + return Attributes[index]->getString(); + + return str; +} + + +//! Sets a string attribute. +//! \param attributeName: Name for the attribute +//! \param value: Value for the attribute. Set this to 0 to delete the attribute +void CAttributes::setAttribute(const c8* attributeName, const wchar_t* value) +{ + for (u32 i=0; iName == attributeName) + { + if (!value) + { + Attributes[i]->drop(); + Attributes.erase(i); + } + else + Attributes[i]->setString(value); + + return; + } + } + + if (value) + { + Attributes.push_back(new CStringAttribute(attributeName, value)); + } +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setStringAttribute() +//! or 0 if attribute is not set. +core::stringw CAttributes::getAttributeAsStringW(const c8* attributeName) +{ + core::stringw str; + + IAttribute* att = getAttributeP(attributeName); + if (att) + str = att->getStringW(); + + return str; +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \param target: Buffer where the string is copied to. +void CAttributes::getAttributeAsStringW(const c8* attributeName, wchar_t* target) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + { + core::stringw str = att->getStringW(); + wcscpy(target,str.c_str()); + } + else + target[0] = 0; +} + +//! Returns string attribute value by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::stringw CAttributes::getAttributeAsStringW(s32 index) +{ + + if ((u32)index < Attributes.size()) + return Attributes[index]->getStringW(); + else + return core::stringw(); +} + + +//! Adds an attribute as an array of wide strings +void CAttributes::addArray(const c8* attributeName, core::array value) +{ + Attributes.push_back(new CStringWArrayAttribute(attributeName, value)); +} + +//! Sets an attribute value as an array of wide strings. +void CAttributes::setAttribute(const c8* attributeName, const core::array value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setArray(value); + else + { + Attributes.push_back(new CStringWArrayAttribute(attributeName, value)); + } +} + +//! Gets an attribute as an array of wide strings. +core::array CAttributes::getAttributeAsArray(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getArray(); + else + return core::array(); +} + +//! Returns attribute value as an array of wide strings by index. +core::array CAttributes::getAttributeAsArray(s32 index) +{ + core::array ret; + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getArray(); + + return ret; +} + +//! Sets an attribute as an array of wide strings +void CAttributes::setAttribute(s32 index, core::array value) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setArray(value); +} + + + + +//! Returns attribute index from name, -1 if not found +s32 CAttributes::findAttribute(const c8* attributeName) +{ + for (u32 i=0; iName == attributeName) + return i; + + return -1; +} + + +IAttribute* CAttributes::getAttributeP(const c8* attributeName) +{ + for (u32 i=0; iName == attributeName) + return Attributes[i]; + + return 0; +} + + +//! Sets a attribute as boolean value +void CAttributes::setAttribute(const c8* attributeName, bool value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBool(value); + else + { + Attributes.push_back(new CBoolAttribute(attributeName, value)); + } +} + +//! Gets a attribute as boolean value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as bool +//! or 0 if attribute is not set. +bool CAttributes::getAttributeAsBool(const c8* attributeName) +{ + bool ret = false; + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getBool(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +//! Sets a attribute as integer value +void CAttributes::setAttribute(const c8* attributeName, s32 value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setInt(value); + else + { + Attributes.push_back(new CIntAttribute(attributeName, value)); + } +} + +//! Gets a attribute as integer value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as integer +//! or 0 if attribute is not set. +s32 CAttributes::getAttributeAsInt(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getInt(); + else + return 0; +} + +//! Sets a attribute as float value +void CAttributes::setAttribute(const c8* attributeName, f32 value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setFloat(value); + else + Attributes.push_back(new CFloatAttribute(attributeName, value)); +} + +//! Gets a attribute as integer value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as float value +//! or 0 if attribute is not set. +f32 CAttributes::getAttributeAsFloat(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getFloat(); + + return 0.f; +} + +//! Sets a attribute as color +void CAttributes::setAttribute(const c8* attributeName, video::SColor value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setColor(value); + else + Attributes.push_back(new CColorAttribute(attributeName, value)); +} + +//! Gets an attribute as color +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +video::SColor CAttributes::getAttributeAsColor(const c8* attributeName) +{ + video::SColor ret(0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getColor(); + + return ret; +} + +//! Sets a attribute as floating point color +void CAttributes::setAttribute(const c8* attributeName, video::SColorf value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setColor(value); + else + Attributes.push_back(new CColorfAttribute(attributeName, value)); +} + +//! Gets an attribute as floating point color +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +video::SColorf CAttributes::getAttributeAsColorf(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getColorf(); + else + return video::SColorf(); +} + +//! Sets a attribute as 2d position +void CAttributes::setAttribute(const c8* attributeName, core::position2di value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setPosition(value); + else + Attributes.push_back(new CPosition2DAttribute(attributeName, value)); +} + +//! Gets an attribute as 2d position +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::position2di CAttributes::getAttributeAsPosition2d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getPosition(); + else + return core::position2di(); +} + +//! Sets a attribute as rectangle +void CAttributes::setAttribute(const c8* attributeName, core::rect value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setRect(value); + else + Attributes.push_back(new CRectAttribute(attributeName, value)); +} + +//! Gets an attribute as rectangle +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::rect CAttributes::getAttributeAsRect(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getRect(); + else + return core::rect(); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(const c8* attributeName, core::vector3df value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setVector(value); + else + Attributes.push_back(new CVector3DAttribute(attributeName, value)); +} + +//! Gets an attribute as vector +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::vector3df CAttributes::getAttributeAsVector3d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getVector(); + else + return core::vector3df(); +} + +//! Sets an attribute as binary data +void CAttributes::setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes ) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBinary(data, dataSizeInBytes); + else + Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes)); +} + +//! Gets an attribute as binary data +//! \param attributeName: Name of the attribute to get. +void CAttributes::getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->getBinary(outData, maxSizeInBytes); +} + +//! Sets an attribute as enumeration +void CAttributes::setAttribute(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setEnum(enumValue, enumerationLiterals); + else + Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals)); +} + +//! Gets an attribute as enumeration +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +const char* CAttributes::getAttributeAsEnumeration(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getEnum(); + else + return 0; +} + +//! Gets an attribute as enumeration +s32 CAttributes::getAttributeAsEnumeration(const c8* attributeName, const char* const* enumerationLiteralsToUse) +{ + IAttribute* att = getAttributeP(attributeName); + + if (enumerationLiteralsToUse && att) + { + const char* value = att->getEnum(); + if (value) + { + for (s32 i=0; enumerationLiteralsToUse[i]; ++i) + if (!strcmp(value, enumerationLiteralsToUse[i])) + return i; + } + } + + return -1; +} + +//! Gets the list of enumeration literals of an enumeration attribute +//! \param attributeName: Name of the attribute to get. +void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array& outLiterals) +{ + IAttribute* att = getAttributeP(attributeName); + + if (att && att->getType() == EAT_ENUM) + outLiterals = ((CEnumAttribute*)att)->EnumLiterals; +} + +//! Sets an attribute as texture reference +void CAttributes::setAttribute(const c8* attributeName, video::ITexture* value ) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setTexture(value); + else + Attributes.push_back(new CTextureAttribute(attributeName, value, Driver)); +} + + +//! Gets an attribute as texture reference +//! \param attributeName: Name of the attribute to get. +video::ITexture* CAttributes::getAttributeAsTexture(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getTexture(); + else + return 0; +} + +//! Gets an attribute as texture reference +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::ITexture* CAttributes::getAttributeAsTexture(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getTexture(); + else + return 0; +} + + +//! Returns amount of string attributes set in this scene manager. +u32 CAttributes::getAttributeCount() const +{ + return Attributes.size(); +} + +//! Returns string attribute name by index. +//! \param index: Index value, must be between 0 and getStringAttributeCount()-1. +const c8* CAttributes::getAttributeName(s32 index) +{ + if ((u32)index >= Attributes.size()) + return 0; + + return Attributes[index]->Name.c_str(); +} + +//! Returns the type of an attribute +E_ATTRIBUTE_TYPE CAttributes::getAttributeType(const c8* attributeName) +{ + E_ATTRIBUTE_TYPE ret = EAT_UNKNOWN; + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getType(); + + return ret; +} + +//! Returns attribute type by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +E_ATTRIBUTE_TYPE CAttributes::getAttributeType(s32 index) +{ + if ((u32)index >= Attributes.size()) + return EAT_UNKNOWN; + + return Attributes[index]->getType(); +} + +//! Returns the type of an attribute +const wchar_t* CAttributes::getAttributeTypeString(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getTypeString(); + else + return L"unknown"; +} + +//! Returns attribute type string by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +const wchar_t* CAttributes::getAttributeTypeString(s32 index) +{ + if ((u32)index >= Attributes.size()) + return L"unknown"; + + return Attributes[index]->getTypeString(); +} + +//! Gets an attribute as boolean value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +bool CAttributes::getAttributeAsBool(s32 index) +{ + bool ret = false; + + if ((u32)index < Attributes.size()) + ret = Attributes[index]->getBool(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +//! Gets an attribute as integer value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +s32 CAttributes::getAttributeAsInt(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getInt(); + else + return 0; +} + +//! Gets an attribute as float value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +f32 CAttributes::getAttributeAsFloat(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getFloat(); + else + return 0.f; +} + +//! Gets an attribute as color +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::SColor CAttributes::getAttributeAsColor(s32 index) +{ + video::SColor ret(0); + + if ((u32)index < Attributes.size()) + ret = Attributes[index]->getColor(); + + return ret; +} + +//! Gets an attribute as floating point color +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::SColorf CAttributes::getAttributeAsColorf(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getColorf(); + + return video::SColorf(); +} + +//! Gets an attribute as 3d vector +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::vector3df CAttributes::getAttributeAsVector3d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getVector(); + else + return core::vector3df(); +} + +//! Gets an attribute as rectangle +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::position2di CAttributes::getAttributeAsPosition2d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getPosition(); + else + return core::position2di(); +} + +//! Gets an attribute as rectangle +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::rect CAttributes::getAttributeAsRect(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getRect(); + else + return core::rect(); +} + + +//! Gets an attribute as binary data +///! \param index: Index value, must be between 0 and getAttributeCount()-1. +void CAttributes::getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->getBinary(outData, maxSizeInBytes); +} + + +//! Gets an attribute as enumeration +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +const char* CAttributes::getAttributeAsEnumeration(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getEnum(); + else + return 0; +} + + +//! Gets an attribute as enumeration +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +s32 CAttributes::getAttributeAsEnumeration(s32 index, const char* const* enumerationLiteralsToUse) +{ + if ((u32)index < Attributes.size()) + { + IAttribute* att = Attributes[index]; + + if (enumerationLiteralsToUse && att) + { + const char* value = att->getEnum(); + if (value) + { + for (s32 i=0; enumerationLiteralsToUse[i]; ++i) + if (!strcmp(value, enumerationLiteralsToUse[i])) + return i; + } + } + } + + return -1; +} + +//! Gets the list of enumeration literals of an enumeration attribute +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array& outLiterals) +{ + if ((u32)index < Attributes.size() && + Attributes[index]->getType() == EAT_ENUM) + outLiterals = ((CEnumAttribute*)Attributes[index])->EnumLiterals; +} + + +//! Adds an attribute as integer +void CAttributes::addInt(const c8* attributeName, s32 value) +{ + Attributes.push_back(new CIntAttribute(attributeName, value)); +} + +//! Adds an attribute as float +void CAttributes::addFloat(const c8* attributeName, f32 value) +{ + Attributes.push_back(new CFloatAttribute(attributeName, value)); +} + +//! Adds an attribute as string +void CAttributes::addString(const c8* attributeName, const char* value) +{ + Attributes.push_back(new CStringAttribute(attributeName, value)); +} + +//! Adds an attribute as wchar string +void CAttributes::addString(const c8* attributeName, const wchar_t* value) +{ + Attributes.push_back(new CStringAttribute(attributeName, value)); +} + +//! Adds an attribute as bool +void CAttributes::addBool(const c8* attributeName, bool value) +{ + Attributes.push_back(new CBoolAttribute(attributeName, value)); +} + +//! Adds an attribute as enum +void CAttributes::addEnum(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals) +{ + Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals)); +} + +//! Adds an attribute as enum +void CAttributes::addEnum(const c8* attributeName, s32 enumValue, const char* const* enumerationLiterals) +{ + addEnum(attributeName, "", enumerationLiterals); + Attributes.getLast()->setInt(enumValue); +} + +//! Adds an attribute as color +void CAttributes::addColor(const c8* attributeName, video::SColor value) +{ + Attributes.push_back(new CColorAttribute(attributeName, value)); +} + +//! Adds an attribute as floating point color +void CAttributes::addColorf(const c8* attributeName, video::SColorf value) +{ + Attributes.push_back(new CColorfAttribute(attributeName, value)); +} + +//! Adds an attribute as 3d vector +void CAttributes::addVector3d(const c8* attributeName, core::vector3df value) +{ + Attributes.push_back(new CVector3DAttribute(attributeName, value)); +} + +//! Adds an attribute as 2d position +void CAttributes::addPosition2d(const c8* attributeName, core::position2di value) +{ + Attributes.push_back(new CPosition2DAttribute(attributeName, value)); +} + +//! Adds an attribute as rectangle +void CAttributes::addRect(const c8* attributeName, core::rect value) +{ + Attributes.push_back(new CRectAttribute(attributeName, value)); +} + +//! Adds an attribute as binary data +void CAttributes::addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes) +{ + Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes)); +} + +//! Adds an attribute as texture reference +void CAttributes::addTexture(const c8* attributeName, video::ITexture* texture) +{ + Attributes.push_back(new CTextureAttribute(attributeName, texture, Driver)); +} + +//! Returns if an attribute with a name exists +bool CAttributes::existsAttribute(const c8* attributeName) +{ + return getAttributeP(attributeName) != 0; +} + +//! Sets an attribute value as string. +//! \param attributeName: Name for the attribute +void CAttributes::setAttribute(s32 index, const c8* value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setString(value); +} + +//! Sets an attribute value as string. +//! \param attributeName: Name for the attribute +void CAttributes::setAttribute(s32 index, const wchar_t* value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setString(value); +} + +//! Sets an attribute as boolean value +void CAttributes::setAttribute(s32 index, bool value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setBool(value); +} + +//! Sets an attribute as integer value +void CAttributes::setAttribute(s32 index, s32 value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setInt(value); +} + +//! Sets a attribute as float value +void CAttributes::setAttribute(s32 index, f32 value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setFloat(value); +} + +//! Sets a attribute as color +void CAttributes::setAttribute(s32 index, video::SColor color) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setColor(color); +} + +//! Sets a attribute as floating point color +void CAttributes::setAttribute(s32 index, video::SColorf color) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setColor(color); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(s32 index, core::vector3df v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setVector(v); +} + +//! Sets a attribute as position +void CAttributes::setAttribute(s32 index, core::position2di v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setPosition(v); +} + +//! Sets a attribute as rectangle +void CAttributes::setAttribute(s32 index, core::rect v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setRect(v); +} + +//! Sets an attribute as binary data +void CAttributes::setAttribute(s32 index, void* data, s32 dataSizeInBytes ) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setBinary(data, dataSizeInBytes); +} + + +//! Sets an attribute as enumeration +void CAttributes::setAttribute(s32 index, const char* enumValue, const char* const* enumerationLiterals) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setEnum(enumValue, enumerationLiterals); +} + + +//! Sets an attribute as texture reference +void CAttributes::setAttribute(s32 index, video::ITexture* texture) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setTexture(texture); +} + + +//! Adds an attribute as matrix +void CAttributes::addMatrix(const c8* attributeName, const core::matrix4& v) +{ + Attributes.push_back(new CMatrixAttribute(attributeName, v)); +} + + +//! Sets an attribute as matrix +void CAttributes::setAttribute(const c8* attributeName, const core::matrix4& v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setMatrix(v); + else + Attributes.push_back(new CMatrixAttribute(attributeName, v)); +} + +//! Gets an attribute as a matrix4 +core::matrix4 CAttributes::getAttributeAsMatrix(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getMatrix(); + else + return core::matrix4(); + +} + +//! Gets an attribute as matrix +core::matrix4 CAttributes::getAttributeAsMatrix(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getMatrix(); + else + return core::matrix4(); +} + +//! Sets an attribute as matrix +void CAttributes::setAttribute(s32 index, const core::matrix4& v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setMatrix(v); +} + + +//! Adds an attribute as quaternion +void CAttributes::addQuaternion(const c8* attributeName, core::quaternion v) +{ + Attributes.push_back(new CQuaternionAttribute(attributeName, v)); +} + + +//! Sets an attribute as quaternion +void CAttributes::setAttribute(const c8* attributeName, core::quaternion v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setQuaternion(v); + else + { + Attributes.push_back(new CQuaternionAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a quaternion +core::quaternion CAttributes::getAttributeAsQuaternion(const c8* attributeName) +{ + core::quaternion ret(0,1,0, 0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getQuaternion(); + + return ret; +} + +//! Gets an attribute as quaternion +core::quaternion CAttributes::getAttributeAsQuaternion(s32 index) +{ + core::quaternion ret(0,1,0, 0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getQuaternion(); + + return ret; +} + +//! Sets an attribute as quaternion +void CAttributes::setAttribute(s32 index, core::quaternion v) +{ +if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setQuaternion(v); +} + +//! Adds an attribute as axis aligned bounding box +void CAttributes::addBox3d(const c8* attributeName, core::aabbox3df v) +{ + Attributes.push_back(new CBBoxAttribute(attributeName, v)); +} + +//! Sets an attribute as axis aligned bounding box +void CAttributes::setAttribute(const c8* attributeName, core::aabbox3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBBox(v); + else + { + Attributes.push_back(new CBBoxAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a axis aligned bounding box +core::aabbox3df CAttributes::getAttributeAsBox3d(const c8* attributeName) +{ + core::aabbox3df ret(0,0,0, 0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getBBox(); + + return ret; +} + +//! Gets an attribute as axis aligned bounding box +core::aabbox3df CAttributes::getAttributeAsBox3d(s32 index) +{ + core::aabbox3df ret(0,0,0, 0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getBBox(); + + return ret; +} + +//! Sets an attribute as axis aligned bounding box +void CAttributes::setAttribute(s32 index, core::aabbox3df v) +{ +if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setBBox(v); +} + +//! Adds an attribute as 3d plane +void CAttributes::addPlane3d(const c8* attributeName, core::plane3df v) +{ + Attributes.push_back(new CPlaneAttribute(attributeName, v)); +} + +//! Sets an attribute as 3d plane +void CAttributes::setAttribute(const c8* attributeName, core::plane3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setPlane(v); + else + { + Attributes.push_back(new CPlaneAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d plane +core::plane3df CAttributes::getAttributeAsPlane3d(const c8* attributeName) +{ + core::plane3df ret(0,0,0, 0,1,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getPlane(); + + return ret; +} + +//! Gets an attribute as 3d plane +core::plane3df CAttributes::getAttributeAsPlane3d(s32 index) +{ + core::plane3df ret(0,0,0, 0,1,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getPlane(); + + return ret; +} + +//! Sets an attribute as 3d plane +void CAttributes::setAttribute(s32 index, core::plane3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setPlane(v); +} + +//! Adds an attribute as 3d triangle +void CAttributes::addTriangle3d(const c8* attributeName, core::triangle3df v) +{ + Attributes.push_back(new CTriangleAttribute(attributeName, v)); +} + +//! Sets an attribute as 3d triangle +void CAttributes::setAttribute(const c8* attributeName, core::triangle3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setTriangle(v); + else + { + Attributes.push_back(new CTriangleAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d triangle +core::triangle3df CAttributes::getAttributeAsTriangle3d(const c8* attributeName) +{ + core::triangle3df ret; + ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getTriangle(); + + return ret; +} + +//! Gets an attribute as 3d triangle +core::triangle3df CAttributes::getAttributeAsTriangle3d(s32 index) +{ + core::triangle3df ret; + ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getTriangle(); + + return ret; +} + +//! Sets an attribute as 3d triangle +void CAttributes::setAttribute(s32 index, core::triangle3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setTriangle(v); +} + +//! Adds an attribute as a 2d line +void CAttributes::addLine2d(const c8* attributeName, core::line2df v) +{ + Attributes.push_back(new CLine2dAttribute(attributeName, v)); +} + +//! Sets an attribute as a 2d line +void CAttributes::setAttribute(const c8* attributeName, core::line2df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setLine2d(v); + else + { + Attributes.push_back(new CLine2dAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 2d line +core::line2df CAttributes::getAttributeAsLine2d(const c8* attributeName) +{ + core::line2df ret(0,0, 0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getLine2d(); + + return ret; +} + +//! Gets an attribute as a 2d line +core::line2df CAttributes::getAttributeAsLine2d(s32 index) +{ + core::line2df ret(0,0, 0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getLine2d(); + + return ret; +} + +//! Sets an attribute as a 2d line +void CAttributes::setAttribute(s32 index, core::line2df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setLine2d(v); +} + +//! Adds an attribute as a 3d line +void CAttributes::addLine3d(const c8* attributeName, core::line3df v) +{ + Attributes.push_back(new CLine3dAttribute(attributeName, v)); +} + +//! Sets an attribute as a 3d line +void CAttributes::setAttribute(const c8* attributeName, core::line3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setLine3d(v); + else + { + Attributes.push_back(new CLine3dAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d line +core::line3df CAttributes::getAttributeAsLine3d(const c8* attributeName) +{ + core::line3df ret(0,0,0, 0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getLine3d(); + + return ret; +} + +//! Gets an attribute as a 3d line +core::line3df CAttributes::getAttributeAsLine3d(s32 index) +{ + core::line3df ret(0,0,0, 0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getLine3d(); + + return ret; +} + +//! Sets an attribute as a 3d line +void CAttributes::setAttribute(s32 index, core::line3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setLine3d(v); + +} + + +//! Adds an attribute as user pointner +void CAttributes::addUserPointer(const c8* attributeName, void* userPointer) +{ + Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer)); +} + +//! Sets an attribute as user pointer +void CAttributes::setAttribute(const c8* attributeName, void* userPointer) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setUserPointer(userPointer); + else + { + Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer)); + } +} + +//! Gets an attribute as user pointer +//! \param attributeName: Name of the attribute to get. +void* CAttributes::getAttributeAsUserPointer(const c8* attributeName) +{ + void* value = 0; + + IAttribute* att = getAttributeP(attributeName); + if (att) + value = att->getUserPointer(); + + return value; +} + +//! Gets an attribute as user pointer +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +void* CAttributes::getAttributeAsUserPointer(s32 index) +{ + void* value = 0; + + if (index >= 0 && index < (s32)Attributes.size()) + value = Attributes[index]->getUserPointer(); + + return value; +} + +//! Sets an attribute as user pointer +void CAttributes::setAttribute(s32 index, void* userPointer) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setUserPointer(userPointer); +} + + +//! Reads attributes from a xml file. +//! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. +//! IF set to false, the first appearing list attributes are read. +bool CAttributes::read(io::IXMLReader* reader, bool readCurrentElementOnly, + const wchar_t* nonDefaultElementName) +{ + if (!reader) + return false; + + clear(); + + core::stringw elementName = L"attributes"; + if (nonDefaultElementName) + elementName = nonDefaultElementName; + + if (readCurrentElementOnly) + { + if (elementName != reader->getNodeName()) + return false; + } + + while(reader->read()) + { + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT: + readAttributeFromXML(reader); + break; + case io::EXN_ELEMENT_END: + if (elementName == reader->getNodeName()) + return true; + break; + default: + break; + } + } + + return true; +} + + +void CAttributes::readAttributeFromXML(io::IXMLReader* reader) +{ + core::stringw element = reader->getNodeName(); + core::stringc name = reader->getAttributeValue(L"name"); + + if (element == L"enum") + { + addEnum(name.c_str(), 0, 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"color") + { + addColor(name.c_str(), video::SColor()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"colorf") + { + addColorf(name.c_str(), video::SColorf()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"float") + { + addFloat(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"int") + { + addInt(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"bool") + { + addBool(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"string") + { + addString(name.c_str(), ""); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"texture") + { + addTexture(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"vector3d") + { + addVector3d(name.c_str(), core::vector3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"position") + { + addPosition2d(name.c_str(), core::position2di()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"rect") + { + addRect(name.c_str(), core::rect()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"matrix") + { + addMatrix(name.c_str(), core::matrix4()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"quaternion") + { + addQuaternion(name.c_str(), core::quaternion()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"box3d") + { + addBox3d(name.c_str(), core::aabbox3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"plane") + { + addPlane3d(name.c_str(), core::plane3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"triangle") + { + addTriangle3d(name.c_str(), core::triangle3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"line2d") + { + addLine2d(name.c_str(), core::line2df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"line3d") + { + addLine3d(name.c_str(), core::line3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"stringwarray") + { + core::array tmpArray; + + s32 count = reader->getAttributeValueAsInt(L"count"); + s32 n=0; + const core::stringw tmpName(L"value"); + for (; ngetAttributeValue((tmpName+n).c_str())); + } + addArray(name.c_str(),tmpArray); + } +} + +//! Write these attributes into a xml file +bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader, + const wchar_t* nonDefaultElementName) +{ + if (!writer) + return false; + + if (writeXMLHeader) + writer->writeXMLHeader(); + + core::stringw elementName = L"attributes"; + if (nonDefaultElementName) + elementName = nonDefaultElementName; + + writer->writeElement(elementName.c_str(), false); + writer->writeLineBreak(); + + s32 i=0; + for (; i<(s32)Attributes.size(); ++i) + { + if ( Attributes[i]->getType() == EAT_STRINGWARRAY ) + { + core::array arraynames, arrayvalues; + core::array arrayinput = Attributes[i]->getArray(); + + // build arrays + + // name + arraynames.push_back(core::stringw(L"name")); + arrayvalues.push_back(core::stringw(Attributes[i]->Name.c_str()) ); + + // count + arraynames.push_back(core::stringw(L"count")); + arrayvalues.push_back(core::stringw((s32)arrayinput.size())); + + // array... + u32 n=0; + const core::stringw tmpName(L"value"); + for (; n < arrayinput.size(); ++n) + { + arraynames.push_back((tmpName+n).c_str()); + arrayvalues.push_back(arrayinput[n]); + } + + // write them + writer->writeElement( Attributes[i]->getTypeString(), true, arraynames, arrayvalues); + } + else + { + writer->writeElement( + Attributes[i]->getTypeString(), true, + L"name", core::stringw(Attributes[i]->Name.c_str()).c_str(), + L"value", Attributes[i]->getStringW().c_str() ); + } + + writer->writeLineBreak(); + } + + writer->writeClosingTag(elementName.c_str()); + writer->writeLineBreak(); + + return true; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CAttributes.h b/src/dep/src/irrlicht/CAttributes.h new file mode 100644 index 0000000..8ae8a64 --- /dev/null +++ b/src/dep/src/irrlicht/CAttributes.h @@ -0,0 +1,732 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ATTRIBUTES_H_INCLUDED__ +#define __C_ATTRIBUTES_H_INCLUDED__ + +#include "IAttributes.h" + +namespace irr +{ +namespace video +{ + class ITexture; + class IVideoDriver; +} +namespace io +{ + +class IAttribute; + +//! Implementation of the IAttributes interface +class CAttributes : public IAttributes +{ +public: + + CAttributes(video::IVideoDriver* driver=0); + ~CAttributes(); + + //! Returns amount of attributes in this collection of attributes. + virtual u32 getAttributeCount() const; + + //! Returns attribute name by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeName(s32 index); + + //! Returns the type of an attribute + //! \param attributeName: Name for the attribute + virtual E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName); + + //! Returns attribute type by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual E_ATTRIBUTE_TYPE getAttributeType(s32 index); + + //! Returns the type string of the attribute + //! \param attributeName: String for the attribute type + virtual const wchar_t* getAttributeTypeString(const c8* attributeName); + + //! Returns the type string of the attribute by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const wchar_t* getAttributeTypeString(s32 index); + + //! Returns if an attribute with a name exists + virtual bool existsAttribute(const c8* attributeName); + + //! Returns attribute index from name, -1 if not found + virtual s32 findAttribute(const c8* attributeName); + + //! Removes all attributes + virtual void clear(); + + //! Reads attributes from a xml file. + //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. + //! IF set to false, the first appearing list attributes are read. + virtual bool read(io::IXMLReader* reader, bool readCurrentElementOnly=false, + const wchar_t* nonDefaultElementName = 0); + + //! Write these attributes into a xml file + virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* nonDefaultElementName=0); + + + /* + + Integer Attribute + + */ + + //! Adds an attribute as integer + virtual void addInt(const c8* attributeName, s32 value); + + //! Sets an attribute as integer value + virtual void setAttribute(const c8* attributeName, s32 value); + + //! Gets an attribute as integer value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsInt(const c8* attributeName); + + //! Gets an attribute as integer value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsInt(s32 index); + + //! Sets an attribute as integer value + virtual void setAttribute(s32 index, s32 value); + + /* + + Float Attribute + + */ + + //! Adds an attribute as float + virtual void addFloat(const c8* attributeName, f32 value); + + //! Sets a attribute as float value + virtual void setAttribute(const c8* attributeName, f32 value); + + //! Gets an attribute as float value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual f32 getAttributeAsFloat(const c8* attributeName); + + //! Gets an attribute as float value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual f32 getAttributeAsFloat(s32 index); + + //! Sets an attribute as float value + virtual void setAttribute(s32 index, f32 value); + + /* + + String Attribute + + */ + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const c8* value); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const c8* value); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringc getAttributeAsString(const c8* attributeName); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsString(const c8* attributeName, c8* target); + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringc getAttributeAsString(s32 index); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const c8* value); + + // wide strings + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const wchar_t* value); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const wchar_t* value); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringw getAttributeAsStringW(const c8* attributeName); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsStringW(const c8* attributeName, wchar_t* target); + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringw getAttributeAsStringW(s32 index); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const wchar_t* value); + + /* + + Binary Data Attribute + + */ + + //! Adds an attribute as binary data + virtual void addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes); + + //! Sets an attribute as binary data + virtual void setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes); + + //! Gets an attribute as binary data + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes); + + //! Gets an attribute as binary data + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes); + + //! Sets an attribute as binary data + virtual void setAttribute(s32 index, void* data, s32 dataSizeInBytes); + + + /* + + Array Attribute + + */ + + //! Adds an attribute as wide string array + virtual void addArray(const c8* attributeName, core::array value); + + //! Sets an attribute value as a wide string array. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const core::array value); + + //! Gets an attribute as an array of wide strings. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::array getAttributeAsArray(const c8* attributeName); + + //! Returns attribute value as an array of wide strings by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::array getAttributeAsArray(s32 index); + + //! Sets an attribute as an array of wide strings + virtual void setAttribute(s32 index, core::array value); + + /* + + Bool Attribute + + */ + + //! Adds an attribute as bool + virtual void addBool(const c8* attributeName, bool value); + + //! Sets an attribute as boolean value + virtual void setAttribute(const c8* attributeName, bool value); + + //! Gets an attribute as boolean value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual bool getAttributeAsBool(const c8* attributeName); + + //! Gets an attribute as boolean value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual bool getAttributeAsBool(s32 index); + + //! Sets an attribute as boolean value + virtual void setAttribute(s32 index, bool value); + + /* + + Enumeration Attribute + + */ + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals); + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, s32 enumValue, const c8* const* enumerationLiterals); + + //! Sets an attribute as enumeration + virtual void setAttribute(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals); + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual const c8* getAttributeAsEnumeration(const c8* attributeName); + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \param enumerationLiteralsToUse: Use these enumeration literals to get the index value instead of the set ones. + //! This is useful when the attribute list maybe was read from an xml file, and only contains the enumeration string, but + //! no information about its index. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsEnumeration(const c8* attributeName, const c8* const* enumerationLiteralsToUse); + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsEnumeration(s32 index, const c8* const* enumerationLiteralsToUse); + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeAsEnumeration(s32 index); + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array& outLiterals); + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array& outLiterals); + + //! Sets an attribute as enumeration + virtual void setAttribute(s32 index, const c8* enumValue, const c8* const* enumerationLiterals); + + + /* + + SColor Attribute + + */ + + //! Adds an attribute as color + virtual void addColor(const c8* attributeName, video::SColor value); + + //! Sets a attribute as color + virtual void setAttribute(const c8* attributeName, video::SColor color); + + //! Gets an attribute as color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColor getAttributeAsColor(const c8* attributeName); + + //! Gets an attribute as color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColor getAttributeAsColor(s32 index); + + //! Sets an attribute as color + virtual void setAttribute(s32 index, video::SColor color); + + /* + + SColorf Attribute + + */ + + //! Adds an attribute as floating point color + virtual void addColorf(const c8* attributeName, video::SColorf value); + + //! Sets a attribute as floating point color + virtual void setAttribute(const c8* attributeName, video::SColorf color); + + //! Gets an attribute as floating point color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColorf getAttributeAsColorf(const c8* attributeName); + + //! Gets an attribute as floating point color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColorf getAttributeAsColorf(s32 index); + + //! Sets an attribute as floating point color + virtual void setAttribute(s32 index, video::SColorf color); + + + /* + + Vector3d Attribute + + */ + + //! Adds an attribute as 3d vector + virtual void addVector3d(const c8* attributeName, core::vector3df value); + + //! Sets a attribute as 3d vector + virtual void setAttribute(const c8* attributeName, core::vector3df v); + + //! Gets an attribute as 3d vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector3df getAttributeAsVector3d(const c8* attributeName); + + //! Gets an attribute as 3d vector + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector3df getAttributeAsVector3d(s32 index); + + //! Sets an attribute as vector + virtual void setAttribute(s32 index, core::vector3df v); + + /* + + Position2d Attribute + + */ + + //! Adds an attribute as 2d position + virtual void addPosition2d(const c8* attributeName, core::position2di value); + + //! Sets a attribute as 2d position + virtual void setAttribute(const c8* attributeName, core::position2di v); + + //! Gets an attribute as position + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::position2di getAttributeAsPosition2d(const c8* attributeName); + + //! Gets an attribute as position + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::position2di getAttributeAsPosition2d(s32 index); + + //! Sets an attribute as 2d position + virtual void setAttribute(s32 index, core::position2di v); + + /* + + Rectangle Attribute + + */ + + //! Adds an attribute as rectangle + virtual void addRect(const c8* attributeName, core::rect value); + + //! Sets an attribute as rectangle + virtual void setAttribute(const c8* attributeName, core::rect v); + + //! Gets an attribute as rectangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::rect getAttributeAsRect(const c8* attributeName); + + //! Gets an attribute as rectangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::rect getAttributeAsRect(s32 index); + + //! Sets an attribute as rectangle + virtual void setAttribute(s32 index, core::rect v); + + + /* + + matrix attribute + + */ + + //! Adds an attribute as matrix + virtual void addMatrix(const c8* attributeName, const core::matrix4& v); + + //! Sets an attribute as matrix + virtual void setAttribute(const c8* attributeName, const core::matrix4& v); + + //! Gets an attribute as a matrix4 + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::matrix4 getAttributeAsMatrix(const c8* attributeName); + + //! Gets an attribute as matrix + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::matrix4 getAttributeAsMatrix(s32 index); + + //! Sets an attribute as matrix + virtual void setAttribute(s32 index, const core::matrix4& v); + + /* + quaternion attribute + + */ + + //! Adds an attribute as quaternion + virtual void addQuaternion(const c8* attributeName, core::quaternion v); + + //! Sets an attribute as quaternion + virtual void setAttribute(const c8* attributeName, core::quaternion v); + + //! Gets an attribute as a quaternion + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::quaternion getAttributeAsQuaternion(const c8* attributeName); + + //! Gets an attribute as quaternion + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::quaternion getAttributeAsQuaternion(s32 index); + + //! Sets an attribute as quaternion + virtual void setAttribute(s32 index, core::quaternion v); + + /* + + 3d bounding box + + */ + + //! Adds an attribute as axis aligned bounding box + virtual void addBox3d(const c8* attributeName, core::aabbox3df v); + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(const c8* attributeName, core::aabbox3df v); + + //! Gets an attribute as a axis aligned bounding box + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::aabbox3df getAttributeAsBox3d(const c8* attributeName); + + //! Gets an attribute as axis aligned bounding box + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::aabbox3df getAttributeAsBox3d(s32 index); + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(s32 index, core::aabbox3df v); + + /* + + plane + + */ + + //! Adds an attribute as 3d plane + virtual void addPlane3d(const c8* attributeName, core::plane3df v); + + //! Sets an attribute as 3d plane + virtual void setAttribute(const c8* attributeName, core::plane3df v); + + //! Gets an attribute as a 3d plane + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::plane3df getAttributeAsPlane3d(const c8* attributeName); + + //! Gets an attribute as 3d plane + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::plane3df getAttributeAsPlane3d(s32 index); + + //! Sets an attribute as 3d plane + virtual void setAttribute(s32 index, core::plane3df v); + + + /* + + 3d triangle + + */ + + //! Adds an attribute as 3d triangle + virtual void addTriangle3d(const c8* attributeName, core::triangle3df v); + + //! Sets an attribute as 3d trianle + virtual void setAttribute(const c8* attributeName, core::triangle3df v); + + //! Gets an attribute as a 3d triangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::triangle3df getAttributeAsTriangle3d(const c8* attributeName); + + //! Gets an attribute as 3d triangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::triangle3df getAttributeAsTriangle3d(s32 index); + + //! Sets an attribute as 3d triangle + virtual void setAttribute(s32 index, core::triangle3df v); + + + /* + + line 2d + + */ + + //! Adds an attribute as a 2d line + virtual void addLine2d(const c8* attributeName, core::line2df v); + + //! Sets an attribute as a 2d line + virtual void setAttribute(const c8* attributeName, core::line2df v); + + //! Gets an attribute as a 2d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line2df getAttributeAsLine2d(const c8* attributeName); + + //! Gets an attribute as a 2d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line2df getAttributeAsLine2d(s32 index); + + //! Sets an attribute as a 2d line + virtual void setAttribute(s32 index, core::line2df v); + + + /* + + line 3d + + */ + + //! Adds an attribute as a 3d line + virtual void addLine3d(const c8* attributeName, core::line3df v); + + //! Sets an attribute as a 3d line + virtual void setAttribute(const c8* attributeName, core::line3df v); + + //! Gets an attribute as a 3d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line3df getAttributeAsLine3d(const c8* attributeName); + + //! Gets an attribute as a 3d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line3df getAttributeAsLine3d(s32 index); + + //! Sets an attribute as a 3d line + virtual void setAttribute(s32 index, core::line3df v); + + + /* + + Texture Attribute + + */ + + //! Adds an attribute as texture reference + virtual void addTexture(const c8* attributeName, video::ITexture* texture); + + //! Sets an attribute as texture reference + virtual void setAttribute(const c8* attributeName, video::ITexture* texture ); + + //! Gets an attribute as texture reference + //! \param attributeName: Name of the attribute to get. + virtual video::ITexture* getAttributeAsTexture(const c8* attributeName); + + //! Gets an attribute as texture reference + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::ITexture* getAttributeAsTexture(s32 index); + + //! Sets an attribute as texture reference + virtual void setAttribute(s32 index, video::ITexture* texture); + + + + /* + + User Pointer Attribute + + */ + + //! Adds an attribute as user pointner + virtual void addUserPointer(const c8* attributeName, void* userPointer); + + //! Sets an attribute as user pointer + virtual void setAttribute(const c8* attributeName, void* userPointer); + + //! Gets an attribute as user pointer + //! \param attributeName: Name of the attribute to get. + virtual void* getAttributeAsUserPointer(const c8* attributeName); + + //! Gets an attribute as user pointer + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void* getAttributeAsUserPointer(s32 index); + + //! Sets an attribute as user pointer + virtual void setAttribute(s32 index, void* userPointer); + +protected: + + void readAttributeFromXML(io::IXMLReader* reader); + + core::array Attributes; + + IAttribute* getAttributeP(const c8* attributeName); + + video::IVideoDriver* Driver; +}; + + +class IAttribute : public virtual IReferenceCounted +{ +public: + + virtual ~IAttribute() {}; + + virtual s32 getInt() { return 0; } + virtual f32 getFloat() { return 0; } + virtual video::SColorf getColorf() { return video::SColorf(1.0f,1.0f,1.0f,1.0f); } + virtual video::SColor getColor() { return video::SColor(255,255,255,255); } + virtual core::stringc getString() { return core::stringc(getStringW().c_str()); } + virtual core::stringw getStringW() { return core::stringw(); } + virtual core::array getArray() { return core::array(); }; + virtual bool getBool() { return false; } + virtual void getBinary(void* outdata, s32 maxLength) {}; + virtual core::vector3df getVector() { return core::vector3df(); } + virtual core::position2di getPosition() { return core::position2di(); } + virtual core::rect getRect() { return core::rect(); } + virtual core::quaternion getQuaternion(){ return core::quaternion(); } + virtual core::matrix4 getMatrix() { return core::matrix4(); } + virtual core::triangle3df getTriangle() { return core::triangle3df(); } + virtual core::vector2df getVector2d() { return core::vector2df(); } + virtual core::vector2di getVector2di() { return core::vector2di(); } + virtual core::line2df getLine2d() { return core::line2df(); } + virtual core::line2di getLine2di() { return core::line2di(); } + virtual core::line3df getLine3d() { return core::line3df(); } + virtual core::line3di getLine3di() { return core::line3di(); } + virtual core::dimension2di getDimension2d() { return core::dimension2di(); } + virtual core::aabbox3d getBBox() { return core::aabbox3d(); } + virtual core::plane3df getPlane() { return core::plane3df(); } + + virtual video::ITexture* getTexture() { return 0; } + virtual const char* getEnum() { return 0; } + virtual void* getUserPointer() { return 0; } + + virtual void setInt(s32 intValue) {}; + virtual void setFloat(f32 floatValue) {}; + virtual void setString(const char* text) {}; + virtual void setString(const wchar_t* text){ setString(core::stringc(text).c_str()); }; + virtual void setArray( core::array arr ) {}; + virtual void setColor(video::SColorf color) {}; + virtual void setColor(video::SColor color) {}; + virtual void setBool(bool boolValue) {}; + virtual void setBinary(void* data, s32 maxLenght) {}; + virtual void setVector(core::vector3df v) {}; + virtual void setPosition(core::position2di v) {}; + virtual void setRect(core::rect v) {}; + virtual void setQuaternion(core::quaternion v) {}; + virtual void setMatrix(core::matrix4 v) {}; + virtual void setTriangle(core::triangle3df v) {}; + virtual void setVector2d(core::vector2df v) {}; + virtual void setVector2d(core::vector2di v) {}; + virtual void setLine2d(core::line2df v) {}; + virtual void setLine2d(core::line2di v) {}; + virtual void setLine3d(core::line3df v) {}; + virtual void setLine3d(core::line3di v) {}; + virtual void setDimension2d(core::dimension2di v) {}; + virtual void setBBox(core::aabbox3d v) {}; + virtual void setPlane(core::plane3df v) {}; + virtual void setUserPointer(void* v) {}; + + virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) {}; + virtual void setTexture(video::ITexture*) {}; + + core::stringc Name; + + virtual E_ATTRIBUTE_TYPE getType() const = 0; + virtual const wchar_t* getTypeString() const = 0; +}; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CB3DMeshFileLoader.cpp b/src/dep/src/irrlicht/CB3DMeshFileLoader.cpp new file mode 100644 index 0000000..aa1b00b --- /dev/null +++ b/src/dep/src/irrlicht/CB3DMeshFileLoader.cpp @@ -0,0 +1,993 @@ + +// B3D Mesh loader +//file format designed by mark sibly for the blitz3d engine and has been declared public domain +//loader by luke hoschke + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_B3D_LOADER_ + +#include "CB3DMeshFileLoader.h" + +#include "IVideoDriver.h" +#include "os.h" + + +namespace irr +{ +namespace scene +{ + +//! Constructor +CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr) +: B3dStack(), NormalsInFile(false), SceneManager(smgr), AnimatedMesh(0), file(0) +{ + #ifdef _DEBUG + setDebugName("CB3DMeshFileLoader"); + #endif +} + + +//! destructor +CB3DMeshFileLoader::~CB3DMeshFileLoader() +{ + for (s32 n=Materials.size()-1; n>=0; --n) + delete Materials[n].Material; +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CB3DMeshFileLoader::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".b3d") != 0; +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f) +{ + if (!f) + return 0; + + file = f; + AnimatedMesh = new scene::CSkinnedMesh(); + + Buffers = &AnimatedMesh->getMeshBuffers(); + AllJoints = &AnimatedMesh->getAllJoints(); + + if ( load() ) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } + + return AnimatedMesh; +} + + +bool CB3DMeshFileLoader::load() +{ + B3dStack.clear(); + + NormalsInFile=false; + + //------ Get header ------ + + SB3dChunkHeader header; + file->read(&header, sizeof(header)); + + #ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); + #endif + + if ( strncmp( header.name, "BB3D", 4 ) != 0 ) + { + os::Printer::log("File is not a b3d file. Loading failed (No header found)", file->getFileName(), ELL_ERROR); + return false; + } + + // Add main chunk... + B3dStack.push_back(SB3dChunk()); + B3dStack.getLast().name[0] = header.name[0]; + B3dStack.getLast().name[1] = header.name[1]; + B3dStack.getLast().name[2] = header.name[2]; + B3dStack.getLast().name[3] = header.name[3]; + B3dStack.getLast().startposition = file->getPos()-8; + B3dStack.getLast().length = header.size+8; + + // Get file version, but ignore it, as it's not important with b3d files... + u32 FileVersion; + file->read(&FileVersion, sizeof(FileVersion)); + #ifdef __BIG_ENDIAN__ + FileVersion = os::Byteswap::byteswap(FileVersion); + #endif + + //------ Read main chunk ------ + + while ( B3dStack.getLast().startposition+B3dStack.getLast().length > file->getPos() ) + { + B3dStack.push_back(SB3dChunk()); + + file->read(&header, sizeof(header)); + + #ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); + #endif + + B3dStack.getLast().name[0] = header.name[0]; + B3dStack.getLast().name[1] = header.name[1]; + B3dStack.getLast().name[2] = header.name[2]; + B3dStack.getLast().name[3] = header.name[3]; + B3dStack.getLast().startposition = file->getPos() - 8; + B3dStack.getLast().length = header.size + 8; + + bool knownChunk = false; + + if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 ) + { + knownChunk=true; + if (!readChunkTEXS()) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 ) + { + knownChunk=true; + if (!readChunkBRUS()) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) + { + knownChunk=true; + if (!readChunkNODE((CSkinnedMesh::SJoint*)0) ) + return false; + } + + if (!knownChunk) + { + os::Printer::log("Unknown chunk found in mesh base - skipping"); + file->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.clear(); + + BaseVertices.clear(); + AnimatedVertices_VertexID.clear(); + AnimatedVertices_BufferID.clear(); + + Materials.clear(); + Textures.clear(); + + Buffers=0; + AllJoints=0; + + return true; +} + + +bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *InJoint) +{ + core::stringc JointName = readString(); + + f32 position[3], scale[3], rotation[4]; + s32 n; + + for (n=0; n<=2; n++) + file->read(&position[n], sizeof(f32)); + + for (n=0; n<=2; n++) + file->read(&scale[n], sizeof(f32)); + + for (n=0; n<=3; n++) + file->read(&rotation[n], sizeof(f32)); + + #ifdef __BIG_ENDIAN__ + for (n=0; n<=2; n++) + position[n] = os::Byteswap::byteswap(position[n]); + + for (n=0; n<=2; n++) + scale[n] = os::Byteswap::byteswap(scale[n]); + + for (n=0; n<=3; n++) + rotation[n] = os::Byteswap::byteswap(rotation[n]); + #endif + + CSkinnedMesh::SJoint *Joint = AnimatedMesh->createJoint(InJoint); + + Joint->Name = JointName; + Joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ; + Joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]); + Joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]); + + //Build LocalMatrix: + + core::matrix4 positionMatrix; + positionMatrix.setTranslation( Joint->Animatedposition ); + core::matrix4 scaleMatrix; + scaleMatrix.setScale( Joint->Animatedscale ); + core::matrix4 rotationMatrix = Joint->Animatedrotation.getMatrix(); + + Joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix; + + if (InJoint) + Joint->GlobalMatrix = InJoint->GlobalMatrix * Joint->LocalMatrix; + else + Joint->GlobalMatrix = Joint->LocalMatrix; + + while(B3dStack.getLast().startposition + B3dStack.getLast().length > file->getPos()) // this chunk repeats + { + B3dStack.push_back(SB3dChunk()); + + SB3dChunkHeader header; + file->read(&header, sizeof(header)); + + #ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); + #endif + + B3dStack.getLast().name[0] = header.name[0]; + B3dStack.getLast().name[1] = header.name[1]; + B3dStack.getLast().name[2] = header.name[2]; + B3dStack.getLast().name[3] = header.name[3]; + B3dStack.getLast().length = header.size+8; + B3dStack.getLast().startposition = file->getPos() - 8; + + bool knownChunk = false; + + if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) + { + knownChunk = true; + if (!readChunkNODE(Joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 ) + { + knownChunk = true; + if (!readChunkMESH(Joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 ) + { + knownChunk = true; + if (!readChunkANIM(Joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 ) + { + knownChunk = true; + if (!readChunkBONE(Joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 ) + { + knownChunk = true; + if(!readChunkKEYS(Joint)) + return false; + } + + if (!knownChunk) + { + os::Printer::log("Unknown chunk found in node chunk - skipping"); + file->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + +bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *InJoint) +{ + const s32 vertices_Start=BaseVertices.size(); //B3Ds have Vertex ID's local within the mesh I don't want this + + s32 brush_id; + + file->read(&brush_id, sizeof(brush_id)); + + #ifdef __BIG_ENDIAN__ + brush_id = os::Byteswap::byteswap(brush_id); + #endif + + NormalsInFile=false; + + while(B3dStack.getLast().startposition + B3dStack.getLast().length>file->getPos()) //this chunk repeats + { + B3dStack.push_back(SB3dChunk()); + + SB3dChunkHeader header; + file->read(&header, sizeof(header)); + + #ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); + #endif + + B3dStack.getLast().name[0]=header.name[0]; + B3dStack.getLast().name[1]=header.name[1]; //Not sure of an easier way + B3dStack.getLast().name[2]=header.name[2]; + B3dStack.getLast().name[3]=header.name[3]; + B3dStack.getLast().length = header.size + 8; + B3dStack.getLast().startposition = file->getPos() - 8; + + bool knownChunk=false; + + if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 ) + { + knownChunk=true; + if (!readChunkVRTS(InJoint, 0, vertices_Start)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 ) + { + knownChunk=true; + + scene::SSkinMeshBuffer *MeshBuffer = AnimatedMesh->createBuffer(); + + if (brush_id!=-1) + MeshBuffer->Material=(*Materials[brush_id].Material); + + if(readChunkTRIS(InJoint, MeshBuffer,AnimatedMesh->getMeshBuffers().size()-1, vertices_Start)==false) + return false; + + if (!NormalsInFile && MeshBuffer->Material.Lighting) // No point wasting time on lightmapped levels + { + s32 i; + + for ( i=0; i<(s32)MeshBuffer->Indices.size(); i+=3) + { + core::plane3d p( MeshBuffer->getVertex(MeshBuffer->Indices[i+0])->Pos, + MeshBuffer->getVertex(MeshBuffer->Indices[i+1])->Pos, + MeshBuffer->getVertex(MeshBuffer->Indices[i+2])->Pos); + + MeshBuffer->getVertex(MeshBuffer->Indices[i+0])->Normal += p.Normal; + MeshBuffer->getVertex(MeshBuffer->Indices[i+1])->Normal += p.Normal; + MeshBuffer->getVertex(MeshBuffer->Indices[i+2])->Normal += p.Normal; + } + + for ( i = 0; i<(s32)MeshBuffer->getVertexCount(); ++i ) + { + MeshBuffer->getVertex(i)->Normal.normalize (); + BaseVertices[vertices_Start+i].Normal=MeshBuffer->getVertex(i)->Normal; + } + } + } + + if (!knownChunk) + { + os::Printer::log("Unknown chunk found in mesh - skipping"); + file->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +/* +VRTS: + int flags ;1=normal values present, 2=rgba values present + int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 + int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 + { + float x,y,z ;always present + float nx,ny,nz ;vertex normal: present if (flags&1) + float red,green,blue,alpha ;vertex color: present if (flags&2) + float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords + } +*/ +bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *InJoint, scene::SSkinMeshBuffer* MeshBuffer, s32 vertices_Start) +{ + s32 flags, tex_coord_sets, tex_coord_set_size; + + file->read(&flags, sizeof(flags)); + file->read(&tex_coord_sets, sizeof(tex_coord_sets)); + file->read(&tex_coord_set_size, sizeof(tex_coord_set_size)); + + #ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); + tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets); + tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size); + #endif + + if (tex_coord_sets >= 3 || tex_coord_set_size >= 4) // Something is wrong + { + os::Printer::log("tex_coord_sets or tex_coord_set_size too big", file->getFileName(), ELL_ERROR); + return false; + } + + //------ Allocate Memory, for speed -----------// + + s32 MemoryNeeded = B3dStack.getLast().length / sizeof(f32); + s32 NumberOfReads = 3; + + if (flags & 1) + NumberOfReads += 3; + if (flags & 2) + NumberOfReads += 4; + + NumberOfReads += tex_coord_sets*tex_coord_set_size; + + MemoryNeeded /= NumberOfReads; + + BaseVertices.reallocate(MemoryNeeded + BaseVertices.size() + 1); + AnimatedVertices_VertexID.reallocate(MemoryNeeded + AnimatedVertices_VertexID.size() + 1); + + //--------------------------------------------// + + while(B3dStack.getLast().startposition + B3dStack.getLast().length > file->getPos()) // this chunk repeats + { + f32 x=0.0f, y=0.0f, z=0.0f; + f32 nx=0.0f, ny=0.0f, nz=0.0f; + f32 red=1.0f, green=1.0f, blue=1.0f, alpha=1.0f; + f32 tex_coords[3][4]; + + file->read(&x, sizeof(x)); + file->read(&y, sizeof(y)); + file->read(&z, sizeof(z)); + + if (flags & 1) + { + NormalsInFile = true; + file->read(&nx, sizeof(nx)); + file->read(&ny, sizeof(ny)); + file->read(&nz, sizeof(nz)); + } + + if (flags & 2) + { + file->read(&red, sizeof(red)); + file->read(&green, sizeof(green)); + file->read(&blue, sizeof(blue)); + file->read(&alpha, sizeof(alpha)); + } + + for (s32 i=0; iread(&tex_coords[i][j], sizeof(f32)); + + #ifdef __BIG_ENDIAN__ + x = os::Byteswap::byteswap(x); + y = os::Byteswap::byteswap(y); + z = os::Byteswap::byteswap(z); + + if (flags&1) + { + nx = os::Byteswap::byteswap(nx); + ny = os::Byteswap::byteswap(ny); + nz = os::Byteswap::byteswap(nz); + } + + if (flags & 2) + { + red = os::Byteswap::byteswap(red); + green = os::Byteswap::byteswap(green); + blue = os::Byteswap::byteswap(blue); + alpha = os::Byteswap::byteswap(alpha); + } + + for (s32 i=0; i<=tex_coord_sets-1; i++) + for (s32 j=0; j<=tex_coord_set_size-1; j++) + tex_coords[i][j] = os::Byteswap::byteswap(tex_coords[i][j]); + #endif + + f32 tu=0.0f, tv=0.0f; + if (tex_coord_sets >= 1 && tex_coord_set_size >= 2) + { + tu=tex_coords[0][0]; + tv=tex_coords[0][1]; + } + + f32 tu2=0.0f, tv2=0.0f; + if (tex_coord_sets>=2 && tex_coord_set_size>=2) + { + tu2=tex_coords[1][0]; + tv2=tex_coords[1][1]; + } + + // Create Vertex... + video::S3DVertex2TCoords Vertex(x, y, z, nx, ny, nz, video::SColorf(red, green, blue, alpha).toSColor(), tu, tv, tu2, tv2); + + // Transform the Vertex position by nested node... + InJoint->GlobalMatrix.transformVect(Vertex.Pos); + + + InJoint->GlobalMatrix.rotateVect(Vertex.Normal); + + //Add it... + + BaseVertices.push_back(Vertex); + + AnimatedVertices_VertexID.push_back(-1); + AnimatedVertices_BufferID.push_back(-1); + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkTRIS(CSkinnedMesh::SJoint *InJoint, scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 vertices_Start) +{ + + bool showVertexWarning=false; + + s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (I'm using a workaround) + + file->read(&triangle_brush_id, sizeof(triangle_brush_id)); + + #ifdef __BIG_ENDIAN__ + triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id); + #endif + + SB3dMaterial *B3dMaterial; + + if (triangle_brush_id != -1) + B3dMaterial = &Materials[triangle_brush_id]; + else + B3dMaterial = 0; + + if (B3dMaterial) + MeshBuffer->Material = (*B3dMaterial->Material); + + s32 MemoryNeeded = B3dStack.getLast().length / sizeof(s32); + MeshBuffer->Indices.reallocate(MemoryNeeded + MeshBuffer->Indices.size() + 1); + + while(B3dStack.getLast().startposition + B3dStack.getLast().length > file->getPos()) // this chunk repeats + { + s32 vertex_id[3]; + + file->read(&vertex_id[0], sizeof(s32)); + file->read(&vertex_id[1], sizeof(s32)); + file->read(&vertex_id[2], sizeof(s32)); + + #ifdef __BIG_ENDIAN__ + vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]); + vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]); + vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]); + #endif + + //Make Ids global: + vertex_id[0] += vertices_Start; + vertex_id[1] += vertices_Start; + vertex_id[2] += vertices_Start; + + for(s32 i=0; i<3; ++i) + { + if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size()) + return false; + + if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1) + { + if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)MeshBufferID ) //If this vertex is linked in a different meshbuffer + { + AnimatedVertices_VertexID[ vertex_id[i] ] = -1; + AnimatedVertices_BufferID[ vertex_id[i] ] = -1; + showVertexWarning=true; + } + } + if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer + { + + //Check for lightmapping: + if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2d(0,0)) + MeshBuffer->MoveTo_2TCoords(); //Will only affect the meshbuffer the first time this is called + + //Add the vertex to the meshbuffer: + if (MeshBuffer->VertexType == video::EVT_STANDARD) + MeshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] ); + else + MeshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] ); + + //create vertex id to meshbuffer index link: + AnimatedVertices_VertexID[ vertex_id[i] ] = MeshBuffer->getVertexCount()-1; + AnimatedVertices_BufferID[ vertex_id[i] ] = MeshBufferID; + + if (B3dMaterial) + { + // Apply Material/Colour/etc... + video::S3DVertex *Vertex=MeshBuffer->getVertex(MeshBuffer->getVertexCount()-1); + + if (Vertex->Color.getAlpha() == 255) //Note: Irrlicht docs state that 0 is opaque, are they wrong? + Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) ); + + + // Use texture's scale + if (B3dMaterial->Textures[0]) + { + Vertex->TCoords.X *=B3dMaterial->Textures[0]->Xscale; + Vertex->TCoords.Y *=B3dMaterial->Textures[0]->Yscale; + } + /* + if (B3dMaterial->Textures[1]) + { + Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale; + Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale; + } + */ + + } + } + } + + MeshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] ); + MeshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] ); + MeshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] ); + } + + B3dStack.erase(B3dStack.size()-1); + + + + if (showVertexWarning) + os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes"); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *InJoint) +{ + if (B3dStack.getLast().length > 8) + { + while(B3dStack.getLast().startposition + B3dStack.getLast().length>file->getPos()) // this chunk repeats + { + CSkinnedMesh::SWeight *Weight=AnimatedMesh->createWeight(InJoint); + + u32 GlobalVertexID; + + file->read(&GlobalVertexID, sizeof(GlobalVertexID)); + file->read(&Weight->strength, sizeof(Weight->strength)); + + #ifdef __BIG_ENDIAN__ + GlobalVertexID = os::Byteswap::byteswap(GlobalVertexID); + Weight->strength = os::Byteswap::byteswap(Weight->strength); + #endif + + if (AnimatedVertices_VertexID[GlobalVertexID]==-1) + { + os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); + Weight->vertex_id = Weight->buffer_id = 0; + } + else + { + //Find the MeshBuffer and Vertex index from the Global Vertex ID: + Weight->vertex_id = AnimatedVertices_VertexID[GlobalVertexID]; + Weight->buffer_id = AnimatedVertices_BufferID[GlobalVertexID]; + } + } + } + + B3dStack.erase(B3dStack.size()-1); + return true; +} + + +bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *InJoint) +{ + s32 flags; + file->read(&flags, sizeof(flags)); + #ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); + #endif + + while(B3dStack.getLast().startposition + B3dStack.getLast().length>file->getPos()) //this chunk repeats + { + s32 frame; + + f32 positionData[3]; + f32 scaleData[3]; + f32 rotationData[4]; + + file->read(&frame, sizeof(frame)); + + if (flags&1) + readFloats(positionData, 3); + + if (flags&2) + readFloats(scaleData, 3); + + if (flags&4) + readFloats(rotationData, 4); + + #ifdef __BIG_ENDIAN__ + frame = os::Byteswap::byteswap(frame); + #endif + + core::vector3df position = core::vector3df(positionData[0], positionData[1], positionData[2]); + core::vector3df scale = core::vector3df(scaleData[0], scaleData[1], scaleData[2]); + core::quaternion rotation = core::quaternion(rotationData[1], rotationData[2], rotationData[3], rotationData[0]); // meant to be in this order + + // Add key frame + + if (flags & 1) + { + CSkinnedMesh::SPositionKey *Key=AnimatedMesh->createPositionKey(InJoint); + Key->frame = (f32)frame; + Key->position = position; + } + if (flags & 2) + { + CSkinnedMesh::SScaleKey *Key=AnimatedMesh->createScaleKey(InJoint); + Key->frame = (f32)frame; + Key->scale=scale; + } + if (flags & 4) + { + CSkinnedMesh::SRotationKey *Key=AnimatedMesh->createRotationKey(InJoint); + Key->frame = (f32)frame; + Key->rotation = rotation; + } + } + + B3dStack.erase(B3dStack.size()-1); + return true; +} + + +bool CB3DMeshFileLoader::readChunkANIM(CSkinnedMesh::SJoint *InJoint) +{ + s32 AnimFlags; //not stored\used + s32 AnimFrames;//not stored\used + f32 AnimFPS; //not stored\used + + file->read(&AnimFlags, sizeof(s32)); + file->read(&AnimFrames, sizeof(s32)); + readFloats(&AnimFPS, 1); + + #ifdef __BIG_ENDIAN__ + AnimFlags = os::Byteswap::byteswap(AnimFlags); + AnimFrames = os::Byteswap::byteswap(AnimFrames); + #endif + + B3dStack.erase(B3dStack.size()-1); + return true; +} + +bool CB3DMeshFileLoader::readChunkTEXS() +{ + bool Previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); + + while(B3dStack.getLast().startposition + B3dStack.getLast().length>file->getPos()) //this chunk repeats + { + core::stringc TextureName=readString(); + + TextureName=stripPathFromString(file->getFileName(),true) + stripPathFromString(TextureName,false); + + SB3dTexture B3dTexture; + B3dTexture.Texture=SceneManager->getVideoDriver()->getTexture ( TextureName.c_str() ); + + file->read(&B3dTexture.Flags, sizeof(s32)); + file->read(&B3dTexture.Blend, sizeof(s32)); + readFloats(&B3dTexture.Xpos, 1); + readFloats(&B3dTexture.Ypos, 1); + readFloats(&B3dTexture.Xscale, 1); + readFloats(&B3dTexture.Yscale, 1); + readFloats(&B3dTexture.Angle, 1); + + #ifdef __BIG_ENDIAN__ + B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags); + B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend); + #endif + + Textures.push_back(B3dTexture); + } + + B3dStack.erase(B3dStack.size()-1); + + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, Previous32BitTextureFlag); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkBRUS() +{ + s32 n_texs; + + file->read(&n_texs, sizeof(s32)); + + #ifdef __BIG_ENDIAN__ + n_texs = os::Byteswap::byteswap(n_texs); + #endif + + while(B3dStack.getLast().startposition + B3dStack.getLast().length>file->getPos()) //this chunk repeats + { + // This is what blitz basic calls a brush, like a Irrlicht Material + + core::stringc MaterialName=readString(); //Not used but we still need the read it + + SB3dMaterial B3dMaterial; + + B3dMaterial.Material = new video::SMaterial(); + B3dMaterial.Textures[0]=0; + B3dMaterial.Textures[1]=0; + + s32 texture_id[8]; + texture_id[0]=-1; + texture_id[1]=-1; + + file->read(&B3dMaterial.red, sizeof(B3dMaterial.red)); + file->read(&B3dMaterial.green, sizeof(B3dMaterial.green)); + file->read(&B3dMaterial.blue, sizeof(B3dMaterial.blue)); + file->read(&B3dMaterial.alpha, sizeof(B3dMaterial.alpha)); + file->read(&B3dMaterial.shininess, sizeof(B3dMaterial.shininess)); + file->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend)); + file->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx)); + + for (s32 n=0; n < n_texs; ++n) + file->read(&texture_id[n], sizeof(s32)); //I'm not sure of getting the sizeof an array + + #ifdef __BIG_ENDIAN__ + B3dMaterial.red = os::Byteswap::byteswap(B3dMaterial.red); + B3dMaterial.green = os::Byteswap::byteswap(B3dMaterial.green); + B3dMaterial.blue = os::Byteswap::byteswap(B3dMaterial.blue); + B3dMaterial.alpha = os::Byteswap::byteswap(B3dMaterial.alpha); + B3dMaterial.shininess = os::Byteswap::byteswap(B3dMaterial.shininess); + B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend); + B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx); + + for (s32 n=0; n < n_texs; ++n) + texture_id[n] = os::Byteswap::byteswap(texture_id[n]); + #endif + + //------ Get pointers to the texture, based on the IDs ------ + if (texture_id[0] != -1) + B3dMaterial.Textures[0]=&Textures[texture_id[0]]; + if (texture_id[1] != -1) + B3dMaterial.Textures[1]=&Textures[texture_id[1]]; + + + //Fixes problems when the lightmap is on the first texture: + if (texture_id[0] != -1) + { + if (Textures[texture_id[0]].Flags & 65536) // 65536 = secondary UV + { + SB3dTexture *TmpTexture; + TmpTexture = B3dMaterial.Textures[1]; + B3dMaterial.Textures[1] = B3dMaterial.Textures[0]; + B3dMaterial.Textures[0] = TmpTexture; + } + } + + if (B3dMaterial.Textures[0] != 0) + B3dMaterial.Material->setTexture(0, B3dMaterial.Textures[0]->Texture); + if (B3dMaterial.Textures[1] != 0) + B3dMaterial.Material->setTexture(1, B3dMaterial.Textures[1]->Texture); + + //If the first texture is empty: + if (B3dMaterial.Textures[1] != 0 && B3dMaterial.Textures[0] == 0) + { + B3dMaterial.Textures[0] = B3dMaterial.Textures[1]; + B3dMaterial.Textures[1] = 0; + } + + //------ Convert blitz flags/blend to irrlicht ------- + + //Two textures: + if (B3dMaterial.Textures[1]) + { + if (B3dMaterial.alpha==1) + { + if (B3dMaterial.Textures[1]->Blend & 5) //(Multiply 2) + B3dMaterial.Material->MaterialType = video::EMT_LIGHTMAP_M2; + else + B3dMaterial.Material->MaterialType = video::EMT_LIGHTMAP; + } + else + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + else if (B3dMaterial.Textures[0]) //One texture: + { + if (B3dMaterial.Textures[0]->Flags & 2) //(Alpha mapped) + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else if (B3dMaterial.Textures[0]->Flags & 4) //(Masked) + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // Todo: create color key texture + else if (B3dMaterial.alpha == 1) + B3dMaterial.Material->MaterialType = video::EMT_SOLID; + else + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + else //No texture: + { + if (B3dMaterial.alpha == 1) + B3dMaterial.Material->MaterialType = video::EMT_SOLID; + else + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + + B3dMaterial.Material->AmbientColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor (); + + //------ Material fx ------ + + if (B3dMaterial.fx & 1) //full-bright + { + B3dMaterial.Material->AmbientColor = video::SColor(255, 255, 255, 255); + B3dMaterial.Material->Lighting = false; + } + + //if (B3dMaterial.fx & 2) //use vertex colors instead of brush color + + if (B3dMaterial.fx & 4) //flatshaded + B3dMaterial.Material->GouraudShading = false; + + if (B3dMaterial.fx & 16) //disable backface culling + B3dMaterial.Material->BackfaceCulling = false; + + if (B3dMaterial.fx & 32) //force vertex alpha-blending + B3dMaterial.Material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + + B3dMaterial.Material->DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor (); + B3dMaterial.Material->EmissiveColor = video::SColorf(0.5, 0.5, 0.5, 0).toSColor (); + B3dMaterial.Material->SpecularColor = video::SColorf(0, 0, 0, 0).toSColor (); + B3dMaterial.Material->Shininess = B3dMaterial.shininess; + + Materials.push_back(B3dMaterial); + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + +core::stringc CB3DMeshFileLoader::readString() +{ + core::stringc newstring; + while (file->getPos() <= file->getSize()) + { + c8 character; + file->read(&character, sizeof(character)); + if (character==0) + return newstring; + newstring.append(character); + } + return newstring; +} + +core::stringc CB3DMeshFileLoader::stripPathFromString(core::stringc string, bool returnPath) +{ + s32 slashIndex=string.findLast('/'); // forward slash + s32 backSlash=string.findLast('\\'); // back slash + + if (backSlash>slashIndex) slashIndex=backSlash; + + if (slashIndex==-1)//no slashes found + if (returnPath) + return core::stringc(); //no path to return + else + return string; + + if (returnPath) + return string.subString(0, slashIndex + 1); + else + return string.subString(slashIndex+1, string.size() - (slashIndex+1)); +} + +void CB3DMeshFileLoader::readFloats(f32* vec, u32 count) +{ + file->read(vec, count*sizeof(f32)); + #ifdef __BIG_ENDIAN__ + for (u32 n=0; n B3dStack; + + bool NormalsInFile; + + core::array Materials; + core::array Textures; + + core::array AnimatedVertices_VertexID; + + core::array AnimatedVertices_BufferID; + + core::array BaseVertices; + + core::array *Buffers; + core::array *AllJoints; + + // + ISceneManager* SceneManager; + CSkinnedMesh* AnimatedMesh; + io::IReadFile* file; +}; + + +} // end namespace scene +} // end namespace irr + +#endif // __C_B3D_MESH_LOADER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CBSPMeshFileLoader.cpp b/src/dep/src/irrlicht/CBSPMeshFileLoader.cpp new file mode 100644 index 0000000..26f1d8d --- /dev/null +++ b/src/dep/src/irrlicht/CBSPMeshFileLoader.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + +#include "CBSPMeshFileLoader.h" +#include "CQ3LevelMesh.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CBSPMeshFileLoader::CBSPMeshFileLoader(io::IFileSystem* fs,video::IVideoDriver* driver, scene::ISceneManager* smgr) +: FileSystem(fs), Driver(driver), SceneManager(smgr) +{ + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + +//! destructor +CBSPMeshFileLoader::~CBSPMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CBSPMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".bsp") || strstr(filename, ".shader"); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file) +{ + // load quake 3 bsp + if (strstr(file->getFileName(), ".bsp")) + { + CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager); + + q->getShader ( "scripts/models.shader", 1 ); + q->getShader ( "scripts/liquid.shader", 1 ); + //q->getShader ( "scripts/sky.shader", 1 ); + + if ( q->loadFile(file) ) + return q; + + q->drop(); + } + + // load quake 3 shader container + if (strstr(file->getFileName(), ".shader")) + { + CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager); + q->getShader ( file->getFileName(), 1 ); + return q; + } + + return 0; +} + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BSP_LOADER_ + diff --git a/src/dep/src/irrlicht/CBSPMeshFileLoader.h b/src/dep/src/irrlicht/CBSPMeshFileLoader.h new file mode 100644 index 0000000..e044dfc --- /dev/null +++ b/src/dep/src/irrlicht/CBSPMeshFileLoader.h @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_BSP_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_BSP_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading Quake 3 BSP files and shaders +class CBSPMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CBSPMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr); + + //! destructor + virtual ~CBSPMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + io::IFileSystem* FileSystem; + video::IVideoDriver* Driver; + scene::ISceneManager* SceneManager; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CBillboardSceneNode.cpp b/src/dep/src/irrlicht/CBillboardSceneNode.cpp new file mode 100644 index 0000000..8a62358 --- /dev/null +++ b/src/dep/src/irrlicht/CBillboardSceneNode.cpp @@ -0,0 +1,243 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CBillboardSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CBillboardSceneNode::CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::dimension2d& size, + video::SColor shade_top, video::SColor shade_down) + : IBillboardSceneNode(parent, mgr, id, position) +{ + #ifdef _DEBUG + setDebugName("CBillboardSceneNode"); + #endif + + setSize(size); + + indices[0] = 0; + indices[1] = 2; + indices[2] = 1; + indices[3] = 0; + indices[4] = 3; + indices[5] = 2; + + vertices[0].TCoords.set(1.0f, 1.0f); + vertices[0].Color = shade_down; + + vertices[1].TCoords.set(1.0f, 0.0f); + vertices[1].Color = shade_top; + + vertices[2].TCoords.set(0.0f, 0.0f); + vertices[2].Color = shade_top; + + vertices[3].TCoords.set(0.0f, 1.0f); + vertices[3].Color = shade_down; +} + + +//! pre render event +void CBillboardSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! render +void CBillboardSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + // make billboard look to camera + + core::vector3df pos = getAbsolutePosition(); + + core::vector3df campos = camera->getAbsolutePosition(); + core::vector3df target = camera->getTarget(); + core::vector3df up = camera->getUpVector(); + core::vector3df view = target - campos; + view.normalize(); + + core::vector3df horizontal = up.crossProduct(view); + if ( horizontal.getLength() == 0 ) + { + horizontal.set(up.Y,up.X,up.Z); + } + horizontal.normalize(); + horizontal *= 0.5f * Size.Width; + + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * Size.Height; + + view *= -1.0f; + + for (s32 i=0; i<4; ++i) + vertices[i].Normal = view; + + vertices[0].Pos = pos + horizontal + vertical; + vertices[1].Pos = pos + horizontal - vertical; + vertices[2].Pos = pos - horizontal - vertical; + vertices[3].Pos = pos - horizontal + vertical; + + // draw + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(BBox, video::SColor(0,208,195,152)); + } + + core::matrix4 mat; + driver->setTransform(video::ETS_WORLD, mat); + + driver->setMaterial(Material); + + driver->drawIndexedTriangleList(vertices, 4, indices, 2); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBillboardSceneNode::getBoundingBox() const +{ + return BBox; +} + + +//! sets the size of the billboard +void CBillboardSceneNode::setSize(const core::dimension2d& size) +{ + Size = size; + + if (Size.Width == 0.0f) + Size.Width = 1.0f; + + if (Size.Height == 0.0f ) + Size.Height = 1.0f; + + f32 avg = (size.Width + size.Height)/6; + BBox.MinEdge.set(-avg,-avg,-avg); + BBox.MaxEdge.set(avg,avg,avg); +} + + +video::SMaterial& CBillboardSceneNode::getMaterial(u32 i) +{ + return Material; +} + + +//! returns amount of materials used by this scene node. +u32 CBillboardSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! gets the size of the billboard +const core::dimension2d& CBillboardSceneNode::getSize() const +{ + return Size; +} + + +//! Writes attributes of the scene node. +void CBillboardSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IBillboardSceneNode::serializeAttributes(out, options); + + out->addFloat("Width", Size.Width); + out->addFloat("Height", Size.Height); + out->addColor ("Shade_Top", vertices[1].Color ); + out->addColor ("Shade_Down", vertices[0].Color ); +} + + +//! Reads attributes of the scene node. +void CBillboardSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IBillboardSceneNode::deserializeAttributes(in, options); + + Size.Width = in->getAttributeAsFloat("Width"); + Size.Height = in->getAttributeAsFloat("Height"); + vertices[1].Color = in->getAttributeAsColor ( "Shade_Top" ); + vertices[0].Color = in->getAttributeAsColor ( "Shade_Down" ); + + setSize(Size); +} + + +//! Set the color of all vertices of the billboard +//! \param overallColor: the color to set +void CBillboardSceneNode::setColor(const video::SColor & overallColor) +{ + for(u32 vertex = 0; vertex < 4; ++vertex) + vertices[0].Color = overallColor; +} + + +//! Set the color of the top and bottom vertices of the billboard +//! \param topColor: the color to set the top vertices +//! \param bottomColor: the color to set the bottom vertices +void CBillboardSceneNode::setColor(const video::SColor & topColor, const video::SColor & bottomColor) +{ + vertices[0].Color = bottomColor; + vertices[1].Color = topColor; + vertices[2].Color = topColor; + vertices[3].Color = bottomColor; +} + + +//! Gets the color of the top and bottom vertices of the billboard +//! \param[out] topColor: stores the color of the top vertices +//! \param[out] bottomColor: stores the color of the bottom vertices +void CBillboardSceneNode::getColor(video::SColor & topColor, video::SColor & bottomColor) const +{ + bottomColor = vertices[0].Color; + topColor = vertices[1].Color; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CBillboardSceneNode* nb = new CBillboardSceneNode(newParent, + newManager, ID, RelativeTranslation, Size); + + nb->cloneMembers(this, newManager); + nb->Material = Material; + + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CBillboardSceneNode.h b/src/dep/src/irrlicht/CBillboardSceneNode.h new file mode 100644 index 0000000..1feb93a --- /dev/null +++ b/src/dep/src/irrlicht/CBillboardSceneNode.h @@ -0,0 +1,88 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_BILLBOARD_SCENE_NODE_H_INCLUDED__ +#define __C_BILLBOARD_SCENE_NODE_H_INCLUDED__ + +#include "IBillboardSceneNode.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element, +//! which always looks to the camera. +class CBillboardSceneNode : public IBillboardSceneNode +{ +public: + + //! constructor + CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::dimension2d& size, + video::SColor shade_top=video::SColor(0xFFFFFFFF),video::SColor shade_down=video::SColor(0xFFFFFFFF)); + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the size of the billboard + virtual void setSize(const core::dimension2d& size); + + //! gets the size of the billboard + virtual const core::dimension2d& getSize() const; + + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Set the color of all vertices of the billboard + //! \param overallColor: the color to set + virtual void setColor(const video::SColor & overallColor); + + //! Set the color of the top and bottom vertices of the billboard + //! \param topColor: the color to set the top vertices + //! \param bottomColor: the color to set the bottom vertices + virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor); + + //! Gets the color of the top and bottom vertices of the billboard + //! \param[out] topColor: stores the color of the top vertices + //! \param[out] bottomColor: stores the color of the bottom vertices + virtual void getColor(video::SColor& topColor, video::SColor& bottomColor) const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_BILLBOARD; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + +private: + + core::dimension2d Size; + core::aabbox3d BBox; + video::SMaterial Material; + + video::S3DVertex vertices[4]; + u16 indices[6]; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CBoneSceneNode.cpp b/src/dep/src/irrlicht/CBoneSceneNode.cpp new file mode 100644 index 0000000..44fa61c --- /dev/null +++ b/src/dep/src/irrlicht/CBoneSceneNode.cpp @@ -0,0 +1,124 @@ + +#include "CBoneSceneNode.h" + + + +namespace irr +{ +namespace scene +{ + +//! constructor +CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + u32 boneIndex, const c8* boneName) +: IBoneSceneNode(parent, mgr, id), AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL), + BoneIndex(boneIndex), BoneName(boneName) +{ + +} + +//! destructor +CBoneSceneNode::~CBoneSceneNode() +{ + +} + +//! Returns the name of the bone +const c8* CBoneSceneNode::getBoneName() const +{ + return BoneName.c_str(); +} + +//! Returns the index of the bone +u32 CBoneSceneNode::getBoneIndex() const +{ + return BoneIndex; +} + +//! Sets the animation mode of the bone. Returns true if successful. +bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode) +{ + AnimationMode = mode; + return true; +} + +//! Gets the current animation mode of the bone +E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const +{ + return AnimationMode; +} + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBoneSceneNode::getBoundingBox() const +{ + return Box; +} +/* +//! Returns the relative transformation of the scene node. +core::matrix4 CBoneSceneNode::getRelativeTransformation() const +{ + return core::matrix4(); // RelativeTransformation; +} +*/ + +void CBoneSceneNode::OnAnimate(u32 timeMs) +{ + if (IsVisible) + { + // animate this node with all animators + + core::list::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->animateNode(this, timeMs); + + // update absolute position + //updateAbsolutePosition(); + + // perform the post render process on all children + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnAnimate(timeMs); + } +} + + + + +void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node) +{ + Node->updateAbsolutePosition(); + + core::list::ConstIterator it = Node->getChildren().begin(); + for (; it != Node->getChildren().end(); ++it) + { + helper_updateAbsolutePositionOfAllChildren( (*it) ); + } +} + + +void CBoneSceneNode::updateAbsolutePositionOfAllChildren() +{ + helper_updateAbsolutePositionOfAllChildren( this ); +} + + + + + +void CBoneSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addInt("BoneIndex", BoneIndex); + out->addString("BoneName", BoneName.c_str()); + out->addEnum("AnimationMode", AnimationMode, BoneAnimationModeNames); +} + +void CBoneSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + BoneIndex = in->getAttributeAsInt("BoneIndex"); + BoneName = in->getAttributeAsString("BoneName"); + AnimationMode = (E_BONE_ANIMATION_MODE)in->getAttributeAsEnumeration("AnimationMode", BoneAnimationModeNames); + // todo: add/replace bone in parent with bone from mesh +} + +} // namespace scene +} // namespace irr diff --git a/src/dep/src/irrlicht/CBoneSceneNode.h b/src/dep/src/irrlicht/CBoneSceneNode.h new file mode 100644 index 0000000..6d6bbb5 --- /dev/null +++ b/src/dep/src/irrlicht/CBoneSceneNode.h @@ -0,0 +1,88 @@ +#ifndef __C_BONE_SCENE_NODE_H_INCLUDED__ +#define __C_BONE_SCENE_NODE_H_INCLUDED__ + +// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes + +#include "IBoneSceneNode.h" +#include "irrString.h" + + +namespace irr +{ +namespace scene +{ + + class CBoneSceneNode : public IBoneSceneNode + { + public: + + //! constructor + CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, + s32 id=-1, u32 boneIndex=0, const c8* boneName=0); + + //! destructor + ~CBoneSceneNode(); + + //! Returns the name of the bone + virtual const c8* getBoneName() const; + + //! Returns the index of the bone + virtual u32 getBoneIndex() const; + + //! Sets the animation mode of the bone. Returns true if successful. + virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode); + + //! Gets the current animation mode of the bone + virtual E_BONE_ANIMATION_MODE getAnimationMode() const; + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns the relative transformation of the scene node. + //virtual core::matrix4 getRelativeTransformation() const; + + virtual void OnAnimate(u32 timeMs); + + + void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node); + + virtual void updateAbsolutePositionOfAllChildren(); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! How the relative transformation of the bone is used + virtual void setSkinningSpace( E_BONE_SKINNING_SPACE space ) + { + SkinningSpace=space; + } + + virtual E_BONE_SKINNING_SPACE getSkinningSpace() + { + return SkinningSpace; + } + + private: + E_BONE_ANIMATION_MODE AnimationMode; + E_BONE_SKINNING_SPACE SkinningSpace; + + u32 BoneIndex; + core::stringc BoneName; + + + + + + core::aabbox3d Box; + }; + +} // end namespace scene +} // end namespace irr + + + +#endif + diff --git a/src/dep/src/irrlicht/CCSMLoader.cpp b/src/dep/src/irrlicht/CCSMLoader.cpp new file mode 100644 index 0000000..a75b705 --- /dev/null +++ b/src/dep/src/irrlicht/CCSMLoader.cpp @@ -0,0 +1,877 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was written by Saurav Mohapatra and modified by Nikolaus Gebhardt. +// See CCSMLoader.h for details. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_CSM_LOADER_ + +#include "CCSMLoader.h" +#include "os.h" +#include "IFileSystem.h" +#include "IReadFile.h" +#include "ISceneManager.h" +#include "IAttributes.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "SAnimatedMesh.h" +#include "SMeshBufferLightMap.h" + +namespace irr +{ +namespace scene +{ + // + // the CSM data types + // + struct color_rgb_t + { + s32 red; + s32 green; + s32 blue; + + void clear() + { + red = 0; + green = 0; + blue = 0; + } + }; + + class BinaryFileReader; + + // + // The file header + // + class Header + { + public: + + static const s32 VERSION_4; + static const s32 VERSION_4_1; + + Header(){ clear(); } + virtual ~Header(){ clear(); } + + s32 getVersion() const{ return version; } + void clear(){ version = 0; } + void load(BinaryFileReader* pReader); + + private: + + s32 version; + }; + + + // + // The groups + // + class Group + { + public: + + Group(){ clear(); } + virtual ~Group(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + + s32 getFlags() const { return flags; } + s32 getParentGroupID() const { return parentGroup; } + const core::stringc& getProperties() const { return props; } + const color_rgb_t* getColor() const { return &color; } + + private: + + s32 flags; + s32 parentGroup; + core::stringc props; + color_rgb_t color; + }; + + + // + // The visgroups + // + class VisGroup + { + public: + + VisGroup(){ clear(); } + virtual ~VisGroup(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + s32 getFlags() const{ return flags; } + const core::stringc& getName() const{ return name; } + const color_rgb_t* getColor() const{ return &color; } + + private: + + core::stringc name; + s32 flags; + color_rgb_t color; + }; + + + // + // Lightmaps + // + class LightMap + { + public: + + LightMap() : pixelData(0){ clear(); } + virtual ~LightMap(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + s32 getWidth() const{ return width; } + s32 getHeight() const{ return height; } + const s32* getPixelData() const{ return pixelData; } + + private: + + s32 width; + s32 height; + s32* pixelData; + }; + + struct Triangle + { + s32 a,b,c; + }; + + + struct Line + { + s32 a,b; + }; + + + class Vertex + { + public: + + Vertex(){ clear(); } + virtual ~Vertex(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + const core::vector3df* getPosition() const { return &position; } + const core::vector3df* getNormal() const { return &normal; } + const color_rgb_t* getColor() const { return &color; } + const core::vector3df* getTextureCoordinates() const { return &texCoords; } + const core::vector3df* getLightMapCoordinates() const { return &lmapCoords; } + + private: + + core::vector3df position; + core::vector3df normal; + color_rgb_t color; + core::vector3df texCoords; + core::vector3df lmapCoords; + }; + + + class Surface + { + public: + + Surface() { clear(); } + virtual ~Surface(){ clear(); } + + void clear(); + void load(BinaryFileReader *pReader); + + s32 getFlags() const{ return flags; } + const core::stringc& getTextureName() const{ return textureName; } + s32 getLightMapId() const{ return lightMapId; } + const core::vector2df* getUVOffset() const{ return &uvOffset; } + const core::vector2df* getUVScale() const{ return &uvScale; } + f32 getUVRotation() const{ return uvRotation; } + + u32 getVertexCount() const{ return vertices.size(); } + const Vertex* getVertexAt(const s32 index) const{ return vertices[index]; } + + s32 getTriangleCount() const{ return triangles.size(); } + const Triangle& getTriangleAt(const s32 index) const{ return triangles[index]; } + + private: + + s32 flags; + core::stringc textureName; + s32 lightMapId; + core::vector2df uvOffset; + core::vector2df uvScale; + f32 uvRotation; + core::array vertices; + core::array triangles; + core::array lines; + }; + + class Mesh + { + public: + + Mesh(){ clear(); } + virtual ~Mesh(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader, bool bReadVisGroups); + + s32 getFlags() const { return flags; } + s32 getGroupID() const { return groupId; } + const core::stringc& getProperties() const { return props; } + const color_rgb_t* getColor() const { return &color; } + const core::vector3df* getPosition() const { return &position; } + s32 getVisgroupID() const { return visgroupId; } + s32 getSurfaceCount() const { return surfaces.size(); } + const Surface* getSurfaceAt(const s32 index) const { return surfaces[index]; } + + private: + + s32 flags; + s32 groupId; + core::stringc props; + color_rgb_t color; + core::vector3df position; + s32 visgroupId; + + core::array surfaces; + }; + + class Entity + { + public: + + Entity() { clear(); } + virtual ~Entity() { clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + s32 getVisgroupID() const { return visgroupId; } + s32 getGroupID() const { return groupId; } + const core::stringc& getProperties() const { return props; } + const core::vector3df* getPosition() const { return &position; } + + private: + + s32 visgroupId; + s32 groupId; + core::stringc props; + core::vector3df position; + }; + + + class CameraData + { + public: + + CameraData(){ clear(); } + virtual ~CameraData(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + + const core::vector3df* getPosition(){ return &position; } + f32 getPitch(){ return pitch; } + f32 getYaw(){ return yaw; } + + private: + + core::vector3df position; + f32 pitch; + f32 yaw; + }; + + // + // A CSM File + // + class CSMFile + { + public: + + CSMFile(){ clear(); } + virtual ~CSMFile(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + const Header* getHeader() const{ return &header; } + + s32 getGroupCount() const{ return groups.size(); } + const Group* getGroupAt(const s32 index) const{ return groups[index]; } + + s32 getVisGroupCount() const{ return visgroups.size(); } + const VisGroup* getVisGroupAt(const s32 index) const{ return visgroups[index]; } + + s32 getLightMapCount() const{ return lightmaps.size(); } + const LightMap* getLightMapAt(const s32 index) const { return lightmaps[index]; } + + s32 getMeshCount() const{ return meshes.size(); } + const Mesh* getMeshAt(const s32 index) const{ return meshes[index]; } + + s32 getEntityCount() const{ return entities.size(); } + const Entity* getEntityAt(const s32 index) const{ return entities[index]; } + + const CameraData* getCameraData() const{ return &cameraData; } + + private: + + Header header; + core::array groups; + core::array visgroups; + core::array lightmaps; + core::array meshes; + core::array entities; + CameraData cameraData; + }; + + + // + // A Binary File Reader + // + class BinaryFileReader + { + public: + + BinaryFileReader(io::IReadFile* pFile, bool closeWhenDone=true); + virtual ~BinaryFileReader(); + + virtual s32 readBuffer(void* buffer, s32 len); + + s32 readLong(); + f32 readFloat(); + u8 readByte(); + + core::stringc readString(); + void readVec3f(core::vector3df* v); + void readVec2f(core::vector2df* v); + void readColorRGB(color_rgb_t* color); + + private: + + io::IReadFile *file; + bool autoClose; + + }; + + CCSMLoader::CCSMLoader(scene::ISceneManager* manager, io::IFileSystem* fs) + : FileSystem(fs), SceneManager(manager) + { + } + + CCSMLoader::~CCSMLoader() + { + } + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + bool CCSMLoader::isALoadableFileExtension(const c8* fileName) const + { + return strstr(fileName, ".csm")!=0; + } + + //! creates/loads an animated mesh from the file. + IAnimatedMesh* CCSMLoader::createMesh(io::IReadFile* file) + { + file->grab(); // originally, this loader created the file on its own. + + scene::IMesh* m = createCSMMesh(file); + + if (!m) + return 0; + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_CSM; + am->addMesh(m); + m->drop(); + + am->recalculateBoundingBox(); + return am; + } + + scene::IMesh* CCSMLoader::createCSMMesh(io::IReadFile* file) + { + if (!file) + return 0; + + if(file) + { + BinaryFileReader reader(file, true); + CSMFile csmFile; + csmFile.load(&reader); + + scene::IMesh* pMesh = createIrrlichtMesh(&csmFile, + SceneManager->getParameters()->getAttributeAsString(CSM_TEXTURE_PATH), + file->getFileName()); + return pMesh; + } + + return 0; + } + + scene::IMesh* CCSMLoader::createIrrlichtMesh(const CSMFile* csmFile, + core::stringc textureRoot, const c8* lmprefix) + { + scene::SMesh *pMesh = new scene::SMesh(); + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + for(s32 l = 0; lgetLightMapCount(); l++) + { + const LightMap* lmap = csmFile->getLightMapAt(l); + + core::stringc lmapName = lmprefix; + lmapName += "LMAP_"; + lmapName += (int)(l+1); + os::Printer::log("CCSMLoader loading light map", lmapName.c_str()); + + video::IImage* lmapImg = driver->createImageFromData( + video::ECF_A8R8G8B8, + core::dimension2d(lmap->getWidth(),lmap->getHeight()), + (void *)(lmap->getPixelData())); + + driver->addTexture(lmapName.c_str(), lmapImg); + lmapImg->drop(); + + } + + for(s32 m = 0; mgetMeshCount(); m++) + { + const Mesh* mshPtr = csmFile->getMeshAt(m); + + for(s32 s = 0; s < mshPtr->getSurfaceCount(); s++) + { + const Surface* surface = mshPtr->getSurfaceAt(s); + + core::stringc texName = textureRoot; + texName+= "/"; + texName+= surface->getTextureName(); + + video::ITexture* texture = driver->getTexture(texName.c_str()); + scene::SMeshBufferLightMap *buffer = new scene::SMeshBufferLightMap(); + + //material + core::stringc lmapName = lmprefix; + lmapName += "LMAP_"; + lmapName += (int)surface->getLightMapId(); + + buffer->Material.setTexture(0, texture); + buffer->Material.setTexture(1, driver->getTexture(lmapName.c_str())); + buffer->Material.Lighting = false; + buffer->Material.MaterialType = video::EMT_LIGHTMAP_M4; + + for(u32 v = 0; v < surface->getVertexCount(); v++) + { + const Vertex *vtxPtr = surface->getVertexAt(v); + video::S3DVertex2TCoords vtx; + vtx.Pos = *(vtxPtr->getPosition()); + vtx.Normal = *(vtxPtr->getPosition()); + vtx.Color.set(255,vtxPtr->getColor()->red,vtxPtr->getColor()->green,vtxPtr->getColor()->blue); + vtx.TCoords.set(vtxPtr->getTextureCoordinates()->X,vtxPtr->getTextureCoordinates()->Y); + vtx.TCoords2.set(vtxPtr->getLightMapCoordinates()->X,0.0f - vtxPtr->getLightMapCoordinates()->Y); + + buffer->Vertices.push_back(vtx); + } + + for(s32 t = 0; t < surface->getTriangleCount(); t++) + { + const Triangle& tri = surface->getTriangleAt(t); + buffer->Indices.push_back(tri.a); + buffer->Indices.push_back(tri.c); + buffer->Indices.push_back(tri.b); + } + + buffer->recalculateBoundingBox(); + pMesh->addMeshBuffer(buffer); + buffer->drop(); + } + } + + pMesh->recalculateBoundingBox(); + return pMesh; + } + + const s32 Header::VERSION_4 = 4; + const s32 Header::VERSION_4_1 = 5; + + void Header::load(BinaryFileReader* pReader) + { + version = pReader->readLong(); + } + + void Group::clear() + { + color.clear(); + flags = 0; + parentGroup = 0; + props = ""; + } + + void Group::load(BinaryFileReader* pReader) + { + flags = pReader->readLong(); + parentGroup = pReader->readLong(); + props = pReader->readString(); + pReader->readColorRGB(&color); + } + + void VisGroup::clear() + { + color.clear(); + flags = 0; + name = ""; + + } + + void VisGroup::load(BinaryFileReader* pReader) + { + name = pReader->readString(); + flags = pReader->readLong(); + pReader->readColorRGB(&color); + } + + void LightMap::clear() + { + if(pixelData) + { + delete[] pixelData; + pixelData = 0; + } + width = height = 0; + } + + void LightMap::load(BinaryFileReader* pReader) + { + width = pReader->readLong(); + height = pReader->readLong(); + pixelData = new s32[width * height]; + pReader->readBuffer(pixelData, width * height * sizeof(s32)); + } + + void Mesh::clear() + { + flags = 0; + groupId = 0; + visgroupId = 0; + props = ""; + color.clear(); + position.set(0,0,0); + + for(u32 s = 0; s < surfaces.size(); s++) + { + if(surfaces[s]) + { + delete surfaces[s]; + } + } + surfaces.clear(); + } + + void Mesh::load(BinaryFileReader* pReader, bool bReadVisGroups) + { + flags = pReader->readLong(); + groupId = pReader->readLong(); + props = pReader->readString(); + pReader->readColorRGB(&color); + pReader->readVec3f(&position); + if(bReadVisGroups) + visgroupId = pReader->readLong(); + else + visgroupId = 0; + + s32 count = pReader->readLong(); + + for(s32 i = 0; i < count; i++) + { + Surface* surf = new Surface(); + surf->load(pReader); + surfaces.push_back(surf); + } + } + + void Surface::clear() + { + flags = 0; + lightMapId = 0; + textureName = ""; + uvOffset.set(0.0f,0.0f); + uvScale.set(0.0f,0.0f); + uvRotation = 0.0f; + triangles.clear(); + lines.clear(); + + for(u32 v = 0; v < vertices.size(); v++) + delete vertices[v]; + + vertices.clear(); + } + + void Surface::load(BinaryFileReader* pReader) + { + flags = pReader->readLong(); + textureName = pReader->readString(); + + lightMapId = pReader->readLong(); + pReader->readVec2f(&uvOffset); + pReader->readVec2f(&uvScale); + uvRotation = pReader->readFloat(); + s32 vtxCount = pReader->readLong(); + s32 triCount = pReader->readLong(); + s32 lineCount = pReader->readLong(); + + for(s32 v = 0; v < vtxCount; v++) + { + Vertex *vtx = new Vertex(); + vtx->load(pReader); + vertices.push_back(vtx); + } + + for(s32 t = 0; t < triCount; t++) + { + Triangle tri; + pReader->readBuffer(&tri, sizeof(tri)); + triangles.push_back(tri); + } + + for(s32 l = 0; l < lineCount; l++) + { + Line line; + pReader->readBuffer(&line,sizeof(line)); + lines.push_back(line); + + } + + } + + void Vertex::clear() + { + position.set(0,0,0); + normal.set(0,0,0); + color.clear(); + texCoords.set(0,0,0); + lmapCoords.set(0,0,0); + } + + void Vertex::load(BinaryFileReader* pReader) + { + pReader->readVec3f(&position); + pReader->readVec3f(&normal); + pReader->readColorRGB(&color); + pReader->readVec3f(&texCoords); + pReader->readVec3f(&lmapCoords); + } + + void Entity::clear() + { + visgroupId = groupId = 0; + props = ""; + position.set(0,0,0); + } + + void Entity::load(BinaryFileReader* pReader) + { + visgroupId = pReader->readLong(); + groupId = pReader->readLong(); + props = pReader->readString(); + pReader->readVec3f(&position); + } + + void CameraData::clear() + { + position.set(0,0,0); + pitch = 0; + yaw = 0; + } + + void CameraData::load(BinaryFileReader* pReader) + { + pReader->readVec3f(&position); + pitch = pReader->readFloat(); + yaw = pReader->readFloat(); + } + + void CSMFile::clear() + { + header.clear(); + cameraData.clear(); + + u32 x =0; + for( x= 0; x < groups.size(); x++) + delete groups[x]; + + groups.clear(); + + for(x= 0; x < visgroups.size(); x++) + delete visgroups[x]; + + visgroups.clear(); + + for(x= 0; x < lightmaps.size(); x++) + delete lightmaps[x]; + + lightmaps.clear(); + + for(x= 0; x < meshes.size(); x++) + delete meshes[x]; + + meshes.clear(); + + for(x= 0; x < entities.size(); x++) + delete entities[x]; + + entities.clear(); + } + + void CSMFile::load(BinaryFileReader* pReader) + { + clear(); + + header.load(pReader); + + //groups + { + s32 count = pReader->readLong(); + + for (s32 i = 0; i < count; i++) + { + Group* grp = new Group(); + grp->load(pReader); + groups.push_back(grp); + } + } + bool bHasVGroups = (header.getVersion() == Header::VERSION_4_1); + + if (bHasVGroups) + { + //visgroups + s32 count = pReader->readLong(); + + for (s32 i = 0; i < count; i++) + { + VisGroup* grp = new VisGroup(); + grp->load(pReader); + visgroups.push_back(grp); + } + } + + //lightmaps + { + s32 count = pReader->readLong(); + + for(s32 i = 0; i < count; i++) + { + LightMap* grp = new LightMap(); + grp->load(pReader); + lightmaps.push_back(grp); + } + } + + //meshes + { + s32 count = pReader->readLong(); + + for(s32 i = 0; i < count; i++) + { + Mesh* grp = new Mesh(); + grp->load(pReader,bHasVGroups); + meshes.push_back(grp); + } + } + + //entities + { + s32 count = pReader->readLong(); + + for(s32 i = 0; i < count; i++) + { + Entity* grp = new Entity(); + grp->load(pReader); + entities.push_back(grp); + } + } + + //camera data + cameraData.load(pReader); + + + } + + BinaryFileReader::BinaryFileReader(io::IReadFile* pFile, + bool closeWhenDone) + : file(pFile), autoClose(closeWhenDone) + { + } + + BinaryFileReader::~BinaryFileReader() + { + if(autoClose && file) + { + file->drop(); + file = 0; + + } + } + + s32 BinaryFileReader::readBuffer(void* buffer, s32 len) + { + return file->read(buffer,len); + + } + + s32 BinaryFileReader::readLong() + { + int ret = 0; + readBuffer(&ret,sizeof(int)); + return (s32)ret; + } + + f32 BinaryFileReader::readFloat() + { + float ret = 0; + readBuffer(&ret,sizeof(float)); + return (f32)ret; + } + + u8 BinaryFileReader::readByte() + { + char ret = 0; + readBuffer(&ret,sizeof(char)); + return (u8)ret; + } + + core::stringc BinaryFileReader::readString() + { + core::stringc str = ""; + c8 c = (c8)readByte(); + while(c != 0) + { + str += c; + c = (c8)readByte(); + } + return str; + } + + void BinaryFileReader::readVec3f(core::vector3df* v) + { + v->X = readFloat(); + v->Y = readFloat(); + v->Z = readFloat(); + } + + void BinaryFileReader::readVec2f(core::vector2df* v) + { + v->X = readFloat(); + v->Y = readFloat(); + } + + void BinaryFileReader::readColorRGB(color_rgb_t* color) + { + readBuffer(color,sizeof(color_rgb_t)); + } + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_CSM_LOADER_ diff --git a/src/dep/src/irrlicht/CCSMLoader.h b/src/dep/src/irrlicht/CCSMLoader.h new file mode 100644 index 0000000..e4275d3 --- /dev/null +++ b/src/dep/src/irrlicht/CCSMLoader.h @@ -0,0 +1,83 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This Loader has been originally written by Saurav Mohapatra. I (Nikolaus Gebhardt) +// modified some minor things and integrated it into Irrlicht 0.9. Thanks a lot +// to Saurav Mohapatra for his work on this and that he gave me his permission to +// add it into Irrlicht. +// I did some changes to Saurav Mohapatra's loader, so I'm writing this down here: +// - Replaced all dependencies to STL and stdio with irr:: methods/constructs. +// - Moved everything into namespace irr::scene +// - Replaced logging with Irrlicht's internal logger. +// - Removed dependency to IrrlichtDevice +// - Moved all internal structures into CCSMLoader.cpp +// - Made the texture root parameter dependent on a ISceneManager string parameter +// - removed exceptions +// - Implemented CCCSMLoader as IMeshLoader +// - Fixed some problems with memory leaks +// - Fixed bounding box calculation +// +// The original readme of this file looks like this: +// +// This component provides a loader for the Cartography shop 4.x .csm maps for Irrlicht Engine. +// This is a part of the M_TRIX Project. +// This is licensed under the ZLib/LibPNG license +// The IrrCSM library is written by Saurav Mohapatra. +// +// Features +// +// The IrrCSM library features the following capabilities +// +// * Loads the .csm 4.0 and 4.1 files transparently +// * Presents the loaded file as irr::scene::IAnimatedMesh for easy creation of IOctTreeSceneNode +// * Loads the textures given the correct texture root. hence map and textures can be in separate directories +// +// For more informations go to http://www.geocities.com/standard_template/irrcsm/downloads.html + +#ifndef __CSM_LOADER_H_INCLUDED__ +#define __CSM_LOADER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMesh.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "IMeshLoader.h" + +namespace irr +{ +namespace scene +{ + class CSMFile; + class ISceneManager; + + class CCSMLoader : public scene::IMeshLoader + { + public: + + CCSMLoader(ISceneManager* manager, io::IFileSystem* fs); + virtual ~CCSMLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + private: + + scene::IMesh* createCSMMesh(io::IReadFile* file); + + scene::IMesh* createIrrlichtMesh(const CSMFile* csmFile, + core::stringc textureRoot, const c8* lmprefix); + + io::IFileSystem* FileSystem; + scene::ISceneManager* SceneManager; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CCameraFPSSceneNode.cpp b/src/dep/src/irrlicht/CCameraFPSSceneNode.cpp new file mode 100644 index 0000000..a3650a5 --- /dev/null +++ b/src/dep/src/irrlicht/CCameraFPSSceneNode.cpp @@ -0,0 +1,302 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCameraFPSSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "os.h" +#include "Keycodes.h" + +namespace irr +{ +namespace scene +{ + +const f32 MAX_VERTICAL_ANGLE = 88.0f; + +//! constructor +CCameraFPSSceneNode::CCameraFPSSceneNode(ISceneNode* parent, ISceneManager* mgr, + gui::ICursorControl* cursorControl, s32 id, f32 rotateSpeed , f32 moveSpeed,f32 jumpSpeed, + SKeyMap* keyMapArray, s32 keyMapSize, bool noVerticalMovement) +: CCameraSceneNode(parent, mgr, id), CursorControl(cursorControl), + MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed), + firstUpdate(true), LastAnimationTime(0), NoVerticalMovement(noVerticalMovement) +{ + #ifdef _DEBUG + setDebugName("CCameraFPSSceneNode"); + #endif + + if (CursorControl) + CursorControl->grab(); + + MoveSpeed /= 1000.0f; + + recalculateViewArea(); + + allKeysUp(); + + // create key map + if (!keyMapArray || !keyMapSize) + { + // create default key map + KeyMap.push_back(SCamKeyMap(0, irr::KEY_UP)); + KeyMap.push_back(SCamKeyMap(1, irr::KEY_DOWN)); + KeyMap.push_back(SCamKeyMap(2, irr::KEY_LEFT)); + KeyMap.push_back(SCamKeyMap(3, irr::KEY_RIGHT)); + KeyMap.push_back(SCamKeyMap(4, irr::KEY_KEY_J)); + } + else + { + // create custom key map + + for (s32 i=0; idrop(); +} + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CCameraFPSSceneNode::OnEvent(const SEvent& event) +{ + if (event.EventType == EET_KEY_INPUT_EVENT) + { + const u32 cnt = KeyMap.size(); + for (u32 i=0; i::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->animateNode(this, timeMs); + + updateAbsolutePosition(); + Target = getPosition() + TargetVector; + + core::list::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnAnimate(timeMs); +} + + +void CCameraFPSSceneNode::animate( u32 timeMs ) +{ + const u32 camIsMe = SceneManager->getActiveCamera() == this; + + if (firstUpdate) + { + if (CursorControl && camIsMe) + { + CursorControl->setPosition(0.5f, 0.5f); + CenterCursor = CursorControl->getRelativePosition(); + } + + LastAnimationTime = os::Timer::getTime(); + + firstUpdate = false; + } + + // get time. only operate on valid camera + f32 timeDiff = 0.f; + + if ( camIsMe ) + { + timeDiff = (f32) ( timeMs - LastAnimationTime ); + LastAnimationTime = timeMs; + } + + + // update position + core::vector3df pos = getPosition(); + + // Update rotation +// if (InputReceiverEnabled) + { + Target.set(0,0,1); + + + if (CursorControl && InputReceiverEnabled && camIsMe ) + { + core::position2d cursorpos = CursorControl->getRelativePosition(); + + if (!core::equals(cursorpos.X, CenterCursor.X) || + !core::equals(cursorpos.Y, CenterCursor.Y)) + { + RelativeRotation.X *= -1.0f; + RelativeRotation.Y *= -1.0f; + + RelativeRotation.Y += (0.5f - cursorpos.X) * RotateSpeed; + RelativeRotation.X = core::clamp ( RelativeRotation.X + (0.5f - cursorpos.Y) * RotateSpeed, + -MAX_VERTICAL_ANGLE, + +MAX_VERTICAL_ANGLE + ); + + RelativeRotation.X *= -1.0f; + RelativeRotation.Y *= -1.0f; + + CursorControl->setPosition(0.5f, 0.5f); + CenterCursor = CursorControl->getRelativePosition(); + } + } + + // set target + + core::matrix4 mat; + mat.setRotationDegrees(core::vector3df( RelativeRotation.X, RelativeRotation.Y, 0)); + mat.transformVect(Target); + + core::vector3df movedir = Target; + + if (NoVerticalMovement) + movedir.Y = 0.f; + + movedir.normalize(); + + if (InputReceiverEnabled && camIsMe) + { + if (CursorKeys[0]) + pos += movedir * timeDiff * MoveSpeed; + + if (CursorKeys[1]) + pos -= movedir * timeDiff * MoveSpeed; + + // strafing + + core::vector3df strafevect = Target; + strafevect = strafevect.crossProduct(UpVector); + + if (NoVerticalMovement) + strafevect.Y = 0.0f; + + strafevect.normalize(); + + if (CursorKeys[2]) + pos += strafevect * timeDiff * MoveSpeed; + + if (CursorKeys[3]) + pos -= strafevect * timeDiff * MoveSpeed; + + // jumping ( need's a gravity , else it's a fly to the World-UpVector ) + if (CursorKeys[4]) + { + pos += UpVector * timeDiff * JumpSpeed; + } + } + + // write translation + + setPosition(pos); + } + + // write right target + + TargetVector = Target; + Target += pos; + +} + +void CCameraFPSSceneNode::allKeysUp() +{ + for (s32 i=0; i<6; ++i) + CursorKeys[i] = false; +} + + +//! sets the look at target of the camera +//! \param pos: Look at target of the camera. +void CCameraFPSSceneNode::setTarget(const core::vector3df& tgt) +{ + updateAbsolutePosition(); + core::vector3df vect = tgt - getAbsolutePosition(); + vect = vect.getHorizontalAngle(); + RelativeRotation.X = vect.X; + RelativeRotation.Y = vect.Y; + + if (RelativeRotation.X > MAX_VERTICAL_ANGLE) + RelativeRotation.X -= 360.0f; +} + +//! Disables or enables the camera to get key or mouse inputs. +void CCameraFPSSceneNode::setInputReceiverEnabled(bool enabled) +{ + // So we don't skip when we return from a non-enabled mode and the + // mouse cursor is now not in the middle of the screen + if( !InputReceiverEnabled && enabled ) + firstUpdate = true; + + InputReceiverEnabled = enabled; +} + +//! Sets the rotation speed +void CCameraFPSSceneNode::setRotateSpeed(const f32 speed) +{ + RotateSpeed = speed; +} + +//! Sets the movement speed +void CCameraFPSSceneNode::setMoveSpeed(const f32 speed) +{ + MoveSpeed = speed; +} + +//! Gets the rotation speed +f32 CCameraFPSSceneNode::getRotateSpeed() +{ + return RotateSpeed; +} + +// Gets the movement speed +f32 CCameraFPSSceneNode::getMoveSpeed() +{ + return MoveSpeed; +} + +} // end namespace +} // end namespace + diff --git a/src/dep/src/irrlicht/CCameraFPSSceneNode.h b/src/dep/src/irrlicht/CCameraFPSSceneNode.h new file mode 100644 index 0000000..5bd3df7 --- /dev/null +++ b/src/dep/src/irrlicht/CCameraFPSSceneNode.h @@ -0,0 +1,104 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CAMERA_FPS_SCENE_NODE_H_INCLUDED__ +#define __C_CAMERA_FPS_SCENE_NODE_H_INCLUDED__ + +#include "ICursorControl.h" +#include "CCameraSceneNode.h" +#include "vector2d.h" +#include "SKeyMap.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + + class CCameraFPSSceneNode : public CCameraSceneNode + { + public: + + //! constructor + CCameraFPSSceneNode(ISceneNode* parent, ISceneManager* mgr, + gui::ICursorControl* cursorControl, s32 id, + f32 rotateSpeed, f32 moveSpeed,f32 jumpSpeed, + SKeyMap* keyMapArray, s32 keyMapSize, bool noVerticalMovement = false ); + + //! destructor + virtual ~CCameraFPSSceneNode(); + + //! It is possible to send mouse and key events to the camera. Most cameras + //! may ignore this input, but camera scene nodes which are created for + //! example with scene::ISceneManager::addMayaCameraSceneNode or + //! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input + //! for changing their position, look at target or whatever. + virtual bool OnEvent(const SEvent& event); + + //! OnAnimate() is called just before rendering the whole scene. + //! nodes may calculate or store animations here, and may do other useful things, + //! dependent on what they are. + virtual void OnAnimate(u32 timeMs); + + //! sets the look at target of the camera + //! \param pos: Look at target of the camera. + virtual void setTarget(const core::vector3df& pos); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA_FPS; } + + //! Disables or enables the camera to get key or mouse inputs. + //! If this is set to true, the camera will respond to key inputs + //! otherwise not. + virtual void setInputReceiverEnabled(bool enabled); + + //! Sets the speed that this camera rotates + virtual void setRotateSpeed(const f32 speed); + + //! Sets the speed that this camera moves + virtual void setMoveSpeed(const f32 speed); + + //! Gets the rotation speed + virtual f32 getRotateSpeed(); + + // Gets the movement speed + virtual f32 getMoveSpeed(); + + private: + + struct SCamKeyMap + { + SCamKeyMap() {}; + SCamKeyMap(s32 a, EKEY_CODE k) : action(a), keycode(k) {} + + s32 action; + EKEY_CODE keycode; + }; + + void allKeysUp(); + void animate( u32 timeMs ); + + bool CursorKeys[6]; + + gui::ICursorControl* CursorControl; + + f32 MoveSpeed; + f32 RotateSpeed; + f32 JumpSpeed; + + bool firstUpdate; + s32 LastAnimationTime; + + core::vector3df TargetVector; + core::array KeyMap; + core::position2d CenterCursor; + + bool NoVerticalMovement; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CCameraMayaSceneNode.cpp b/src/dep/src/irrlicht/CCameraMayaSceneNode.cpp new file mode 100644 index 0000000..28760d5 --- /dev/null +++ b/src/dep/src/irrlicht/CCameraMayaSceneNode.cpp @@ -0,0 +1,329 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCameraMayaSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CCameraMayaSceneNode::CCameraMayaSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + f32 rs, f32 zs, f32 ts) +: CCameraSceneNode(parent, mgr, id), + Zooming(false), Rotating(false), Moving(false), Translating(false), + ZoomSpeed(zs), RotateSpeed(rs), TranslateSpeed(ts), + RotateStartX(0.0f), RotateStartY(0.0f), ZoomStartX(0.0f), ZoomStartY(0.0f), + TranslateStartX(0.0f), TranslateStartY(0.0f), CurrentZoom(70.0f), RotX(0.0f), RotY(0.0f) +{ + #ifdef _DEBUG + setDebugName("CCameraMayaSceneNode"); + #endif + + Target.set(0.0f, 0.0f, 0.0f); + OldTarget = Target; + + allKeysUp(); + recalculateViewArea(); +} + + +//! destructor +CCameraMayaSceneNode::~CCameraMayaSceneNode() +{ +} + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CCameraMayaSceneNode::OnEvent(const SEvent& event) +{ + if (event.EventType != EET_MOUSE_INPUT_EVENT || + !InputReceiverEnabled) + return false; + + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + MouseKeys[0] = true; + break; + case EMIE_RMOUSE_PRESSED_DOWN: + MouseKeys[2] = true; + break; + case EMIE_MMOUSE_PRESSED_DOWN: + MouseKeys[1] = true; + break; + case EMIE_LMOUSE_LEFT_UP: + MouseKeys[0] = false; + break; + case EMIE_RMOUSE_LEFT_UP: + MouseKeys[2] = false; + break; + case EMIE_MMOUSE_LEFT_UP: + MouseKeys[1] = false; + break; + case EMIE_MOUSE_MOVED: + { + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if (driver) + { + core::dimension2d ssize = SceneManager->getVideoDriver()->getScreenSize(); + MousePos.X = event.MouseInput.X / (f32)ssize.Width; + MousePos.Y = event.MouseInput.Y / (f32)ssize.Height; + } + } + break; + case EMIE_MOUSE_WHEEL: + case EMIE_COUNT: + break; + } + return true; +} + +//! OnAnimate() is called just before rendering the whole scene. +//! nodes may calculate or store animations here, and may do other useful things, +//! dependent on what they are. +void CCameraMayaSceneNode::OnAnimate(u32 timeMs) +{ + animate(); + + ISceneNode::setPosition(Pos); + updateAbsolutePosition(); + + // This scene node cannot be animated by scene node animators, so + // don't invoke them. +} + + +bool CCameraMayaSceneNode::isMouseKeyDown(s32 key) +{ + return MouseKeys[key]; +} + + + +void CCameraMayaSceneNode::animate() +{ + //Alt + LM = Rotate around camera pivot + //Alt + LM + MM = Dolly forth/back in view direction (speed % distance camera pivot - max distance to pivot) + //Alt + MM = Move on camera plane (Screen center is about the mouse pointer, depending on move speed) + + const SViewFrustum* va = getViewFrustum(); + + f32 nRotX = RotX; + f32 nRotY = RotY; + f32 nZoom = CurrentZoom; + + if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) ) + { + if (!Zooming) + { + ZoomStartX = MousePos.X; + ZoomStartY = MousePos.Y; + Zooming = true; + nZoom = CurrentZoom; + } + else + { + f32 old = nZoom; + nZoom += (ZoomStartX - MousePos.X) * ZoomSpeed; + + f32 targetMinDistance = 0.1f; + if (nZoom < targetMinDistance) // jox: fixed bug: bounce back when zooming to close + nZoom = targetMinDistance; + + if (nZoom < 0) + nZoom = old; + } + } + else + { + if (Zooming) + { + f32 old = CurrentZoom; + CurrentZoom = CurrentZoom + (ZoomStartX - MousePos.X ) * ZoomSpeed; + nZoom = CurrentZoom; + + if (nZoom < 0) + nZoom = CurrentZoom = old; + } + + Zooming = false; + } + + // Translation --------------------------------- + + core::vector3df translate(OldTarget); + + core::vector3df tvectX = Pos - Target; + tvectX = tvectX.crossProduct(UpVector); + tvectX.normalize(); + + core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown()); + tvectY = tvectY.crossProduct(UpVector.Y > 0 ? Pos - Target : Target - Pos); + tvectY.normalize(); + + + if (isMouseKeyDown(2) && !Zooming) + { + if (!Translating) + { + TranslateStartX = MousePos.X; + TranslateStartY = MousePos.Y; + Translating = true; + } + else + { + translate += tvectX * (TranslateStartX - MousePos.X)*TranslateSpeed + + tvectY * (TranslateStartY - MousePos.Y)*TranslateSpeed; + } + } + else + { + if (Translating) + { + translate += tvectX * (TranslateStartX - MousePos.X)*TranslateSpeed + + tvectY * (TranslateStartY - MousePos.Y)*TranslateSpeed; + OldTarget = translate; + } + + Translating = false; + } + + // Rotation ------------------------------------ + + if (isMouseKeyDown(0) && !Zooming) + { + if (!Rotating) + { + RotateStartX = MousePos.X; + RotateStartY = MousePos.Y; + Rotating = true; + nRotX = RotX; + nRotY = RotY; + } + else + { + nRotX += (RotateStartX - MousePos.X) * RotateSpeed; + nRotY += (RotateStartY - MousePos.Y) * RotateSpeed; + } + } + else + { + if (Rotating) + { + RotX = RotX + (RotateStartX - MousePos.X) * RotateSpeed; + RotY = RotY + (RotateStartY - MousePos.Y) * RotateSpeed; + nRotX = RotX; + nRotY = RotY; + } + + Rotating = false; + } + + // Set Pos ------------------------------------ + + Target = translate; + + Pos.X = nZoom + Target.X; + Pos.Y = Target.Y; + Pos.Z = Target.Z; + + Pos.rotateXYBy(nRotY, Target); + Pos.rotateXZBy(-nRotX, Target); + + // Rotation Error ---------------------------- + + // jox: fixed bug: jitter when rotating to the top and bottom of y + UpVector.set(0,1,0); + UpVector.rotateXYBy(-nRotY, core::vector3df(0,0,0)); + UpVector.rotateXZBy(-nRotX+180.f, core::vector3df(0,0,0)); + + /*if (nRotY < 0.0f) + nRotY *= -1.0f; + + nRotY = (f32)fmod(nRotY, 360.0f); + + + if (nRotY >= 90.0f && nRotY <= 270.0f) + UpVector.set(0, -1, 0); + else + UpVector.set(0, 1, 0);*/ +} + + +void CCameraMayaSceneNode::allKeysUp() +{ + for (s32 i=0; i<3; ++i) + MouseKeys[i] = false; +} + +// function added by jox: fix setPosition() +void CCameraMayaSceneNode::setPosition(const core::vector3df& pos) +{ + Pos = pos; + updateAnimationState(); + + ISceneNode::setPosition(pos); +} + +// function added by jox: fix setTarget() +void CCameraMayaSceneNode::setTarget(const core::vector3df& pos) +{ + Target = OldTarget = pos; + updateAnimationState(); +} + + +// function added by jox +void CCameraMayaSceneNode::updateAnimationState() +{ + core::vector3df pos(Pos - Target); + + // X rotation + core::vector2df vec2d(pos.X, pos.Z); + RotX = (f32)vec2d.getAngle(); + + // Y rotation + pos.rotateXZBy(RotX, core::vector3df()); + vec2d.set(pos.X, pos.Y); + RotY = -(f32)vec2d.getAngle(); + + // Zoom + CurrentZoom = (f32)Pos.getDistanceFrom(Target); +} + +//! Sets the rotation speed +void CCameraMayaSceneNode::setRotateSpeed(const f32 speed) +{ + RotateSpeed = speed; +} + +//! Sets the movement speed +void CCameraMayaSceneNode::setMoveSpeed(const f32 speed) +{ + TranslateSpeed = speed; +} + +//! Gets the rotation speed +f32 CCameraMayaSceneNode::getRotateSpeed() +{ + return RotateSpeed; +} + +// Gets the movement speed +f32 CCameraMayaSceneNode::getMoveSpeed() +{ + return TranslateSpeed; +} + +} // end namespace +} // end namespace + diff --git a/src/dep/src/irrlicht/CCameraMayaSceneNode.h b/src/dep/src/irrlicht/CCameraMayaSceneNode.h new file mode 100644 index 0000000..88c50d2 --- /dev/null +++ b/src/dep/src/irrlicht/CCameraMayaSceneNode.h @@ -0,0 +1,90 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CAMERA_MAYA_SCENE_NODE_H_INCLUDED__ +#define __C_CAMERA_MAYA_SCENE_NODE_H_INCLUDED__ + +#include "CCameraSceneNode.h" +#include "vector2d.h" + +namespace irr +{ +namespace scene +{ + + class CCameraMayaSceneNode : public CCameraSceneNode + { + public: + + //! constructor + CCameraMayaSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f, f32 translationSpeed = 100.0f); + + //! destructor + virtual ~CCameraMayaSceneNode(); + + //! It is possible to send mouse and key events to the camera. Most cameras + //! may ignore this input, but camera scene nodes which are created for + //! example with scene::ISceneManager::addMayaCameraSceneNode or + //! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input + //! for changing their position, look at target or whatever. + virtual bool OnEvent(const SEvent& event); + + //! OnAnimate() is called just before rendering the whole scene. + //! nodes may calculate or store animations here, and may do other useful things, + //! dependent on what they are. + virtual void OnAnimate(u32 timeMs); + + //! Sets the position of the node. Note that the position is + //! relative to the parent. + virtual void setPosition(const core::vector3df& newpos); + + //! Sets the position of the node. Note that the position is + //! relative to the parent. + virtual void setTarget(const core::vector3df& newpos); + + //! Sets the rotation speed + virtual void setRotateSpeed(const f32 speed); + + //! Sets the movement speed + virtual void setMoveSpeed(const f32 speed); + + //! Gets the rotation speed + virtual f32 getRotateSpeed(); + + // Gets the movement speed + virtual f32 getMoveSpeed(); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA_MAYA; } + + private: + + void allKeysUp(); + void animate(); + bool isMouseKeyDown(s32 key); + void updateAnimationState(); + + bool MouseKeys[3]; + + core::vector3df Pos; + bool Zooming, Rotating, Moving, Translating; + f32 ZoomSpeed; + f32 RotateSpeed; + f32 TranslateSpeed; + f32 RotateStartX, RotateStartY; + f32 ZoomStartX, ZoomStartY; + f32 TranslateStartX, TranslateStartY; + f32 CurrentZoom; + f32 RotX, RotY; + core::vector3df OldTarget; + + core::vector2df MousePos; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CCameraSceneNode.cpp b/src/dep/src/irrlicht/CCameraSceneNode.cpp new file mode 100644 index 0000000..84e70cc --- /dev/null +++ b/src/dep/src/irrlicht/CCameraSceneNode.cpp @@ -0,0 +1,309 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCameraSceneNode.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& lookat) + : ICameraSceneNode(parent, mgr, id, position, core::vector3df(0.0f, 0.0f, 0.0f), + core::vector3df(1.0f, 1.0f, 1.0f)), InputReceiverEnabled(true) +{ + #ifdef _DEBUG + setDebugName("CCameraSceneNode"); + #endif + + // set default view + + UpVector.set(0.0f, 1.0f, 0.0f); + Target.set(lookat); + + // set default projection + + Fovy = core::PI / 2.5f; // Field of view, in radians. + Aspect = 4.0f / 3.0f; // Aspect ratio. + ZNear = 1.0f; // value of the near view-plane. + ZFar = 3000.0f; // Z-value of the far view-plane. + + video::IVideoDriver* d = mgr->getVideoDriver(); + if (d) + Aspect = (f32)d->getCurrentRenderTargetSize().Width / + (f32)d->getCurrentRenderTargetSize().Height; + + recalculateProjectionMatrix(); + recalculateViewArea(); +} + + + +//! destructor +CCameraSceneNode::~CCameraSceneNode() +{ +} + + +//! Disables or enables the camera to get key or mouse inputs. +void CCameraSceneNode::setInputReceiverEnabled(bool enabled) +{ + InputReceiverEnabled = enabled; +} + + +//! Returns if the input receiver of the camera is currently enabled. +bool CCameraSceneNode::isInputReceiverEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return InputReceiverEnabled; +} + + +//! Sets the projection matrix of the camera. The core::matrix4 class has some methods +//! to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH +//! \param projection: The new projection matrix of the camera. +void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection) +{ + ViewArea.Matrices [ video::ETS_PROJECTION ] = projection; + ViewArea.setTransformState ( video::ETS_PROJECTION ); +} + + + +//! Gets the current projection matrix of the camera +//! \return Returns the current projection matrix of the camera. +const core::matrix4& CCameraSceneNode::getProjectionMatrix() const +{ + return ViewArea.Matrices [ video::ETS_PROJECTION ]; +} + + + +//! Gets the current view matrix of the camera +//! \return Returns the current view matrix of the camera. +const core::matrix4& CCameraSceneNode::getViewMatrix() const +{ + return ViewArea.Matrices [ video::ETS_VIEW ]; +} + + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CCameraSceneNode::OnEvent(const SEvent& event) +{ + return false; +} + + + +//! sets the look at target of the camera +//! \param pos: Look at target of the camera. +void CCameraSceneNode::setTarget(const core::vector3df& pos) +{ + Target = pos; +} + + + +//! Gets the current look at target of the camera +//! \return Returns the current look at target of the camera +core::vector3df CCameraSceneNode::getTarget() const +{ + return Target; +} + + + +//! sets the up vector of the camera +//! \param pos: New upvector of the camera. +void CCameraSceneNode::setUpVector(const core::vector3df& pos) +{ + UpVector = pos; +} + + + +//! Gets the up vector of the camera. +//! \return Returns the up vector of the camera. +core::vector3df CCameraSceneNode::getUpVector() const +{ + return UpVector; +} + + +f32 CCameraSceneNode::getNearValue() const +{ + return ZNear; +} + +f32 CCameraSceneNode::getFarValue() const +{ + return ZFar; +} + +f32 CCameraSceneNode::getAspectRatio() const +{ + return Aspect; +} + +f32 CCameraSceneNode::getFOV() const +{ + return Fovy; +} + +void CCameraSceneNode::setNearValue(f32 f) +{ + ZNear = f; + recalculateProjectionMatrix(); +} + +void CCameraSceneNode::setFarValue(f32 f) +{ + ZFar = f; + recalculateProjectionMatrix(); +} + +void CCameraSceneNode::setAspectRatio(f32 f) +{ + Aspect = f; + recalculateProjectionMatrix(); +} + +void CCameraSceneNode::setFOV(f32 f) +{ + Fovy = f; + recalculateProjectionMatrix(); +} + +void CCameraSceneNode::recalculateProjectionMatrix() +{ + ViewArea.Matrices [ video::ETS_PROJECTION ].buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar); + ViewArea.setTransformState ( video::ETS_PROJECTION ); +} + + +//! prerender +void CCameraSceneNode::OnRegisterSceneNode() +{ + // if upvector and vector to the target are the same, we have a + // problem. so solve this problem: + + core::vector3df pos = getAbsolutePosition(); + core::vector3df tgtv = Target - pos; + tgtv.normalize(); + + core::vector3df up = UpVector; + up.normalize(); + + f32 dp = tgtv.dotProduct(up); + + if ( core::equals ( fabs ( dp ), 1.f ) ) + { + up.X += 0.5f; + } + + ViewArea.Matrices [ video::ETS_VIEW ].buildCameraLookAtMatrixLH(pos, Target, up); + ViewArea.setTransformState ( video::ETS_VIEW ); + recalculateViewArea(); + + if ( SceneManager->getActiveCamera () == this ) + SceneManager->registerNodeForRendering(this, ESNRP_CAMERA); + + if (IsVisible) + ISceneNode::OnRegisterSceneNode(); +} + + + +//! render +void CCameraSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if ( driver) + { + driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices [ video::ETS_PROJECTION ] ); + driver->setTransform(video::ETS_VIEW, ViewArea.Matrices [ video::ETS_VIEW ] ); + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CCameraSceneNode::getBoundingBox() const +{ + return ViewArea.getBoundingBox(); +} + + + +//! returns the view frustum. needed sometimes by bsp or lod render nodes. +const SViewFrustum* CCameraSceneNode::getViewFrustum() const +{ + return &ViewArea; +} + +core::vector3df CCameraSceneNode::getAbsolutePosition() const +{ + return AbsoluteTransformation.getTranslation(); +} + +void CCameraSceneNode::recalculateViewArea() +{ + ViewArea.cameraPosition = getAbsolutePosition(); + ViewArea.setFrom ( ViewArea.Matrices [ SViewFrustum::ETS_VIEW_PROJECTION_3 ] ); +/* + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if ( driver) + { + driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices [ video::ETS_PROJECTION ] ); + driver->setTransform(video::ETS_VIEW, ViewArea.Matrices [ video::ETS_VIEW ] ); + } +*/ +} + + +//! Writes attributes of the scene node. +void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addVector3d("Target", Target); + out->addVector3d("UpVector", UpVector); + out->addFloat("Fovy", Fovy); + out->addFloat("Aspect", Aspect); + out->addFloat("ZNear", ZNear); + out->addFloat("ZFar", ZFar); +} + + +//! Reads attributes of the scene node. +void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + ISceneNode::deserializeAttributes(in, options); + + Target = in->getAttributeAsVector3d("Target"); + UpVector = in->getAttributeAsVector3d("UpVector"); + Fovy = in->getAttributeAsFloat("Fovy"); + Aspect = in->getAttributeAsFloat("Aspect"); + ZNear = in->getAttributeAsFloat("ZNear"); + ZFar = in->getAttributeAsFloat("ZFar"); + + recalculateProjectionMatrix(); + recalculateViewArea(); +} + + +} // end namespace +} // end namespace + diff --git a/src/dep/src/irrlicht/CCameraSceneNode.h b/src/dep/src/irrlicht/CCameraSceneNode.h new file mode 100644 index 0000000..e280abb --- /dev/null +++ b/src/dep/src/irrlicht/CCameraSceneNode.h @@ -0,0 +1,145 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CAMERA_SCENE_NODE_H_INCLUDED__ +#define __C_CAMERA_SCENE_NODE_H_INCLUDED__ + +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" + +namespace irr +{ +namespace scene +{ + + class CCameraSceneNode : public ICameraSceneNode + { + public: + + //! constructor + CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,100)); + + //! destructor + virtual ~CCameraSceneNode(); + + //! Sets the projection matrix of the camera. The core::matrix4 class has some methods + //! to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH + //! \param projection: The new projection matrix of the camera. + virtual void setProjectionMatrix(const core::matrix4& projection); + + //! Gets the current projection matrix of the camera + //! \return Returns the current projection matrix of the camera. + virtual const core::matrix4& getProjectionMatrix() const; + + //! Gets the current view matrix of the camera + //! \return Returns the current view matrix of the camera. + virtual const core::matrix4& getViewMatrix() const; + + //! It is possible to send mouse and key events to the camera. Most cameras + //! may ignore this input, but camera scene nodes which are created for + //! example with scene::ISceneManager::addMayaCameraSceneNode or + //! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input + //! for changing their position, look at target or whatever. + virtual bool OnEvent(const SEvent& event); + + //! sets the look at target of the camera + //! \param pos: Look at target of the camera. + virtual void setTarget(const core::vector3df& pos); + + //! Gets the current look at target of the camera + //! \return Returns the current look at target of the camera + virtual core::vector3df getTarget() const; + + //! Sets the up vector of the camera. + //! \param pos: New upvector of the camera. + virtual void setUpVector(const core::vector3df& pos); + + //! Gets the up vector of the camera. + //! \return Returns the up vector of the camera. + virtual core::vector3df getUpVector() const; + + //! Gets distance from the camera to the near plane. + //! \return Value of the near plane of the camera. + virtual f32 getNearValue() const; + + //! Gets the distance from the camera to the far plane. + //! \return Value of the far plane of the camera. + virtual f32 getFarValue() const; + + //! Get the aspect ratio of the camera. + //! \return The aspect ratio of the camera. + virtual f32 getAspectRatio() const; + + //! Gets the field of view of the camera. + //! \return Field of view of the camera + virtual f32 getFOV() const; + + //! Sets the value of the near clipping plane. (default: 1.0f) + virtual void setNearValue(f32 zn); + + //! Sets the value of the far clipping plane (default: 2000.0f) + virtual void setFarValue(f32 zf); + + //! Sets the aspect ratio (default: 4.0f / 3.0f) + virtual void setAspectRatio(f32 aspect); + + //! Sets the field of view (Default: PI / 3.5f) + virtual void setFOV(f32 fovy); + + //! PreRender event + virtual void OnRegisterSceneNode(); + + //! Render + virtual void render(); + + //! Returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns the view area. Sometimes needed by bsp or lod render nodes. + virtual const SViewFrustum* getViewFrustum() const; + + //! Disables or enables the camera to get key or mouse inputs. + //! If this is set to true, the camera will respond to key inputs + //! otherwise not. + virtual void setInputReceiverEnabled(bool enabled); + + //! Returns if the input receiver of the camera is currently enabled. + virtual bool isInputReceiverEnabled() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; } + + virtual core::vector3df getAbsolutePosition() const; + + protected: + + void recalculateProjectionMatrix(); + void recalculateViewArea(); + + core::vector3df Target; + core::vector3df UpVector; + + f32 Fovy; // Field of view, in radians. + f32 Aspect; // Aspect ratio. + f32 ZNear; // value of the near view-plane. + f32 ZFar; // Z-value of the far view-plane. + + SViewFrustum ViewArea; + + bool InputReceiverEnabled; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CColladaFileLoader.cpp b/src/dep/src/irrlicht/CColladaFileLoader.cpp new file mode 100644 index 0000000..3e6c700 --- /dev/null +++ b/src/dep/src/irrlicht/CColladaFileLoader.cpp @@ -0,0 +1,1571 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ + +#include "CColladaFileLoader.h" +#include "os.h" +#include "IXMLReader.h" +#include "IDummyTransformationSceneNode.h" +#include "SAnimatedMesh.h" +#include "fast_atof.h" +#include "quaternion.h" +#include "ILightSceneNode.h" +#include "ICameraSceneNode.h" +#include "IMeshManipulator.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "IMeshCache.h" +#include "IMeshSceneNode.h" +#include "SMeshBufferLightMap.h" + +//#define COLLADA_READER_DEBUG +namespace irr +{ +namespace scene +{ + // currently supported COLLADA tag names + + const core::stringc colladaSectionName = "COLLADA"; + const core::stringc librarySectionName = "library"; + const core::stringc assetSectionName = "asset"; + const core::stringc sceneSectionName = "scene"; + + const core::stringc lightPrefabName = "light"; + const core::stringc cameraPrefabName = "camera"; + const core::stringc materialSectionName = "material"; + const core::stringc geometrySectionName = "geometry"; + const core::stringc imageSectionName = "image"; + const core::stringc textureSectionName = "texture"; + + const core::stringc meshSectionName = "mesh"; + const core::stringc sourceSectionName = "source"; + const core::stringc arraySectionName = "array"; + const core::stringc accessorSectionName = "accessor"; + const core::stringc verticesSectionName = "vertices"; + const core::stringc inputTagName = "input"; + const core::stringc polygonsSectionName = "polygons"; + const core::stringc polygonName = "p"; + const core::stringc nodeSectionName = "node"; + const core::stringc lookatNodeName = "lookat"; + const core::stringc matrixNodeName = "matrix"; + const core::stringc perspectiveNodeName = "perspective"; + const core::stringc rotateNodeName = "rotate"; + const core::stringc scaleNodeName = "scale"; + const core::stringc translateNodeName = "translate"; + const core::stringc skewNodeName = "skew"; + const core::stringc instanceNodeName = "instance"; + + const core::stringc paramTagName = "param"; + + const char* const inputSemanticNames[] = {"POSITION", "VERTEX", "NORMAL", "TEXCOORD", + "UV", "TANGENT", "IMAGE", "TEXTURE", 0}; + + //! following class is for holding and creating instances of library objects, + //! named prefabs in this loader. + class CPrefab : public IColladaPrefab + { + public: + + CPrefab(const char* id) + { + Id = id; + } + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + // empty implementation + return 0; + } + + //! returns id of this prefab + virtual const c8* getId() + { + return Id.c_str(); + } + + protected: + + core::stringc Id; + }; + + + //! prefab for a light scene node + class CLightPrefab : public CPrefab + { + public: + + CLightPrefab(const char* id) : CPrefab(id) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: loaded light prefab:", Id.c_str()); + #endif + } + + video::SLight LightData; // publically accessible + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing light instance:", Id.c_str()); + #endif + + scene::ILightSceneNode* l = mgr->addLightSceneNode(parent); + l->setLightData ( LightData ); + return l; + } + }; + + + //! prefab for a mesh scene node + class CGeometryPrefab : public CPrefab + { + public: + + CGeometryPrefab(const char* id) : CPrefab(id) + { + } + + scene::IMesh* Mesh; // public accessible + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing mesh instance:", Id.c_str()); + #endif + + scene::ISceneNode* m = mgr->addMeshSceneNode(Mesh, parent); + return m; + } + }; + + + //! prefab for a camera scene node + class CCameraPrefab : public CPrefab + { + public: + + CCameraPrefab(const char* id) + : CPrefab(id), YFov(core::PI / 2.5f), ZNear(1.0f), ZFar(3000.0f) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: loaded camera prefab:", Id.c_str()); + #endif + } + + // public accessible data + f32 YFov; + f32 ZNear; + f32 ZFar; + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing camera instance:", Id.c_str()); + #endif + + scene::ICameraSceneNode* c = mgr->addCameraSceneNode(parent); + c->setFOV(YFov); + c->setNearValue(ZNear); + c->setFarValue(ZFar); + return c; + } + }; + +//! Constructor +CColladaFileLoader::CColladaFileLoader(video::IVideoDriver* driver, + scene::ISceneManager* smgr, io::IFileSystem* fs) +: Driver(driver), SceneManager(smgr), FileSystem(fs), DummyMesh(0), + FirstLoadedMesh(0), LoadedMeshCount(0), CreateInstances(false) +{ + +} + + +//! destructor +CColladaFileLoader::~CColladaFileLoader() +{ + if (DummyMesh) + DummyMesh->drop(); + + if (FirstLoadedMesh) + FirstLoadedMesh->drop(); +} + + +//! Returns true if the file maybe is able to be loaded by this class. +/** This decision should be based only on the file extension (e.g. ".cob") */ +bool CColladaFileLoader::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".xml") || + strstr(fileName, ".dae"); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CColladaFileLoader::createMesh(io::IReadFile* file) +{ + io::IXMLReaderUTF8* reader = FileSystem->createXMLReaderUTF8(file); + if (!reader) + return 0; + + CurrentlyLoadingMesh = file->getFileName(); + CreateInstances = SceneManager->getParameters()->getAttributeAsBool( + scene::COLLADA_CREATE_SCENE_INSTANCES); + + // read until COLLADA section, skip other parts + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (colladaSectionName == reader->getNodeName()) + readColladaSection(reader); + else + skipSection(reader, true); // unknown section + } + } + + reader->drop(); + + scene::IAnimatedMesh* returnMesh = DummyMesh; + + // because this loader loads and creates a complete scene instead of + // a single mesh, return an empty dummy mesh to make the scene manager + // know that everything went well. + if (!DummyMesh) + { + DummyMesh = new SAnimatedMesh(); + returnMesh = DummyMesh; + } + + // add the first loaded mesh into the mesh cache too, if more than one + // meshes have been loaded from the file + if (LoadedMeshCount>1 && FirstLoadedMesh) + { + os::Printer::log("Added COLLADA mesh", FirstLoadedMeshName.c_str()); + SceneManager->getMeshCache()->addMesh(FirstLoadedMeshName.c_str(), FirstLoadedMesh); + } + + // clean up temporary loaded data + clearData(); + + returnMesh->grab(); // store until this loader is destroyed + + DummyMesh->drop(); + DummyMesh = 0; + + if (FirstLoadedMesh) + FirstLoadedMesh->drop(); + FirstLoadedMesh = 0; + LoadedMeshCount = 0; + + return returnMesh; +} + + + +//! skips an (unknown) section in the collada document +void CColladaFileLoader::skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping) +{ + #ifndef COLLADA_READER_DEBUG + if (reportSkipping) // always report in COLLADA_READER_DEBUG mode + #endif + os::Printer::log("COLLADA skipping section", core::stringc(reader->getNodeName()).c_str()); + + // skip if this element is empty anyway. + if (reader->isEmptyElement()) + return; + + // read until we've reached the last element in this section + u32 tagCounter = 1; + + while(tagCounter && reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + !reader->isEmptyElement()) + { + #ifdef COLLADA_READER_DEBUG + if (reportSkipping) + os::Printer::log("COLLADA unknown element:", core::stringc(reader->getNodeName()).c_str()); + #endif // COLLADA_READER_DEBUG + + ++tagCounter; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + --tagCounter; + } +} + + +//! reads the section and its content +void CColladaFileLoader::readColladaSection(io::IXMLReaderUTF8* reader) +{ + if (reader->isEmptyElement()) + return; + + // I ignore version information here. Keep on reading content: + + while(reader->read()) + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (librarySectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (assetSectionName == reader->getNodeName()) + readAssetSection(reader); + else + if (sceneSectionName == reader->getNodeName()) + readSceneSection(reader); + else + skipSection(reader, true); // unknown section + } +} + + + +//! reads a section and its content +void CColladaFileLoader::readLibrarySection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading library"); + #endif + + while(reader->read()) + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (lightPrefabName == reader->getNodeName()) + readLightPrefab(reader); + else + if (imageSectionName == reader->getNodeName()) + readImage(reader); + else + if (textureSectionName == reader->getNodeName()) + readTexture(reader); + else + if (materialSectionName == reader->getNodeName()) + readMaterial(reader); + else + if (cameraPrefabName == reader->getNodeName()) + readCameraPrefab(reader); + else + if (geometrySectionName == reader->getNodeName()) + readGeometry(reader); + else + skipSection(reader, true); // unknown section + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (librarySectionName == reader->getNodeName()) + break; // end reading. + } +} + + +//! reads a section and its content +void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading scene"); + #endif + + if (reader->isEmptyElement()) + return; + + // read the scene + + while(reader->read()) + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (nodeSectionName == reader->getNodeName()) + readNodeSection(reader, SceneManager->getRootSceneNode()); + else + skipSection(reader, true); // ignore all other sections + } +} + + + +//! reads a section and its content +void CColladaFileLoader::readAssetSection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading asset"); + #endif + + // don't need asset data so far, so skip it + skipSection(reader, false); +} + + + +//! reads a section and its content +void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading node"); + #endif + + if (reader->isEmptyElement()) + return; + + core::stringc name = reader->getAttributeValue("name"); // name of the node + core::matrix4 transform; // transformation of this node + scene::ISceneNode* node = 0; // instance + + // read the node + + while(reader->read()) + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (lookatNodeName == reader->getNodeName()) + transform *= readLookAtNode(reader); + else + if (matrixNodeName == reader->getNodeName()) + transform *= readMatrixNode(reader); + else + if (perspectiveNodeName == reader->getNodeName()) + transform *= readPerspectiveNode(reader); + else + if (rotateNodeName == reader->getNodeName()) + transform *= readRotateNode(reader); + else + if (scaleNodeName == reader->getNodeName()) + transform *= readScaleNode(reader); + else + if (translateNodeName == reader->getNodeName()) + transform *= readTranslateNode(reader); + else + if (skewNodeName == reader->getNodeName()) + transform *= readSkewNode(reader); + else + if (instanceNodeName == reader->getNodeName()) + { + scene::ISceneNode* newnode = 0; + readInstanceNode(reader, parent, &newnode); + + if (node && newnode) + { + // move children from dummy to new node + core::list::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); it = node->getChildren().begin()) + (*it)->setParent(newnode); + + // remove previous dummy node + node->remove(); + } + + node = newnode; + } + else + if (nodeSectionName == reader->getNodeName()) + { + // create dummy node if there is none yet. + if (!node) + { + scene::IDummyTransformationSceneNode* dummy = + SceneManager->addDummyTransformationSceneNode(parent); + dummy->getRelativeTransformationMatrix() = transform; + node = dummy; + } + + // read and add child + readNodeSection(reader, node); + } + else + skipSection(reader, true); // ignore all other sections + + } // end if node + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (nodeSectionName == reader->getNodeName()) + break; + } + + if (node) + { + // TODO: set transformation correctly into node. + // currently this isn't done correctly. Need to get transformation, + // rotation and scale from the matrix. + const core::vector3df& trans = transform.getTranslation(); + const core::vector3df& rot = transform.getRotationDegrees(); + + node->setPosition(trans); + node->setRotation(rot); + node->updateAbsolutePosition(); + + node->setName(name.c_str()); + } +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader) +{ + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading look at node"); + #endif + + f32 floats[9]; + readFloatsInsideElement(reader, floats, 9); + + mat.buildCameraLookAtMatrixLH( + core::vector3df(floats[0], floats[1], floats[2]), + core::vector3df(floats[3], floats[4], floats[5]), + core::vector3df(floats[6], floats[7], floats[8])); + + return mat; +} + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading skew node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[7]; + readFloatsInsideElement(reader, floats, 7); + + // TODO: build skew matrix from these 7 floats + + os::Printer::log("COLLADA loader warning: not implemented yet.", ELL_WARNING); + + return mat; +} + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading matrix node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + readFloatsInsideElement(reader, mat.pointer(), 16); + + return mat; +} + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading perspective node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[1]; + readFloatsInsideElement(reader, floats, 1); + + // TODO: build perspecitve matrix from this float + + os::Printer::log("COLLADA loader warning: not implemented yet.", ELL_WARNING); + + return mat; +} + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading rotate node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[4]; + readFloatsInsideElement(reader, floats, 4); + + core::quaternion q(floats[0], floats[1], floats[2], floats[3]); + return q.getMatrix(); +} + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading scale node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[3]; + readFloatsInsideElement(reader, floats, 3); + + mat.setScale(core::vector3df(floats[0], floats[1], floats[2])); + + return mat; +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading translate node"); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[3]; + readFloatsInsideElement(reader, floats, 3); + + mat.setTranslation(core::vector3df(floats[0], floats[1], floats[2])); + + return mat; +} + +//! reads a node and creates a scene node from it +void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, + scene::ISceneNode** outNode) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading instance"); + #endif + + // find prefab of the specified id + core::stringc url = reader->getAttributeValue("url"); + uriToId(url); + + if (CreateInstances) + for (u32 i=0; igetId()) + { + *outNode = Prefabs[i]->addInstance(parent, SceneManager); + if (*outNode) + (*outNode)->setName(reader->getAttributeValue("id")); + return; + } +} + +//! reads a element and stores it as prefab +void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading camera prefab"); + #endif + + CCameraPrefab* prefab = new CCameraPrefab(reader->getAttributeValue("id")); + + if (!reader->isEmptyElement()) + { + readColladaParameters(reader, cameraPrefabName); + + SColladaParam* p; + + p = getColladaParameter(ECPN_YFOV); + if (p && p->Type == ECPT_FLOAT) + prefab->YFov = p->Floats[0]; + + p = getColladaParameter(ECPN_ZNEAR); + if (p && p->Type == ECPT_FLOAT) + prefab->ZNear = p->Floats[0]; + + p = getColladaParameter(ECPN_ZFAR); + if (p && p->Type == ECPT_FLOAT) + prefab->ZFar = p->Floats[0]; + } + + Prefabs.push_back(prefab); +} + + +//! reads a element and stores it in the image section +void CColladaFileLoader::readImage(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading image"); + #endif + + SColladaImage image; + image.Id = reader->getAttributeValue("id"); + image.Filename = reader->getAttributeValue("source"); + + // add image to list of loaded images. + Images.push_back(image); +} + + +//! reads a element and stores it in the texture section +void CColladaFileLoader::readTexture(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading texture"); + #endif + + SColladaTexture texture; + texture.Id = reader->getAttributeValue("id"); + + if (!reader->isEmptyElement()) + { + readColladaInputs(reader, textureSectionName); + SColladaInput* input = getColladaInput(ECIS_IMAGE); + if (input) + { + core::stringc imageName = input->Source; + uriToId(imageName); + for (u32 i=0; igetTexture(Images[i].Filename.c_str()); + break; + } + } + } + + // add texture to list of loaded textures. + Textures.push_back(texture); +} + + +//! reads a element and stores it in the material section +void CColladaFileLoader::readMaterial(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading material"); + #endif + + SColladaMaterial material; + material.Id = reader->getAttributeValue("id"); + + if (!reader->isEmptyElement()) + { + readColladaInputs(reader, materialSectionName); + SColladaInput* input = getColladaInput(ECIS_TEXTURE); + if (input) + { + core::stringc textureName = input->Source; + uriToId(textureName); + for (u32 i=0; iType == ECPT_FLOAT3) + material.Mat.AmbientColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_DIFFUSE); + if (p && p->Type == ECPT_FLOAT3) + material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_SPECULAR); + if (p && p->Type == ECPT_FLOAT3) + material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_SHININESS); + if (p && p->Type == ECPT_FLOAT) + material.Mat.Shininess = p->Floats[0]; +#endif + } + + // add material to list of loaded materials. + Materials.push_back(material); +} + +//! reads a element and stores it as mesh if possible +void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading geometry"); + #endif + + core::stringc id = reader->getAttributeValue("id"); + + core::stringc VertexPositionSource; // each mesh has exactly one member, containing + // a POSITION input. This string stores the source of this input. + core::array sources; + bool okToReadArray = false; + + SAnimatedMesh* amesh = new SAnimatedMesh(); + scene::SMesh* mesh = new SMesh(); + amesh->addMesh(mesh); + + // read sources with arrays and accessor for each mesh + + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const char* nodeName = reader->getNodeName(); + if (meshSectionName == nodeName) + { + // inside a mesh section. Don't have to do anything here. + } + else + if (sourceSectionName == nodeName) + { + // create a new source + sources.push_back(SSource()); + sources.getLast().Id = reader->getAttributeValue("id"); + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Loaded source", sources.getLast().Id.c_str()); + #endif + } + else + if (arraySectionName == nodeName) + { + // create a new array and read it. + if (!sources.empty()) + { + sources.getLast().Array.Name = reader->getAttributeValue("id"); + + int count = reader->getAttributeValueAsInt("count"); + sources.getLast().Array.Data.set_used(count); // pre allocate + + // check if type of array is ok + const char* type = reader->getAttributeValue("type"); + okToReadArray = (!strcmp("float", type) || !strcmp("int", type)); + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Read array", sources.getLast().Array.Name.c_str()); + #endif + } + #ifdef COLLADA_READER_DEBUG + else + os::Printer::log("Warning, array found, but no source", + reader->getAttributeValue("id")); + #endif + + } + else + if (accessorSectionName == nodeName) + { + SAccessor accessor; + accessor.Count = reader->getAttributeValueAsInt("count"); + accessor.Offset = reader->getAttributeValueAsInt("offset"); + accessor.Stride = reader->getAttributeValueAsInt("stride"); + if (accessor.Stride == 0) + accessor.Stride = 1; + + // the accessor contains some information on how to access (boi!) the array, + // the info is stored in collada style parameters, so just read them. + readColladaParameters(reader, accessorSectionName); + if (!sources.empty()) + { + sources.getLast().Accessors.push_back(accessor); + sources.getLast().Accessors.getLast().Parameters = Parameters; + } + } + else + if (verticesSectionName == nodeName) + { + // read vertex input position source + readColladaInputs(reader, verticesSectionName); + SColladaInput* input = getColladaInput(ECIS_POSITION); + if (input) + VertexPositionSource = input->Source; + } + else + if (polygonsSectionName == nodeName) + { + // read polygons section + readPolygonSection(reader, VertexPositionSource, sources, mesh); + } + + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_TEXT) + { + // read array data + if (okToReadArray && !sources.empty()) + { + core::array& a = sources.getLast().Array.Data; + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + { + if (geometrySectionName == reader->getNodeName()) + { + // end of geometry section reached, cancel out + break; + } + } + } // end while reader->read(); + + // add mesh as geometry + + mesh->recalculateBoundingBox(); + + // create virtual file name + core::stringc filename = CurrentlyLoadingMesh; + filename += '#'; + filename += id; + + // add to scene manager + if (LoadedMeshCount) + { + SceneManager->getMeshCache()->addMesh(filename.c_str(), amesh); + os::Printer::log("Added COLLADA mesh", filename.c_str()); + } + else + { + FirstLoadedMeshName = filename; + FirstLoadedMesh = amesh; + FirstLoadedMesh->grab(); + } + + ++LoadedMeshCount; + mesh->drop(); + amesh->drop(); + + // create geometry prefab + CGeometryPrefab* prefab = new CGeometryPrefab(id.c_str()); + prefab->Mesh = mesh; + Prefabs.push_back(prefab); + + // store as dummy mesh if no instances will be created + if (!CreateInstances && !DummyMesh) + { + DummyMesh = amesh; + DummyMesh->grab(); + } +} + + +struct SInputSlot +{ + f32* Data; // Pointer to source data + ECOLLADA_INPUT_SEMANTIC Semantic; +}; + +struct SPolygon +{ + core::array Indices; +}; + +//! reads a polygons section and creates a mesh from it +void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader, + const core::stringc& vertexPositionSource, core::array& sources, + scene::SMesh* mesh) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading polygon section"); + #endif + + core::stringc materialName = reader->getAttributeValue("material"); + uriToId(materialName); + video::SMaterial mat; + + for (u32 matnum=0; matnumgetAttributeValueAsInt("count"); + core::array slots; + core::array polygons; + bool parsePolygonOK = false; + u32 inputSemanticCount = 0; + + // read all and + if (!reader->isEmptyElement()) + while(reader->read()) + { + const char* nodeName = reader->getNodeName(); + + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (inputTagName == nodeName) + { + // read input tag + readColladaInput(reader); + + // create new input slot + if (!Inputs.empty()) + { + SInputSlot slot; + slot.Data=0; + slot.Semantic = Inputs.getLast().Semantic; + + core::stringc sourceArrayURI; + + // get input source array id, if it is a vertex input, take + // the -source attribute. + if (slot.Semantic == ECIS_VERTEX) + sourceArrayURI = vertexPositionSource; + else + sourceArrayURI = Inputs.getLast().Source; + + uriToId(sourceArrayURI); + + // find source array (we'll ignore acessors for this implementation) + u32 s; + for (s=0; sgetNodeType() == io::EXN_ELEMENT_END) + { + if (polygonName == nodeName) + parsePolygonOK = false; // end parsing a polygon + else + if (polygonsSectionName == nodeName) + break; // cancel out and create mesh + + } // end is element end + else + if (reader->getNodeType() == io::EXN_TEXT) + { + if (parsePolygonOK && polygons.size()) + { + // parse this text and add it to the last polygon data + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + SPolygon& poly = polygons.getLast(); + while(*p) + { + findNextNoneWhiteSpace(&p); + if (*p) + poly.Indices.push_back(readInt(&p)); + } + parsePolygonOK = false; + } + } + + } // end while reader->read() + + if (inputSemanticCount == 0 || inputSemanticCount != slots.size()) + return; // we cannot create the mesh if one of the input semantics wasn't found. + + if (!polygons.size()) + return; // cancel if there are no polygons anyway. + + // analyze content of slots to create a fitting mesh buffer + + u32 u; + u32 textureCoordSetCount = 0; + bool normalSlotCount = false; + u32 secondTexCoordSetIndex = 0xFFFFFFFF; + + for (u=0; uMaterial=mat; + buffer = mbuffer; + + for (u32 i=0; iVertices.push_back(vtx); + + } // end for all vertices + + // add vertex indices + const u32 oldVertexCount = mbuffer->Vertices.size() - vertexCount; + for (u32 face=0; faceIndices.push_back(oldVertexCount + 0); + mbuffer->Indices.push_back(oldVertexCount + 1 + face); + mbuffer->Indices.push_back(oldVertexCount + 2 + face); + } + + } // end for all polygons + } + else + { + // lightmap mesh buffer + + scene::SMeshBufferLightMap* mbuffer = new SMeshBufferLightMap(); + mbuffer->Material=mat; + buffer = mbuffer; + + for (u32 i=0; iVertices.push_back(vtx); + + } // end for all vertices + + // add vertex indices + const u32 oldVertexCount = mbuffer->Vertices.size() - vertexCount; + for (u32 face=0; faceIndices.push_back(oldVertexCount + 0); + mbuffer->Indices.push_back(oldVertexCount + 1 + face); + mbuffer->Indices.push_back(oldVertexCount + 2 + face); + } + + } // end for all polygons + } + + // calculate normals if there is no slot for it + + if (!normalSlotCount) + SceneManager->getMeshManipulator()->recalculateNormals(buffer); + + // recalculate bounding box + buffer->recalculateBoundingBox(); + + // add mesh buffer + mesh->addMeshBuffer(buffer); + + buffer->drop(); +} + + +//! reads a element and stores it as prefab +void CColladaFileLoader::readLightPrefab(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading light prefab"); + #endif + + CLightPrefab* prefab = new CLightPrefab(reader->getAttributeValue("id")); + + if (!reader->isEmptyElement()) + { + readColladaParameters(reader, lightPrefabName); + + SColladaParam* p = getColladaParameter(ECPN_COLOR); + if (p && p->Type == ECPT_FLOAT3) + prefab->LightData.DiffuseColor.set(p->Floats[0], p->Floats[1], p->Floats[2]); + } + + Prefabs.push_back(prefab); +} + + +//! returns a collada parameter or none if not found +SColladaParam* CColladaFileLoader::getColladaParameter(ECOLLADA_PARAM_NAME name) +{ + for (u32 i=0; igetAttributeValue("semantic"); + for (u32 i=0; inputSemanticNames[i]; ++i) + if (semanticName == inputSemanticNames[i]) + { + p.Semantic = (ECOLLADA_INPUT_SEMANTIC)i; + break; + } + + // get source + p.Source = reader->getAttributeValue("source"); + + // add input + Inputs.push_back(p); +} + +//! parses all collada inputs inside an element and stores them in Inputs +void CColladaFileLoader::readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName) +{ + Inputs.clear(); + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + inputTagName == reader->getNodeName()) + { + readColladaInput(reader); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (parentName == reader->getNodeName()) + return; // end of parent reached + } + + } // end while reader->read(); +} + +//! parses all collada parameters inside an element and stores them in Parameters +void CColladaFileLoader::readColladaParameters(io::IXMLReaderUTF8* reader, + const core::stringc& parentName) +{ + Parameters.clear(); + + const char* const paramNames[] = {"COLOR", "AMBIENT", "DIFFUSE", + "SPECULAR", "SHININESS", "YFOV", "ZNEAR", "ZFAR", 0}; + + const char* const typeNames[] = {"float", "float2", "float3", 0}; + + while(reader->read()) + { + const char* nodeName = reader->getNodeName(); + if (reader->getNodeType() == io::EXN_ELEMENT && + paramTagName == nodeName) + { + // parse param + SColladaParam p; + + // get type + u32 i; + core::stringc typeName = reader->getAttributeValue("type"); + for (i=0; typeNames[i]; ++i) + if (typeName == typeNames[i]) + { + p.Type = (ECOLLADA_PARAM_TYPE)i; + break; + } + + // get name + core::stringc nameName = reader->getAttributeValue("name"); + for (i=0; typeNames[i]; ++i) + if (nameName == paramNames[i]) + { + p.Name = (ECOLLADA_PARAM_NAME)i; + break; + } + + // read parameter data inside parameter tags + switch(p.Type) + { + case ECPT_FLOAT: + case ECPT_FLOAT2: + case ECPT_FLOAT3: + case ECPT_FLOAT4: + readFloatsInsideElement(reader, p.Floats, p.Type - ECPT_FLOAT + 1); + break; + + // TODO: other types of data (ints, bools or whatever) + default: + break; + } + + // add param + Parameters.push_back(p); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (parentName == reader->getNodeName()) + return; // end of parent reached + } + + } // end while reader->read(); +} + + +//! parses a float from a char pointer and moves the pointer +//! to the end of the parsed float +inline f32 CColladaFileLoader::readFloat(const c8** p) +{ + f32 ftmp; + *p = core::fast_atof_move(*p, ftmp); + return ftmp; +} + +//! parses an int from a char pointer and moves the pointer to +//! the end of the parsed float +inline s32 CColladaFileLoader::readInt(const c8** p) +{ + return (s32)readFloat(p); +} + +//! places pointer to next begin of a token +void CColladaFileLoader::findNextNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + + +//! reads floats from inside of xml element until end of xml element +void CColladaFileLoader::readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count) +{ + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + // TODO: check for comments inside the element + // and ignore them. + + if (reader->getNodeType() == io::EXN_TEXT) + { + // parse float data + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + break; // end parsing text + } +} + + +//! clears all loaded data +void CColladaFileLoader::clearData() +{ + // delete all prefabs + + for (u32 i=0; idrop(); + + Prefabs.clear(); + + // clear all parameters + Parameters.clear(); + + // clear all materials + Images.clear(); + + // clear all materials + Textures.clear(); + + // clear all materials + Materials.clear(); + + // clear all inputs + Inputs.clear(); +} + +//! changes the XML URI into an internal id +void CColladaFileLoader::uriToId(core::stringc& str) +{ + // currently, we only remove the # from the begin if there + // because we simply don't support referencing other files. + if (!str.size()) + return; + + if (str[0] == '#') + str.erase(0); +} + + + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_COLLADA_LOADER_ diff --git a/src/dep/src/irrlicht/CColladaFileLoader.h b/src/dep/src/irrlicht/CColladaFileLoader.h new file mode 100644 index 0000000..facd3f9 --- /dev/null +++ b/src/dep/src/irrlicht/CColladaFileLoader.h @@ -0,0 +1,313 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +//#define COLLADA_READER_DEBUG +#endif + +class IColladaPrefab; + +enum ECOLLADA_PARAM_NAME +{ + ECPN_COLOR = 0, + ECPN_AMBIENT, + ECPN_DIFFUSE, + ECPN_SPECULAR, + ECPN_SHININESS, + ECPN_TRANSPARENCY, + ECPN_YFOV, + ECPN_ZNEAR, + ECPN_ZFAR, + + ECPN_COUNT +}; + +enum ECOLLADA_PARAM_TYPE +{ + ECPT_FLOAT = 0, + ECPT_FLOAT2, + ECPT_FLOAT3, + ECPT_FLOAT4, + + ECPT_COUNT +}; + +//! Collada Parameter +struct SColladaParam +{ + SColladaParam() + : Name(ECPN_COUNT), Type(ECPT_COUNT) + { + for (int i=0; i<4; ++i) Floats[i] = 0; + } + + ECOLLADA_PARAM_NAME Name; + ECOLLADA_PARAM_TYPE Type; + + f32 Floats[4]; +}; + +enum ECOLLADA_INPUT_SEMANTIC +{ + ECIS_POSITION = 0, + ECIS_VERTEX, + ECIS_NORMAL, + ECIS_TEXCOORD, + ECIS_UV, + ECIS_TANGENT, + ECIS_IMAGE, + ECIS_TEXTURE, + + ECIS_COUNT +}; + +//! Collada Input +struct SColladaInput +{ + SColladaInput() + : Semantic(ECIS_COUNT) + { + } + + ECOLLADA_INPUT_SEMANTIC Semantic; + core::stringc Source; +}; + +//! Collada images +struct SColladaImage +{ + core::stringc Filename; + core::stringc Id; +}; + + +//! Collada texture +struct SColladaTexture +{ + video::ITexture* Texture; + core::stringc Id; +}; + + +//! Collada material +struct SColladaMaterial +{ + video::SMaterial Mat; + core::stringc Id; +}; + + +struct SNumberArray // for stroring float and int arrays +{ + core::stringc Name; + core::array Data; +}; + +struct SAccessor +{ + SAccessor() + : Count(0), Offset(0), Stride(1) {} + // I don't store the source of the accessor here because I assume + // it to use the array of the source this accessor is located in. + + int Count; + int Offset; + int Stride; + + core::array Parameters; // parameters defining the accessor +}; + +struct SSource +{ + core::stringc Id; + SNumberArray Array; + core::array Accessors; +}; + + +//! Meshloader capable of loading COLLADA meshes and scene descriptions into Irrlicht. +class CColladaFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CColladaFileLoader(video::IVideoDriver* driver, + scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~CColladaFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + //! skips an (unknown) section in the collada document + void skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping); + + //! reads the section and its content + void readColladaSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readLibrarySection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readSceneSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readAssetSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readLookAtNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readMatrixNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readPerspectiveNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readRotateNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readTranslateNode(io::IXMLReaderUTF8* reader); + + //! reads a node and creates a scene node from it + void readInstanceNode(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, + scene::ISceneNode** outNode); + + //! reads a element and stores it as prefab + void readLightPrefab(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it as prefab + void readCameraPrefab(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the image section + void readImage(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the texture section + void readTexture(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the material section + void readMaterial(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it as mesh if possible + void readGeometry(io::IXMLReaderUTF8* reader); + + //! parses a float from a char pointer and moves the pointer to + //! the end of the parsed float + inline f32 readFloat(const c8** p); + + //! parses an int from a char pointer and moves the pointer to + //! the end of the parsed float + inline s32 readInt(const c8** p); + + //! places pointer to next begin of a token + void findNextNoneWhiteSpace(const c8** p); + + //! reads floats from inside of xml element until end of xml element + void readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count); + + //! clears all loaded data + void clearData(); + + //! parses all collada parameters inside an element and stores them in Parameters + void readColladaParameters(io::IXMLReaderUTF8* reader, const core::stringc& parentName); + + //! returns a collada parameter or none if not found + SColladaParam* getColladaParameter(ECOLLADA_PARAM_NAME name); + + //! parses all collada inputs inside an element and stores them in Inputs. Reads + //! until first tag which is not an input tag or the end of the parent is reached + void readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName); + + //! reads a collada input tag and adds it to the input parameter + void readColladaInput(io::IXMLReaderUTF8* reader); + + //! returns a collada input or none if not found + SColladaInput* getColladaInput(ECOLLADA_INPUT_SEMANTIC input); + + //! changes the XML URI into an internal id + void uriToId(core::stringc& str); + + //! reads a polygons section and creates a mesh from it + void readPolygonSection(io::IXMLReaderUTF8* reader, + const core::stringc& vertexPositionSource, core::array& sources, + scene::SMesh* mesh); + + video::IVideoDriver* Driver; + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + + scene::IAnimatedMesh* DummyMesh; + core::stringc CurrentlyLoadingMesh; + + scene::IAnimatedMesh* FirstLoadedMesh; + core::stringc FirstLoadedMeshName; + s32 LoadedMeshCount; + + core::array Prefabs; + core::array Parameters; + core::array Images; + core::array Textures; + core::array Materials; + core::array Inputs; + + bool CreateInstances; +}; + + + +//! following class is for holding and createing instances of library objects, +//! named prefabs in this loader. +class IColladaPrefab : public virtual IReferenceCounted +{ +public: + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) = 0; + + //! returns id of this prefab + virtual const c8* getId() = 0; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CColladaMeshWriter.cpp b/src/dep/src/irrlicht/CColladaMeshWriter.cpp new file mode 100644 index 0000000..53f140f --- /dev/null +++ b/src/dep/src/irrlicht/CColladaMeshWriter.cpp @@ -0,0 +1,690 @@ +#include "CColladaMeshWriter.h" +#include "os.h" +#include "IFileSystem.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" +#include "IMesh.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + + +CColladaMeshWriter::CColladaMeshWriter(video::IVideoDriver* driver, + io::IFileSystem* fs) + : FileSystem(fs), VideoDriver(driver), Writer(0) +{ + if (VideoDriver) + VideoDriver->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +CColladaMeshWriter::~CColladaMeshWriter() +{ + if (VideoDriver) + VideoDriver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CColladaMeshWriter::getType() const +{ + return EMWT_COLLADA; +} + + +//! writes a mesh +bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + Writer = FileSystem->createXMLWriter(file); + + if (!Writer) + { + os::Printer::log("Could not write file", file->getFileName()); + return false; + } + + os::Printer::log("Writing mesh", file->getFileName()); + + // write COLLADA header + + Writer->writeXMLHeader(); + + Writer->writeElement(L"COLLADA", false, + L"xmlns", L"http://www.collada.org/2005/COLLADASchema", + L"version", L"1.2.0"); + Writer->writeLineBreak(); + + // write asset data + + Writer->writeElement(L"asset", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"revision", false); + Writer->writeText(L"1.0"); + Writer->writeClosingTag(L"revision"); + Writer->writeLineBreak(); + + Writer->writeElement(L"authoring_tool", false); + core::stringw strautoring = L"Irrlicht Engine / irrEdit"; // this code has originated from irrEdit 0.7 + Writer->writeText(strautoring.c_str()); + Writer->writeClosingTag(L"authoring_tool"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"asset"); + Writer->writeLineBreak(); + + // write all materials + + Writer->writeElement(L"library", false, L"type", L"MATERIAL"); + Writer->writeLineBreak(); + + u32 i; + for (i=0; igetMeshBufferCount(); ++i) + { + core::stringw strMat = "mat"; + strMat += i; + + Writer->writeElement(L"material", false, + L"name", strMat.c_str(), + L"id", strMat.c_str()); + Writer->writeLineBreak(); + + // write all interesting material parameters as parameter + + io::IAttributes* attributes = VideoDriver->createAttributesFromMaterial( + mesh->getMeshBuffer(i)->getMaterial()); + + u32 count = attributes->getAttributeCount(); + for (u32 attridx=0; attridxgetAttributeName(attridx); + + Writer->writeElement(L"param", false, + L"name", str.c_str(), + L"type", attributes->getAttributeTypeString(attridx) ); + + str = attributes->getAttributeAsString(attridx).c_str(); + Writer->writeText(str.c_str()); + + Writer->writeClosingTag(L"param"); + Writer->writeLineBreak(); + } + + attributes->drop(); + + Writer->writeClosingTag(L"material"); + Writer->writeLineBreak(); + } + + Writer->writeClosingTag(L"library"); + Writer->writeLineBreak(); + + // write mesh + + Writer->writeElement(L"library", false, L"type", L"GEOMETRY"); + Writer->writeLineBreak(); + + Writer->writeElement(L"geometry", false, L"id", L"mesh", L"name", L"mesh"); + Writer->writeLineBreak(); + Writer->writeElement(L"mesh"); + Writer->writeLineBreak(); + + // do some statistics for the mesh to know which stuff needs to be saved into + // the file: + // - count vertices + // - check for the need of a second texture coordinate + // - count amount of second texture coordinates + // - check for the need of tangents (TODO) + + u32 totalVertexCount = 0; + u32 totalTCoords2Count = 0; + bool needsTangents = false; // TODO: tangents not supported here yet + + for (i=0; igetMeshBufferCount(); ++i) + { + totalVertexCount += mesh->getMeshBuffer(i)->getVertexCount(); + + if (hasSecondTextureCoordinates(mesh->getMeshBuffer(i)->getVertexType())) + totalTCoords2Count += mesh->getMeshBuffer(i)->getVertexCount(); + + if (!needsTangents) + needsTangents = mesh->getMeshBuffer(i)->getVertexType() == video::EVT_TANGENTS; + } + + SComponentGlobalStartPos* globalIndices = new SComponentGlobalStartPos[mesh->getMeshBufferCount()]; + + // write positions + + Writer->writeElement(L"source", false, L"id", L"mesh-Pos"); + Writer->writeLineBreak(); + + core::stringw vertexCountStr = (totalVertexCount*3); + Writer->writeElement(L"array", false, L"id", L"mesh-Pos-array", + L"type", L"float", L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].PosStartIndex = 0; + + if (i!=0) + globalIndices[i].PosStartIndex = globalIndices[i-1].PosLastIndex + 1; + + globalIndices[i].PosLastIndex = globalIndices[i].PosStartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique", false, L"profile", L"COMMON"); + Writer->writeLineBreak(); + + vertexCountStr = totalVertexCount; + + Writer->writeElement(L"accessor", false, L"source", L"#mesh-Pos-array", + L"count", vertexCountStr.c_str(), L"stride", L"3"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write texture coordinates + + Writer->writeElement(L"source", false, L"id", L"mesh-TexCoord0"); + Writer->writeLineBreak(); + + vertexCountStr = (totalVertexCount*2); + Writer->writeElement(L"array", false, L"id", L"mesh-TexCoord0-array", + L"type", L"float", L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].TCoord0StartIndex = 0; + + if (i!=0) + globalIndices[i].TCoord0StartIndex = globalIndices[i-1].TCoord0LastIndex + 1; + + globalIndices[i].TCoord0LastIndex = globalIndices[i].TCoord0StartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique", false, L"profile", L"COMMON"); + Writer->writeLineBreak(); + + vertexCountStr = totalVertexCount; + + Writer->writeElement(L"accessor", false, L"source", L"#mesh-TexCoord0-array", + L"count", vertexCountStr.c_str(), L"stride", L"2"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write normals + + Writer->writeElement(L"source", false, L"id", L"mesh-Normal"); + Writer->writeLineBreak(); + + vertexCountStr = (totalVertexCount*3); + Writer->writeElement(L"array", false, L"id", L"mesh-Normal-array", + L"type", L"float", L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].NormalStartIndex = 0; + + if (i!=0) + globalIndices[i].NormalStartIndex = globalIndices[i-1].NormalLastIndex + 1; + + globalIndices[i].NormalLastIndex = globalIndices[i].NormalStartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique", false, L"profile", L"COMMON"); + Writer->writeLineBreak(); + + vertexCountStr = totalVertexCount; + + Writer->writeElement(L"accessor", false, L"source", L"#mesh-Normal-array", + L"count", vertexCountStr.c_str(), L"stride", L"3"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write second set of texture coordinates + + if (totalTCoords2Count) + { + Writer->writeElement(L"source", false, L"id", L"mesh-TexCoord1"); + Writer->writeLineBreak(); + + vertexCountStr = (totalTCoords2Count*2); + Writer->writeElement(L"array", false, L"id", L"mesh-TexCoord1-array", + L"type", L"float", L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + if (hasSecondTextureCoordinates(vtxType)) + { + globalIndices[i].TCoord1StartIndex = 0; + + if (i!=0 && globalIndices[i-1].TCoord1LastIndex != -1) + globalIndices[i].TCoord1StartIndex = globalIndices[i-1].TCoord1LastIndex + 1; + + globalIndices[i].TCoord1LastIndex = globalIndices[i].TCoord1StartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + default: + break; + } + } // end this buffer has 2 texture coordinates + } + + Writer->writeClosingTag(L"array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique", false, L"profile", L"COMMON"); + Writer->writeLineBreak(); + + vertexCountStr = totalTCoords2Count; + + Writer->writeElement(L"accessor", false, L"source", L"#mesh-TexCoord1-array", + L"count", vertexCountStr.c_str(), L"stride", L"2"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float", L"flow", L"OUT"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + } + + // write tangents + + // TODO + + // write vertices + + Writer->writeElement(L"vertices", false, L"id", L"mesh-Vtx"); + Writer->writeLineBreak(); + + Writer->writeElement(L"input", true, L"semantic", L"POSITION", L"source", L"#mesh-Pos"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"vertices"); + Writer->writeLineBreak(); + + // write polygons + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + + u32 polyCount = buffer->getIndexCount() / 3; + core::stringw strPolyCount = polyCount; + core::stringw strMat = "#mat"; + strMat += i; + + Writer->writeElement(L"polygons", false, L"count", strPolyCount.c_str(), + L"material", strMat.c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", L"#mesh-Vtx", L"idx", L"0"); + Writer->writeLineBreak(); + Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord0", L"idx", L"1"); + Writer->writeLineBreak(); + Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", L"#mesh-Normal", L"idx", L"2"); + Writer->writeLineBreak(); + + bool has2ndTexCoords = hasSecondTextureCoordinates(buffer->getVertexType()); + if (has2ndTexCoords) + { + Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", L"#mesh-TexCoord1", L"idx", L"3"); + Writer->writeLineBreak(); + } + + // write indices now + + s32 posIdx = globalIndices[i].PosStartIndex; + s32 tCoordIdx = globalIndices[i].TCoord0StartIndex; + s32 normalIdx = globalIndices[i].NormalStartIndex; + s32 tCoord2Idx = globalIndices[i].TCoord1StartIndex; + + for (u32 p=0; pwriteElement(L"p", false); + + core::stringw strP; + + strP += buffer->getIndices()[(p*3) + 0] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 0] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 0] + normalIdx; + strP += " "; + if (has2ndTexCoords) + { + strP += buffer->getIndices()[(p*3) + 0] + tCoord2Idx; + strP += " "; + } + + strP += buffer->getIndices()[(p*3) + 1] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 1] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 1] + normalIdx; + strP += " "; + if (has2ndTexCoords) + { + strP += buffer->getIndices()[(p*3) + 1] + tCoord2Idx; + strP += " "; + } + + strP += buffer->getIndices()[(p*3) + 2] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + normalIdx; + if (has2ndTexCoords) + { + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + tCoord2Idx; + } + + Writer->writeText(strP.c_str()); + + Writer->writeClosingTag(L"p"); + Writer->writeLineBreak(); + } + + // close index buffer section + + Writer->writeClosingTag(L"polygons"); + Writer->writeLineBreak(); + } + + // close mesh and geometry + + Writer->writeClosingTag(L"mesh"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"geometry"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"library"); + Writer->writeLineBreak(); + + // close everything + + Writer->writeClosingTag(L"COLLADA"); + Writer->drop(); + + delete [] globalIndices; + + return true; +} + + +bool CColladaMeshWriter::hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const +{ + return type == video::EVT_2TCOORDS; +} + + +} // end namespace +} // end namespace diff --git a/src/dep/src/irrlicht/CColladaMeshWriter.h b/src/dep/src/irrlicht/CColladaMeshWriter.h new file mode 100644 index 0000000..79e1660 --- /dev/null +++ b/src/dep/src/irrlicht/CColladaMeshWriter.h @@ -0,0 +1,69 @@ +#ifndef __IRR_C_COLLADA_MESH_WRITER_H_INCLUDED__ +#define __IRR_C_COLLADA_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; + class IFileSystem; +} +namespace scene +{ + +//! class to write meshes, implementing a COLLADA (.dae, .xml) writer +/** This writer implementation has been originally developed for irrEdit and then +merged out to the Irrlicht Engine */ +class CColladaMeshWriter : public IMeshWriter +{ +public: + + CColladaMeshWriter(video::IVideoDriver* driver, io::IFileSystem* fs); + virtual ~CColladaMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + +protected: + + bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const; + + struct SComponentGlobalStartPos + { + SComponentGlobalStartPos() : PosStartIndex(-1), PosLastIndex(-1), + NormalStartIndex(-1), NormalLastIndex(-1), + TCoord0StartIndex(-1), TCoord0LastIndex(-1), + TCoord1StartIndex(-1), TCoord1LastIndex(-1) + { } + + s32 PosStartIndex; + s32 PosLastIndex; + + s32 NormalStartIndex; + s32 NormalLastIndex; + + s32 TCoord0StartIndex; + s32 TCoord0LastIndex; + + s32 TCoord1StartIndex; + s32 TCoord1LastIndex; + }; + + io::IFileSystem* FileSystem; + video::IVideoDriver* VideoDriver; + io::IXMLWriter* Writer; +}; + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CColorConverter.cpp b/src/dep/src/irrlicht/CColorConverter.cpp new file mode 100644 index 0000000..e75b0cc --- /dev/null +++ b/src/dep/src/irrlicht/CColorConverter.cpp @@ -0,0 +1,571 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CColorConverter.h" +#include "SColor.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +//! converts a monochrome bitmap to A1R5G5B5 data +void CColorConverter::convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad, bool flip) +{ + if (!in || !out) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y>shift & 0x01 ? (s16)0xffff : (s16)0x8000; + + if ((--shift)<0) // 8 pixel done + { + shift=7; + ++in; + } + } + + if (shift != 7) // width did not fill last byte + ++in; + + if (!flip) + out += width; + in += linepad; + } +} + + + +//! converts a 4 bit palettized image to A1R5G5B5 +void CColorConverter::convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip) +{ + if (!in || !out || !palette) + return; + + if (flip) + out += width*height; + + for (s32 y=0; y> shift) & 0xf)]); + + if (shift==0) + { + shift = 4; + ++in; + } + else + shift = 0; + } + + if (shift == 0) // odd width + ++in; + + if (!flip) + out += width; + in += linepad; + } +} + + + +//! converts a 8 bit palettized image into A1R5G5B5 +void CColorConverter::convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip) +{ + if (!in || !out || !palette) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y> 15)&0x1)<<31) | (((t >> 10)&0x1F)<<19) | + (((t >> 5)&0x1F)<<11) | (t&0x1F)<<3; + out[(s32)(y*newWidth + x)] = t; + + sy+=sourceYStep; + } + } +} + + + +//! copies X8R8G8B8 32 bit data +void CColorConverter::convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip) +{ + if (!in || !out) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y> 7; + dB[1] = (*sB & 0x03e0) >> 2; + dB[0] = (*sB & 0x1f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[0] = (*sB & 0x7c00) >> 7; + dB[1] = (*sB & 0x03e0) >> 2; + dB[2] = (*sB & 0x1f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A1R5G5B5toA8R8G8B8(*sB++); +} + +void CColorConverter::convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 2); +} + +void CColorConverter::convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A1R5G5B5toR5G6B5(*sB++); +} + +void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + // sB[3] is alpha + dB[0] = sB[2]; + dB[1] = sB[1]; + dB[2] = sB[0]; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + // sB[3] is alpha + dB[0] = sB[0]; + dB[1] = sB[1]; + dB[2] = sB[2]; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 4); +} + +void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u32* sB = (u32*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A8R8G8B8toA1R5G5B5(*sB++); +} + +void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[2] >> 3; + s32 g = sB[1] >> 2; + s32 b = sB[0] >> 3; + + dB[0] = (r << 11) | (g << 5) | (b); + + sB += 4; + dB += 1; + } +} + +void CColorConverter::convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + u8 r = sB[2] & 0xe0; + u8 g = (sB[1] & 0xe0) >> 3; + u8 b = (sB[0] & 0xc0) >> 6; + + dB[0] = (r | g | b); + + sB += 4; + dB += 1; + } +} + +void CColorConverter::convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 3); +} + +void CColorConverter::convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8* )sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + { + *dB = 0xff000000 | (sB[0]<<16) | (sB[1]<<8) | sB[2]; + + sB += 3; + ++dB; + } +} + +void CColorConverter::convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[0] >> 3; + s32 g = sB[1] >> 3; + s32 b = sB[2] >> 3; + + dB[0] = (0x8000) | (r << 10) | (g << 5) | (b); + + sB += 3; + dB += 1; + } +} + +void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[0] >> 3; + s32 g = sB[1] >> 2; + s32 b = sB[2] >> 3; + + dB[0] = (r << 11) | (g << 5) | (b); + + sB += 3; + dB += 1; + } +} + +void CColorConverter::convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 2); +} + +void CColorConverter::convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[0] = (*sB & 0xf800) << 8; + dB[1] = (*sB & 0x07e0) << 2; + dB[2] = (*sB & 0x001f) << 3; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[2] = (*sB & 0xf800) << 8; + dB[1] = (*sB & 0x07e0) << 2; + dB[0] = (*sB & 0x001f) << 3; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = R5G6B5toA8R8G8B8(*sB++); +} + +void CColorConverter::convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = R5G6B5toA1R5G5B5(*sB++); +} + + +void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF) +{ + switch (sF) + { + case ECF_A1R5G5B5: + switch (dF) + { + case ECF_A1R5G5B5: + convert_A1R5G5B5toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_A1R5G5B5toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_A1R5G5B5toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_A1R5G5B5toR8G8B8(sP, sN, dP); + break; + } + break; + case ECF_R5G6B5: + switch (dF) + { + case ECF_A1R5G5B5: + convert_R5G6B5toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_R5G6B5toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_R5G6B5toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_R5G6B5toR8G8B8(sP, sN, dP); + break; + } + break; + case ECF_A8R8G8B8: + switch (dF) + { + case ECF_A1R5G5B5: + convert_A8R8G8B8toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_A8R8G8B8toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_A8R8G8B8toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_A8R8G8B8toR8G8B8(sP, sN, dP); + break; + } + break; + case ECF_R8G8B8: + switch (dF) + { + case ECF_A1R5G5B5: + convert_R8G8B8toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_R8G8B8toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_R8G8B8toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_R8G8B8toR8G8B8(sP, sN, dP); + break; + } + break; + } +} + + +} // end namespace video +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CColorConverter.h b/src/dep/src/irrlicht/CColorConverter.h new file mode 100644 index 0000000..d3cbf3d --- /dev/null +++ b/src/dep/src/irrlicht/CColorConverter.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_COLOR_CONVERTER_H_INCLUDED__ +#define __C_COLOR_CONVERTER_H_INCLUDED__ + +#include "irrTypes.h" +#include "IImage.h" + +namespace irr +{ +namespace video +{ + +class CColorConverter +{ +public: + + //! converts a monochrome bitmap to A1R5G5B5 + static void convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false); + + //! converts a 4 bit palettized image to A1R5G5B5 + static void convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false); + + //! converts a 8 bit palettized image to A1R5G5B5 + static void convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false); + + //! converts R8G8B8 16 bit data to A1R5G5B5 data + static void convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false); + + //! copies R8G8B8 24 bit data to 24 data, and flips and + //! mirrors the image during the process. + static void convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad=0, bool flip=false, bool bgr=false); + + //! Resizes the surface to a new size and converts it at the same time + //! to an A8R8G8B8 format, returning the pointer to the new buffer. + static void convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight); + + //! copies X8R8G8B8 32 bit data, and flips and + //! mirrors the image during the process. + static void convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip=false); + + + //! functions for converting one image format to another efficiently + //! and hopefully correctly. + //! + //! \param sP pointer to source pixel data + //! \param sN number of source pixels to copy + //! \param dP pointer to destination data buffer. must be big enough + //! to hold sN pixels in the output format. + static void convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP); + + static void convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); + + static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); + + static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF); +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CCubeSceneNode.cpp b/src/dep/src/irrlicht/CCubeSceneNode.cpp new file mode 100644 index 0000000..32bd0ba --- /dev/null +++ b/src/dep/src/irrlicht/CCubeSceneNode.cpp @@ -0,0 +1,173 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCubeSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + /* + 011 111 + /6,8------/5 y + / | / | ^ z + / | / | | / + 010 3,9-------2 | |/ + | 7- - -10,4 101 *---->x + | / | / + |/ | / + 0------11,1/ + 000 100 + */ + +//! constructor +CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr, + s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) + : ISceneNode(parent, mgr, id, position, rotation, scale), Size(size) +{ + #ifdef _DEBUG + setDebugName("CCubeSceneNode"); + #endif + + const u16 u[36] = { 0,2,1, 0,3,2, 1,5,4, 1,2,5, 4,6,7, 4,5,6, + 7,3,0, 7,6,3, 9,5,2, 9,8,5, 0,11,10, 0,10,7}; + + Buffer.Indices.set_used(36); + for (u32 i=0; i<36; ++i) + Buffer.Indices[i] = u[i]; + + setSize(); +} + + +//! destructor +CCubeSceneNode::~CCubeSceneNode() +{ +} + +void CCubeSceneNode::setSize() +{ + // we are creating the cube mesh here. + + // nicer texture mapping sent in by Dr Andros C Bragianos + // .. and then improved by jox. + + video::SColor clr(255,255,255,255); + + Buffer.Vertices.set_used(12); + Buffer.Vertices[0] = video::S3DVertex(0,0,0, -1,-1,-1, clr, 0, 1); + Buffer.Vertices[1] = video::S3DVertex(1,0,0, 1,-1,-1, clr, 1, 1); + Buffer.Vertices[2] = video::S3DVertex(1,1,0, 1, 1,-1, clr, 1, 0); + Buffer.Vertices[3] = video::S3DVertex(0,1,0, -1, 1,-1, clr, 0, 0); + Buffer.Vertices[4] = video::S3DVertex(1,0,1, 1,-1, 1, clr, 0, 1); + Buffer.Vertices[5] = video::S3DVertex(1,1,1, 1, 1, 1, clr, 0, 0); + Buffer.Vertices[6] = video::S3DVertex(0,1,1, -1, 1, 1, clr, 1, 0); + Buffer.Vertices[7] = video::S3DVertex(0,0,1, -1,-1, 1, clr, 1, 1); + Buffer.Vertices[8] = video::S3DVertex(0,1,1, -1, 1, 1, clr, 0, 1); + Buffer.Vertices[9] = video::S3DVertex(0,1,0, -1, 1,-1, clr, 1, 1); + Buffer.Vertices[10] = video::S3DVertex(1,0,1, 1,-1, 1, clr, 1, 0); + Buffer.Vertices[11] = video::S3DVertex(1,0,0, 1,-1,-1, clr, 0, 0); + + Buffer.BoundingBox.reset(0,0,0); + + for (u32 i=0; i<12; ++i) + { + Buffer.Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); + Buffer.Vertices[i].Pos *= Size; + Buffer.BoundingBox.addInternalPoint(Buffer.Vertices[i].Pos); + } +} + + +//! renders the node. +void CCubeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + driver->setMaterial(Buffer.Material); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + driver->drawMeshBuffer(&Buffer); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CCubeSceneNode::getBoundingBox() const +{ + return Buffer.BoundingBox; +} + + +void CCubeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CCubeSceneNode::getMaterial(u32 i) +{ + return Buffer.Material; +} + + +//! returns amount of materials used by this scene node. +u32 CCubeSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Writes attributes of the scene node. +void CCubeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addFloat("Size", Size); +} + + +//! Reads attributes of the scene node. +void CCubeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Size = in->getAttributeAsFloat("Size"); + Size = core::max_(Size, 0.0001f); + setSize(); + + ISceneNode::deserializeAttributes(in, options); +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CCubeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CCubeSceneNode* nb = new CCubeSceneNode(Size, newParent, + newManager, ID, RelativeTranslation); + + nb->cloneMembers(this, newManager); + nb->Buffer.Material = Buffer.Material; + + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CCubeSceneNode.h b/src/dep/src/irrlicht/CCubeSceneNode.h new file mode 100644 index 0000000..853af77 --- /dev/null +++ b/src/dep/src/irrlicht/CCubeSceneNode.h @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TEST_SCENE_NODE_H_INCLUDED__ +#define __C_TEST_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + class CCubeSceneNode : public ISceneNode + { + public: + + //! constructor + CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CCubeSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CUBE; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + void setSize(); + + SMeshBuffer Buffer; + f32 Size; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CD3D8Driver.cpp b/src/dep/src/irrlicht/CD3D8Driver.cpp new file mode 100644 index 0000000..6e32166 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8Driver.cpp @@ -0,0 +1,2128 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D8Driver.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "os.h" +#include "S3DVertex.h" +#include "CD3D8Texture.h" +#include "CImage.h" +#include "CD3D8MaterialRenderer.h" +#include "CD3D8ShaderMaterialRenderer.h" +#include "CD3D8NormalMapRenderer.h" +#include "CD3D8ParallaxMapRenderer.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CD3D8Driver::CD3D8Driver(const core::dimension2d& screenSize, HWND window, + bool fullscreen, bool stencilbuffer, + io::IFileSystem* io, bool pureSoftware, bool vsync) +: CNullDriver(io, screenSize), CurrentRenderMode(ERM_NONE), + ResetRenderStates(true), Transformation3DChanged(false), StencilBuffer(stencilbuffer), + D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), + LastVertexType((video::E_VERTEX_TYPE)-1), MaxTextureUnits(0), MaxUserClipPlanes(0), + MaxLightDistance(sqrtf(FLT_MAX)), LastSetLight(-1), DeviceLost(false) +{ + #ifdef _DEBUG + setDebugName("CD3D8Driver"); + #endif + + printVersion(); + + for (u32 i=0; iRelease(); + + if (pID3D) + pID3D->Release(); +} + + +void CD3D8Driver::createMaterialRenderers() +{ + // create D3D8 material renderers + + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); + + // add the same renderer for all lightmap types + CD3D8MaterialRenderer_LIGHTMAP* lmr = new CD3D8MaterialRenderer_LIGHTMAP(pID3DDevice, this); + addMaterialRenderer(lmr); // for EMT_LIGHTMAP: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: + lmr->drop(); + + // add remaining material renderers + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); + + // add normal map renderers + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add parallax map renderers + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add basic 1 texture blending + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); + +} + + +//! initialises the Direct3D API +bool CD3D8Driver::initDriver(const core::dimension2d& screenSize, HWND hwnd, + u32 bits, bool fullScreen, bool pureSoftware, + bool highPrecisionFPU, bool vsync, bool antiAlias) +{ + HRESULT hr; + D3DLibrary = LoadLibrary( "d3d8.dll" ); + + if (!D3DLibrary) + { + os::Printer::log("Error, could not load d3d8.dll.", ELL_ERROR); + return false; + } + + typedef IDirect3D8 * (__stdcall *D3DCREATETYPE)(UINT); + D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate8"); + + if (!d3dCreate) + { + os::Printer::log("Error, could not get proc adress of Direct3DCreate8.", ELL_ERROR); + return false; + } + + //just like pID3D = Direct3DCreate8(D3D_SDK_VERSION); + pID3D = (*d3dCreate)(D3D_SDK_VERSION); + + if (!pID3D) + { + os::Printer::log("Error initializing D3D.", ELL_ERROR); + return false; + } + + // print device information + D3DADAPTER_IDENTIFIER8 dai; + if (!FAILED(pID3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &dai))) + { + char tmp[512]; + + s32 Product = HIWORD(dai.DriverVersion.HighPart); + s32 Version = LOWORD(dai.DriverVersion.HighPart); + s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); + s32 Build = LOWORD(dai.DriverVersion.LowPart); + + sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, + SubVersion, Build); + os::Printer::log(tmp, ELL_INFORMATION); + } + + + + D3DDISPLAYMODE d3ddm; + hr = pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); + if (FAILED(hr)) + { + os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); + return false; + } + + + ZeroMemory(&present, sizeof(present)); + + present.SwapEffect = D3DSWAPEFFECT_COPY; + present.Windowed = TRUE; + present.BackBufferFormat = d3ddm.Format; + present.EnableAutoDepthStencil = TRUE; + + if (fullScreen) + { + present.SwapEffect = D3DSWAPEFFECT_FLIP; + present.Windowed = FALSE; + present.BackBufferWidth = screenSize.Width; + present.BackBufferHeight = screenSize.Height; + present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + present.FullScreen_PresentationInterval = vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + + if (bits == 32) + present.BackBufferFormat = D3DFMT_X8R8G8B8; + else + present.BackBufferFormat = D3DFMT_R5G6B5; + } + + D3DDEVTYPE devtype = D3DDEVTYPE_HAL; + #ifndef _IRR_D3D_NO_SHADER_DEBUGGING + devtype = D3DDEVTYPE_REF; + #endif + + // enable anti alias if possible and whished + if (antiAlias) + { + if (!FAILED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, + devtype , present.BackBufferFormat, !fullScreen, + D3DMULTISAMPLE_2_SAMPLES))) + { + // enable multi sampling + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + present.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES; + } + else + { + os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); + antiAlias = false; + } + } + + // check stencil buffer compatibility + if (StencilBuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D24S8; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X4S4; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D15S1; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + } + } + else + if(FAILED(pID3D->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) + { + os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + } + // do not use else here to cope with flag change in previous block + if (!StencilBuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D32; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X8; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D16; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); + return false; + } + } + } + } + + // create device + + DWORD fpuPrecision = highPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; + if (pureSoftware) + { + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, + fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR); + } + else + { + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); + if(FAILED(hr)) + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); + } + + if (!pID3DDevice) + { + os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); + return false; + } + + // get caps + pID3DDevice->GetDeviceCaps(&Caps); + + if (StencilBuffer && + (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) + { + os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + + // set default vertex shader + setVertexShader(EVT_STANDARD); + + // enable antialiasing + if (antiAlias) + pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + + // set fog mode + setFog(FogColor, LinearFog, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); + + // set exposed data + ExposedData.D3D8.D3D8 = pID3D; + ExposedData.D3D8.D3DDev8 = pID3DDevice; + ExposedData.D3D8.HWnd = reinterpret_cast(hwnd); + + ResetRenderStates = true; + + // create materials + createMaterialRenderers(); + + MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); + MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; + + // set the renderstates + setRenderStates3DMode(); + + // set max anisotropy + pID3DDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY, core::min_( (DWORD) 16, Caps.MaxAnisotropy)); + pID3DDevice->SetTextureStageState(1, D3DTSS_MAXANISOTROPY, core::min_( (DWORD) 16, Caps.MaxAnisotropy)); + pID3DDevice->SetTextureStageState(2, D3DTSS_MAXANISOTROPY, core::min_( (DWORD) 16, Caps.MaxAnisotropy)); + pID3DDevice->SetTextureStageState(3, D3DTSS_MAXANISOTROPY, core::min_( (DWORD) 16, Caps.MaxAnisotropy)); + + // so far so good. + return true; +} + + + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color); + HRESULT hr; + + if (!pID3DDevice) + return false; + + if (DeviceLost) + { + if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) + { + if (hr == D3DERR_DEVICELOST) + return false; + + if (hr == D3DERR_DEVICENOTRESET) + reset(); + return false; + } + } + + DWORD flags = 0; + + if (backBuffer) + flags |= D3DCLEAR_TARGET; + + if (zBuffer) + flags |= D3DCLEAR_ZBUFFER; + + if (StencilBuffer) + flags |= D3DCLEAR_STENCIL; + + hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); + if (FAILED(hr)) + os::Printer::log("Direct3D8 clear failed.", ELL_WARNING); + + hr = pID3DDevice->BeginScene(); + if (FAILED(hr)) + { + os::Printer::log("Direct3D8 begin scene failed.", ELL_WARNING); + return false; + } + + return true; +} + + + +//! resets the device +bool CD3D8Driver::reset() +{ + // reset + HRESULT hr; + os::Printer::log("Resetting D3D8 device.", ELL_INFORMATION); + if (FAILED(hr = pID3DDevice->Reset(&present))) + { + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); + } + else + os::Printer::log("Resetting failed.", ELL_WARNING); + return false; + } + + DeviceLost = false; + ResetRenderStates = true; + LastVertexType = (E_VERTEX_TYPE)-1; + + for (u32 i=0; i* sourceRect ) +{ + CNullDriver::endScene(); + + HRESULT hr = pID3DDevice->EndScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D8 end scene failed.", ELL_WARNING); + return false; + } + + RECT* srcRct = 0; + RECT sourceRectData; + if ( sourceRect) + { + srcRct = &sourceRectData; + sourceRectData.left = sourceRect->UpperLeftCorner.X; + sourceRectData.top = sourceRect->UpperLeftCorner.Y; + sourceRectData.right = sourceRect->LowerRightCorner.X; + sourceRectData.bottom = sourceRect->LowerRightCorner.Y; + } + + hr = pID3DDevice->Present(srcRct, NULL, (HWND)windowId, NULL); + + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("DIRECT3D8 device lost.", ELL_WARNING); + } + else + if (FAILED(hr) && hr != D3DERR_INVALIDCALL) + { + os::Printer::log("DIRECT3D8 present failed.", ELL_WARNING); + return false; + } + + return true; +} + + + +//! queries the features of the driver, returns true if feature is available +bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_RENDER_TO_TARGET: + case EVDF_MULTITEXTURE: + case EVDF_BILINEAR_FILTER: + return true; + case EVDF_HARDWARE_TL: + return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; + case EVDF_MIP_MAP: + return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; + case EVDF_STENCIL_BUFFER: + return StencilBuffer && Caps.StencilCaps; + case EVDF_VERTEX_SHADER_1_1: + return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); + case EVDF_VERTEX_SHADER_2_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); + case EVDF_VERTEX_SHADER_3_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); + case EVDF_PIXEL_SHADER_1_1: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); + case EVDF_PIXEL_SHADER_1_2: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); + case EVDF_PIXEL_SHADER_1_3: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); + case EVDF_PIXEL_SHADER_1_4: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); + case EVDF_PIXEL_SHADER_2_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); + case EVDF_PIXEL_SHADER_3_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); + case EVDF_TEXTURE_NPOT: + return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; + default: + return false; + }; +} + + + +//! sets transformation +void CD3D8Driver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + switch(state) + { + case ETS_VIEW: + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_WORLD: + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_PROJECTION: + pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_TEXTURE_0: + case ETS_TEXTURE_1: + case ETS_TEXTURE_2: + case ETS_TEXTURE_3: + pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + if (mat.isIdentity()) + pID3DDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), &UnitMatrixD3D8 ); + else + pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), + (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_COUNT: + break; + } + + Matrices[state] = mat; +} + + + +//! sets the current Texture +bool CD3D8Driver::setTexture(s32 stage, const video::ITexture* texture) +{ + if (CurrentTexture[stage] == texture) + return true; + + if (texture && texture->getDriverType() != EDT_DIRECT3D8) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + CurrentTexture[stage] = texture; + + if (!texture) + { + pID3DDevice->SetTexture(stage, 0); + pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + } + else + { + pID3DDevice->SetTexture(stage, ((const CD3D8Texture*)texture)->getDX8Texture()); + } + return true; +} + + + +//! sets a material +void CD3D8Driver::setMaterial(const SMaterial& material) +{ + Material = material; + + for (u32 i=0; igetDriverType() != EDT_DIRECT3D8) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + // check for valid render target + + CD3D8Texture* tex = (CD3D8Texture*)texture; + + if (texture && !tex->isRenderTarget()) + { + os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); + return false; + } + + if (texture && (tex->getSize().Width > ScreenSize.Width || + tex->getSize().Height > ScreenSize.Height )) + { + os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); + return false; + } + + // check if we should set the previous RT back + + bool ret = true; + + if (tex == 0) + { + if (PrevRenderTarget) + { + IDirect3DSurface8* dss = 0; + pID3DDevice->GetDepthStencilSurface(&dss); + + if (FAILED(pID3DDevice->SetRenderTarget(PrevRenderTarget, dss))) + { + os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); + ret = false; + } + + if (dss) + dss->Release(); + + CurrentRendertargetSize = core::dimension2d(0,0); + PrevRenderTarget->Release(); + PrevRenderTarget = 0; + } + } + else + { + // we want to set a new target. so do this. + + // store previous target + + if (!PrevRenderTarget) + if (FAILED(pID3DDevice->GetRenderTarget(&PrevRenderTarget))) + { + os::Printer::log("Could not get previous render target.", ELL_ERROR); + return false; + } + + // set new render target + + IDirect3DSurface8* dss = 0; + pID3DDevice->GetDepthStencilSurface(&dss); + + if (FAILED(pID3DDevice->SetRenderTarget(tex->getRenderTargetSurface(), dss))) + { + os::Printer::log("Error: Could not set render target.", ELL_ERROR); + ret = false; + } + + if (dss) + dss->Release(); + + CurrentRendertargetSize = tex->getSize(); + } + + if (clearBackBuffer || clearZBuffer) + { + DWORD flags = 0; + + if (clearBackBuffer) + flags |= D3DCLEAR_TARGET; + + if (clearZBuffer) + flags |= D3DCLEAR_ZBUFFER; + + pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); + } + + return ret; +} + +//! Creates a render target texture. +ITexture* CD3D8Driver::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + return new CD3D8Texture(this, size, name); +} + + + +//! sets a viewport +void CD3D8Driver::setViewPort(const core::rect& area) +{ + core::rect vp(area); + core::rect rendert(0,0, ScreenSize.Width, ScreenSize.Height); + vp.clipAgainst(rendert); + + D3DVIEWPORT8 viewPort; + viewPort.X = vp.UpperLeftCorner.X; + viewPort.Y = vp.UpperLeftCorner.Y; + viewPort.Width = vp.getWidth(); + viewPort.Height = vp.getHeight(); + viewPort.MinZ = 0.0f; + viewPort.MaxZ = 1.0f; + + HRESULT hr = D3DERR_INVALIDCALL; + if (vp.getHeight()>0 && vp.getWidth()>0) + hr = pID3DDevice->SetViewport(&viewPort); + + if (FAILED(hr)) + os::Printer::log("Failed setting the viewport.", ELL_WARNING); + + ViewPort = vp; +} + + + +//! gets the area of the current viewport +const core::rect& CD3D8Driver::getViewPort() const +{ + return ViewPort; +} + + + +//! draws a vertex primitive list +void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType); + + if (!vertexCount || !primitiveCount) + return; + + setVertexShader(vType); + + const u32 stride = getVertexPitchFromType(vType); + + if (setRenderStates3DMode()) + { + switch (pType) + { + case scene::EPT_POINT_SPRITES: + case scene::EPT_POINTS: + { + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&Material.Thickness)); + f32 tmp=1.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); + tmp=0.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); + } + break; + case scene::EPT_LINE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_LINE_LOOP: + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + u16 tmpIndices[] = {0, primitiveCount}; + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + 1, tmpIndices, D3DFMT_INDEX16, vertices, stride); + } + break; + case scene::EPT_LINES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLE_FAN: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + } + } +} + + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CD3D8Driver::draw2DImage(const video::ITexture* texture, const core::position2d& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + if (!setTexture(0, texture)) + return; + + core::position2d targetPos = pos; + core::position2d sourcePos = sourceRect.UpperLeftCorner; + core::dimension2d sourceSize(sourceRect.getSize()); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + if (targetPos.X + sourceSize.Width > renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + s32 xPlus = -(renderTargetSize.Width>>1); + f32 xFact = 1.0f / (renderTargetSize.Width>>1); + + s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); + f32 yFact = 1.0f / (renderTargetSize.Height>>1); + + const core::dimension2d sourceSurfaceSize = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)+0.5f) / texture->getOriginalSize().Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)+0.5f) / texture->getOriginalSize().Height; + tcoords.LowerRightCorner.X = (((f32)sourcePos.X +0.5f + (f32)sourceSize.Width)) / texture->getOriginalSize().Width; + tcoords.LowerRightCorner.Y = (((f32)sourcePos.Y +0.5f + (f32)sourceSize.Height)) / texture->getOriginalSize().Height; + + core::rect poss(targetPos, sourceSize); + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.UpperLeftCorner.Y ) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- poss.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); +} + + + +void CD3D8Driver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + video::SColor* colors, bool useAlphaChannelOfTexture) +{ + if(!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; + tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; + tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; + tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + core::rect npos; + f32 xFact = 2.0f / ( renderTargetSize.Width ); + f32 yFact = 2.0f / ( renderTargetSize.Height ); + npos.UpperLeftCorner.X = ( destRect.UpperLeftCorner.X * xFact ) - 1.0f; + npos.UpperLeftCorner.Y = 1.0f - ( destRect.UpperLeftCorner.Y * yFact ); + npos.LowerRightCorner.X = ( destRect.LowerRightCorner.X * xFact ) - 1.0f; + npos.LowerRightCorner.Y = 1.0f - ( destRect.LowerRightCorner.Y * yFact ); + + video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + video::SColor* useColor = colors ? colors : temp; + + S3DVertex vtx[4]; // clock wise + vtx[0] = S3DVertex(npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, useColor[0], tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex(npos.LowerRightCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, useColor[3], tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex(npos.LowerRightCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, useColor[2], tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, useColor[1], tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); + + setTexture(0, texture); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); +} + + + +//!Draws an 2d rectangle with a gradient. +void CD3D8Driver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + core::rect pos(position); + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + s32 xPlus = -(renderTargetSize.Width>>1); + f32 xFact = 1.0f / (renderTargetSize.Width>>1); + + s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); + f32 yFact = 1.0f / (renderTargetSize.Height>>1); + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); + vtx[1] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); + vtx[2] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); + vtx[3] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode( + colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + +} + + + +//! Draws a 2d line. +void CD3D8Driver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + // thanks to Vash TheStampede who sent in his implementation + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + const s32 xPlus = -(renderTargetSize.Width>>1); + const f32 xFact = 1.0f / (renderTargetSize.Width>>1); + + const s32 yPlus = + renderTargetSize.Height-(renderTargetSize.Height>>1); + const f32 yFact = 1.0f / (renderTargetSize.Height>>1); + + S3DVertex vtx[2]; + vtx[0] = S3DVertex((f32)(start.X + xPlus) * xFact, + (f32)(yPlus - start.Y) * yFact, + 0.0f, // z + 0.0f, 0.0f, 0.0f, // normal + color, + 0.0f, 0.0f); // texture + + vtx[1] = S3DVertex((f32)(end.X+xPlus) * xFact, + (f32)(yPlus- end.Y) * yFact, + 0.0f, + 0.0f, 0.0f, 0.0f, + color, + 0.0f, 0.0f); + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); +} + + + +//! sets right vertex shader +void CD3D8Driver::setVertexShader(E_VERTEX_TYPE newType) +{ + // Because we don't know if a vertex shader was set in a material instead of a + // fvf, this call cannot be prevented in D3D8. + //if (newType != LastVertexType) + { + LastVertexType = newType; + HRESULT hr = 0; + + switch(newType) + { + case EVT_STANDARD: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); + break; + case EVT_2TCOORDS: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); + break; + case EVT_TANGENTS: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | + D3DFVF_TEXCOORDSIZE2(0) | // real texture coord + D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent + D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal + ); + break; + } + + if (FAILED(hr)) + { + os::Printer::log("Could not set vertex Shader.", ELL_ERROR); + return; + } + } +} + + +//! sets the needed renderstates +bool CD3D8Driver::setRenderStates3DMode() +{ + if (!pID3DDevice) + return false; + + if (CurrentRenderMode != ERM_3D) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + + ResetRenderStates = true; + } + + if (ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (CurrentRenderMode == ERM_3D && + LastMaterial.MaterialType != Material.MaterialType && + LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + } + + bool shaderOK = true; + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); + + LastMaterial = Material; + + ResetRenderStates = false; + + CurrentRenderMode = ERM_3D; + + return shaderOK; +} + + +//! Can be called by an IMaterialRenderer to make its work easier. +void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates) +{ + if (resetAllRenderstates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.Shininess != material.Shininess) + { + D3DMATERIAL8 mat; + mat.Diffuse = colorToD3D(material.DiffuseColor); + mat.Ambient = colorToD3D(material.AmbientColor); + mat.Specular = colorToD3D(material.SpecularColor); + mat.Emissive = colorToD3D(material.EmissiveColor); + mat.Power = material.Shininess; + pID3DDevice->SetMaterial(&mat); + } + + // fillmode + if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) + { + if (material.Wireframe) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + else + if (material.PointCloud) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); + else + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } + + // shademode + + if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) + { + if (material.GouraudShading) + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + else + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + + // lighting + + if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) + { + if (material.Lighting) + pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); + else + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + } + + + // zbuffer + + if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case 0: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + break; + case 1: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + break; + case 2: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + break; + } + } + + + // zwrite + if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) + { + if (material.ZWriteEnable) + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); + else + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); + } + + // back face culling + + + if (resetAllRenderstates || lastmaterial.BackfaceCulling != material.BackfaceCulling) + { + if (material.BackfaceCulling) + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + else + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE); + } + + // fog + if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) + { + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); + } + + // specular highlights + if (resetAllRenderstates || !core::equals(lastmaterial.Shininess, material.Shininess)) + { + bool enable = (material.Shininess!=0); + pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); + } + + // normalization + if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); + } + + // thickness + if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) + { + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); + } + + // texture address mode + for (u32 st=0; stSetTextureStageState(st, D3DTSS_ADDRESSU, mode ); + pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, mode ); + } + + // Bilinear and/or trilinear + if (resetAllRenderstates || + lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || + lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || + lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter ) + { + if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter) + { + D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMip = material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT; + + pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, tftMag); + pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, tftMin); + pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, tftMip); + } + else + { + pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, D3DTEXF_POINT); + } + } + } +} + + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStatesStencilShadowMode(bool zfail) +{ + if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && + CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || + Transformation3DChanged) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + Transformation3DChanged = false; + + setTexture(0,0); + setTexture(1,0); + setTexture(2,0); + setTexture(3,0); + + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetVertexShader(D3DFVF_XYZ); + LastVertexType = (video::E_VERTEX_TYPE)(-1); + + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); + pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE ); + pID3DDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT); + + //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + } + + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) + { + // USE THE ZPASS METHOD + + pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); + + pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x1 ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); + pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); + } + else + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) + { + // USE THE ZFAIL METHOD + + pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); + + pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x0 ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); + pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); + } + + CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; +} + + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) +{ + if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); + //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + + Transformation3DChanged = false; + + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_STENCIL_FILL; +} + + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (!pID3DDevice) + return; + + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); + + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + + pID3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); + pID3DDevice->SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); + + pID3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D8 ); + + Transformation3DChanged = false; + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + } + + if (texture) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + + if (alphaChannel) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + + if (alpha) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + } + else + { + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + else + { + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + } + else + { + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_2D; +} + + +//! deletes all dynamic lights there are +void CD3D8Driver::deleteAllDynamicLights() +{ + for (s32 i=0; iLightEnable(i, false); + + LastSetLight = -1; + + CNullDriver::deleteAllDynamicLights(); +} + + + +//! adds a dynamic light +void CD3D8Driver::addDynamicLight(const SLight& dl) +{ + if ((u32)LastSetLight == Caps.MaxActiveLights-1) + return; + + CNullDriver::addDynamicLight(dl); + + D3DLIGHT8 light; + + switch (dl.Type) + { + case ELT_POINT: + light.Type = D3DLIGHT_POINT; + break; + case ELT_SPOT: + light.Type = D3DLIGHT_SPOT; + break; + case ELT_DIRECTIONAL: + light.Type = D3DLIGHT_DIRECTIONAL; + break; + } + + light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); + light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); + + light.Range = core::min_(dl.Radius, MaxLightDistance); + light.Falloff = dl.Falloff; + + light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); + light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); + light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); + + light.Attenuation0 = dl.Attenuation.X; + light.Attenuation1 = dl.Attenuation.Y; + light.Attenuation2 = dl.Attenuation.Z; + + light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; + light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; + + ++LastSetLight; + pID3DDevice->SetLight(LastSetLight, &light); + pID3DDevice->LightEnable(LastSetLight, true); +} + + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CD3D8Driver::getMaximalDynamicLightAmount() const +{ + return Caps.MaxActiveLights; +} + + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CD3D8Driver::setAmbientLight(const SColorf& color) +{ + if (!pID3DDevice) + return; + + AmbientLight = color; + D3DCOLOR col = color.toSColor().color; + pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); +} + + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CD3D8Driver::getName() const +{ + return L"Direct3D 8.1"; +} + + + +//! 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 +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CD3D8Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail) +{ + if (!StencilBuffer || !count) + return; + + setRenderStatesStencilShadowMode(zfail); + + if (!zfail) + { + // ZPASS Method + + // Draw front-side of shadow volume in stencil/z only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + } + else + { + // ZFAIL Method + + // Draw front-side of shadow volume in stencil/z only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + } +} + + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CD3D8Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!StencilBuffer) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); + vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); + vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); + vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,1,3,2}; + + setRenderStatesStencilFillMode( + leftUpEdge.getAlpha() < 255 || + rightUpEdge.getAlpha() < 255 || + leftDownEdge.getAlpha() < 255 || + rightDownEdge.getAlpha() < 255); + + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + + if (clearStencilBuffer) + pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); +} + + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CD3D8Driver::getMaximalPrimitiveCount() const +{ + return Caps.MaxPrimitiveCount; +} + + +//! Sets the fog mode. +void CD3D8Driver::setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, linearFog, start, end, density, pixelFog, rangeFog); + + if (!pID3DDevice) + return; + + pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); + + pID3DDevice->SetRenderState( + pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, + linearFog ? D3DFOG_LINEAR : D3DFOG_EXP); + + if(linearFog) + { + pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); + pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); + } + else + pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); + + if(!pixelFog) + pID3DDevice->SetRenderState (D3DRS_RANGEFOGENABLE, rangeFog); +} + +//! Draws a 3d line. +void CD3D8Driver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setVertexShader(EVT_STANDARD); + setRenderStates3DMode(); + video::S3DVertex v[2]; + v[0].Color = color; + v[1].Color = color; + v[0].Pos = start; + v[1].Pos = end; + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); +} + + +void CD3D8Driver::OnResize(const core::dimension2d& size) +{ + if (!pID3DDevice) + return; + + CNullDriver::OnResize(size); + reset(); +} + +//! Returns type of video driver +E_DRIVER_TYPE CD3D8Driver::getDriverType() const +{ + return EDT_DIRECT3D8; +} + +//! Returns the transformation set by setTransform +const core::matrix4& CD3D8Driver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + +//! Sets a vertex shader constant. +void CD3D8Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetVertexShaderConstant(startRegister, data, constantAmount); +} + +//! Sets a pixel shader constant. +void CD3D8Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetPixelShaderConstant(startRegister, data, constantAmount); +} + +//! Sets a constant for the vertex shader based on a name. +bool CD3D8Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + +//! Sets a constant for the pixel shader based on a name. +bool CD3D8Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + +//! Returns pointer to the IGPUProgrammingServices interface. +IGPUProgrammingServices* CD3D8Driver::getGPUProgrammingServices() +{ + return this; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CD3D8Driver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + CD3D8ShaderMaterialRenderer* r = new CD3D8ShaderMaterialRenderer( + pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* CD3D8Driver::getVideoDriver() +{ + return this; +} + + + +//! Clears the ZBuffer. +void CD3D8Driver::clearZBuffer() +{ + HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); + + if (FAILED(hr)) + os::Printer::log("CD3D8Driver clearZBuffer() failed.", ELL_WARNING); +} + +//! Returns an image created from the last rendered frame. +IImage* CD3D8Driver::createScreenShot() +{ + HRESULT hr; + + // query the screen dimensions of the current adapter + D3DDISPLAYMODE displayMode; + pID3DDevice->GetDisplayMode(&displayMode); + + // create the image surface to store the front buffer image [always A8R8G8B8] + LPDIRECT3DSURFACE8 lpSurface; + if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface))) + return 0; + + // read the front buffer into the image surface + if (FAILED(hr = pID3DDevice->GetFrontBuffer(lpSurface))) + { + lpSurface->Release(); + return 0; + } + + RECT clientRect; + { + POINT clientPoint; + clientPoint.x = 0; + clientPoint.y = 0; + + ClientToScreen( (HWND)getExposedVideoData().D3D8.HWnd, &clientPoint ); + + clientRect.left = clientPoint.x; + clientRect.top = clientPoint.y; + clientRect.right = clientRect.left + ScreenSize.Width; + clientRect.bottom = clientRect.top + ScreenSize.Height; + } + + // lock our area of the surface + D3DLOCKED_RECT lockedRect; + if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) + { + lpSurface->Release(); + return 0; + } + + // this could throw, but we aren't going to worry about that case very much + IImage* newImage = new CImage(ECF_A8R8G8B8, ScreenSize); + + // d3d pads the image, so we need to copy the correct number of bytes + u32* pPixels = (u32*)newImage->lock(); + if (pPixels) + { + u8 * sP = (u8 *)lockedRect.pBits; + u32* dP = (u32*)pPixels; + + for (s32 y = 0; y < ScreenSize.Height; ++y) + { + memcpy(dP, sP, ScreenSize.Width * 4); + + sP += lockedRect.Pitch; + dP += ScreenSize.Width; + } + + newImage->unlock(); + } + + // we can unlock and release the surface + lpSurface->UnlockRect(); + + // release the image surface + lpSurface->Release(); + + // return status of save operation to caller + return newImage; +} + + + +// returns the current size of the screen or rendertarget +core::dimension2d CD3D8Driver::getCurrentRenderTargetSize() +{ + if ( CurrentRendertargetSize.Width == 0 ) + return ScreenSize; + else + return CurrentRendertargetSize; +} + + + +// Set/unset a clipping plane. +bool CD3D8Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + if (index >= MaxUserClipPlanes) + return false; + + pID3DDevice->SetClipPlane(index, (const float*)&plane); + enableClipPlane(index, enable); + return true; +} + + +// Enable/disable a clipping plane. +void CD3D8Driver::enableClipPlane(u32 index, bool enable) +{ + if (index >= MaxUserClipPlanes) + return; + DWORD renderstate; + pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); + if (enable) + renderstate |= (1 << index); + else + renderstate &= ~(1 << index); + pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +//! creates a video driver +IVideoDriver* createDirectX8Driver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool stencilbuffer, + io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU, + bool vsync, bool antiAlias) +{ + CD3D8Driver* dx8 = new CD3D8Driver(screenSize, window, fullscreen, + stencilbuffer, io, pureSoftware); + + if (!dx8->initDriver(screenSize, window, bits, fullscreen, + pureSoftware, highPrecisionFPU, vsync, antiAlias)) + { + dx8->drop(); + dx8 = 0; + } + + return dx8; +} +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +} // end namespace video +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CD3D8Driver.h b/src/dep/src/irrlicht/CD3D8Driver.h new file mode 100644 index 0000000..df66af7 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8Driver.h @@ -0,0 +1,297 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_DIRECTX_8_H_INCLUDED__ +#define __C_VIDEO_DIRECTX_8_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#ifdef _IRR_WINDOWS_ + #define WIN32_LEAN_AND_MEAN + #include +#endif + +#ifdef _IRR_XBOX_PLATFORM_ + #include +#endif + +// always included for static createDriver function +#include "CNullDriver.h" +#include "IMaterialRendererServices.h" + +#include + +namespace irr +{ +namespace video +{ + class CD3D8Driver : public CNullDriver, IMaterialRendererServices + { + public: + + //! constructor + CD3D8Driver(const core::dimension2d& screenSize, HWND window, bool fullscreen, + bool stencibuffer, io::IFileSystem* io, bool pureSoftware=false, bool vsync=false); + + //! destructor + virtual ~CD3D8Driver(); + + //! applications must call this method before performing any rendering. returns false if failed. + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + //! applications must call this method after performing any rendering. returns false if failed. + virtual bool endScene( s32 windowId, core::rect* sourceRect=0 ); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=false, bool clearZBuffer=false, + SColor color=video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + //! draws a vertex primitive list + void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! initialises the Direct3D API + bool initDriver(const core::dimension2d& screenSize, HWND hwnd, + u32 bits, bool fullScreen, bool pureSoftware, + bool highPrecisionFPU, bool vsync, bool antiAlias); + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light + virtual void addDynamicLight(const SLight& light); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! 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 + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Sets the fog mode. + virtual void setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates); + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! Returns pointer to the IGPUProgrammingServices interface. + virtual IGPUProgrammingServices* getGPUProgrammingServices(); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Creates a render target texture. + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + private: + + // enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D, // 3d rendering mode + ERM_STENCIL_FILL, // stencil fill mode + ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode + ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode + }; + + //! sets right vertex shader + void setVertexShader(video::E_VERTEX_TYPE newType); + + //! sets the needed renderstates + bool setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + //! sets the needed renderstates + void setRenderStatesStencilFillMode(bool alpha); + + //! sets the needed renderstates + void setRenderStatesStencilShadowMode(bool zfail); + + //! sets the current Texture + bool setTexture(s32 stage, const video::ITexture* texture); + + //! resets the device + bool reset(); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name); + + // returns the current size of the screen or rendertarget + core::dimension2d getCurrentRenderTargetSize(); + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData); + + void createMaterialRenderers(); + + inline D3DCOLORVALUE colorToD3D(const SColor& col) + { + const f32 f = 1.0f / 255.0f; + D3DCOLORVALUE v; + v.r = col.getRed() * f; + v.g = col.getGreen() * f; + v.b = col.getBlue() * f; + v.a = col.getAlpha() * f; + return v; + } + + E_RENDER_MODE CurrentRenderMode; + D3DPRESENT_PARAMETERS present; + + SMaterial Material, LastMaterial; + bool ResetRenderStates; // bool to make all renderstates be reseted if set. + bool Transformation3DChanged; + bool StencilBuffer; + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + core::matrix4 Matrices[ETS_COUNT]; // matrices of the 3d mode we need to restore when we switch back from the 2d mode. + + HINSTANCE D3DLibrary; + IDirect3D8* pID3D; + IDirect3DDevice8* pID3DDevice; + + IDirect3DSurface8* PrevRenderTarget; + core::dimension2d CurrentRendertargetSize; + + D3DCAPS8 Caps; + + E_VERTEX_TYPE LastVertexType; + + D3DMATRIX UnitMatrix; + + u32 MaxTextureUnits; + u32 MaxUserClipPlanes; + f32 MaxLightDistance; + s32 LastSetLight; + bool DeviceLost; + + SColorf AmbientLight; + }; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CD3D8MaterialRenderer.h b/src/dep/src/irrlicht/CD3D8MaterialRenderer.h new file mode 100644 index 0000000..af2d8a9 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8MaterialRenderer.h @@ -0,0 +1,596 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +D3DMATRIX UnitMatrixD3D8; +D3DMATRIX SphereMapMatrixD3D8; + +//! Base class for all internal D3D8 material renderers +class CD3D8MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CD3D8MaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver) + : pID3DDevice(d3ddev), Driver(driver) + { + } + +protected: + + IDirect3DDevice8* pID3DDevice; + video::IVideoDriver* Driver; +}; + + +//! Solid material renderer +class CD3D8MaterialRenderer_SOLID : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SOLID(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + +//! Generic Texture Blend +class CD3D8MaterialRenderer_ONETEXTURE_BLEND : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || + material.MaterialTypeParam != lastMaterial.MaterialTypeParam || + resetAllRenderstates) + { + + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + unpack_texureBlendFunc ( srcFact, dstFact, modulate, material.MaterialTypeParam ); + + if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); + } + + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, getD3DModulate ( modulate ) ); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) ) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + } + + private: + + u32 getD3DBlend ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_ZERO: r = D3DBLEND_ZERO; break; + case EBF_ONE: r = D3DBLEND_ONE; break; + case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; + case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; + case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; + case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; + } + return r; + } + + u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_SRC_ALPHA: r = 1; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; + case EBF_DST_ALPHA: r = 1; break; + case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; + case EBF_SRC_ALPHA_SATURATE: r = 1; break; + } + return r; + } + + u32 getD3DModulate ( E_MODULATE_FUNC func ) const + { + u32 r = D3DTOP_MODULATE; + switch ( func ) + { + case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; + case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; + case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; + } + return r; + } + +}; + + +//! Solid 2 layer material renderer +class CD3D8MaterialRenderer_SOLID_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + + +//! Transparent add color material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + s32 refValue = core::floor32(material.MaterialTypeParam * 255.f); + if ( !refValue ) + refValue = 127; // default value + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, refValue); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + s32 refValue = core::floor32(material.MaterialTypeParam * 255.f); + if ( !refValue ) + refValue = 127; // default value + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF,refValue); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + + +//! material renderer for all kinds of linghtmaps +class CD3D8MaterialRenderer_LIGHTMAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_LIGHTMAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) + { + // with lighting + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + } + + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + + if (material.MaterialType == EMT_LIGHTMAP_ADD) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); + else + if (material.MaterialType == EMT_LIGHTMAP_M4) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE4X); + else + if (material.MaterialType == EMT_LIGHTMAP_M2) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); + else + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + +//! material renderer for detail maps +class CD3D8MaterialRenderer_DETAIL_MAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_DETAIL_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED); + pID3DDevice->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + + +//! sphere map material renderer +class CD3D8MaterialRenderer_SPHERE_MAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SPHERE_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D8 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D8MaterialRenderer_REFLECTION_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D8 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D8 ); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D8NormalMapRenderer.cpp b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.cpp new file mode 100644 index 0000000..da197b2 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.cpp @@ -0,0 +1,238 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "CD3D8NormalMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + + // 1.1 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D8 render path normal map vertex shader + const char D3D8_NORMAL_MAP_VSH[] = + ";Irrlicht Engine 0.8 D3D8 render path normal map vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "\n"\ + "; v0 - position \n"\ + "; v1 - normal \n"\ + "; v2 - color \n"\ + "; v3 - texture coord \n"\ + "; v4 - tangent \n"\ + "; v5 - binormal \n"\ + "\n"\ + "vs.1.1\n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ + "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D8 render path normal map pixel shader + const char D3D8_NORMAL_MAP_PSH[] = + ";Irrlicht Engine 0.8 D3D8 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + "ps.1.1 \n"\ + "tex t0 ; sample color map \n"\ + "tex t1 ; sample normal map\n"\ + "texcoord t2 ; fetch light vector 1\n"\ + "texcoord t3 ; fetch light vector 2\n"\ + "\n"\ + "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ + "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ + "\n"\ + "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ + "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ + "\n"\ + "mul r0, t0, r0 ; total luminance * base color\n"\ + "mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ + "\n"\ + ""; + + CD3D8NormalMapRenderer::CD3D8NormalMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CompiledShaders(true) + { + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D8NormalMapRenderer* nmr = (video::CD3D8NormalMapRenderer*)renderer; + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, D3D8_NORMAL_MAP_VSH, D3D8_NORMAL_MAP_PSH, EVT_TANGENTS); + } + } + + CD3D8NormalMapRenderer::~CD3D8NormalMapRenderer() + { + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } + } + + bool CD3D8NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + //! Returns the render capability of the material. + s32 CD3D8NormalMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + void CD3D8NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the + // driver and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h new file mode 100644 index 0000000..f998f42 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8NormalMapRenderer.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "CD3D8ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps +class CD3D8NormalMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D8NormalMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + ~CD3D8NormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + + //! stores if this shader compiled the shaders and is + //! allowed to delete them again. D3D8 lacks reference counting + //! support for shaders. + bool CompiledShaders; + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.cpp b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.cpp new file mode 100644 index 0000000..ec78e8b --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.cpp @@ -0,0 +1,306 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "CD3D8ParallaxMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + // 1.1/1.4 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D8 render path normal map vertex shader + const char D3D8_PARALLAX_MAP_VSH[] = + ";Irrlicht Engine 0.10 D3D8 render path parallax mapping vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c4: Eye position \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "; v0 ; position \n"\ + "; v1 ; normal \n"\ + "; v2 ; color \n"\ + "; v3 ; texture coord \n"\ + "; v4 ; tangent \n"\ + "; v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ + "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ + "add r1, -c4, r4 ; eye - vtxpos \n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ + "dp3 r10.y, r6, r1 \n"\ + "dp3 r10.z, r7, r1 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + ";mul r8, r8, c96 \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + ";mul r9, r9, c96 \n"\ + "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ + "rsq r10.w, r10.w \n"\ + "mul r10, r10, r10.w \n"\ + "mul r10, r10, c96 \n"\ + "\n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + + // Irrlicht Engine D3D8 render path normal map pixel shader version 1.4 + const char D3D8_PARALLAX_MAP_PSH[] = + ";Irrlicht Engine 0.10 D3D8 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.1.4 \n"\ + " \n"\ + ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ + " \n"\ + "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "texcrd r4.xyz, t4 ; fetch eye vector \n"\ + "texcrd r0.xyz, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to reduce swimming effect: \n"\ + "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ + "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "phase \n"\ + " \n"\ + "texld r0, r2 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2 ; sample normal map \n"\ + "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ + "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "dp3_sat r2, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "+mov r0.a, v0.a ; write original alpha value \n"\ + "\n"; + + + CD3D8ParallaxMapRenderer::CD3D8ParallaxMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CompiledShaders(true), CurrentScale(0.0f) + { + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled parallax map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D8ParallaxMapRenderer* nmr = (video::CD3D8ParallaxMapRenderer*)renderer; + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, D3D8_PARALLAX_MAP_VSH, D3D8_PARALLAX_MAP_PSH, EVT_TANGENTS); + } + } + + CD3D8ParallaxMapRenderer::~CD3D8ParallaxMapRenderer() + { + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } + } + + bool CD3D8ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + void CD3D8ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) + { + CD3D8ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; + } + + //! Returns the render capability of the material. + s32 CD3D8ParallaxMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + void CD3D8ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set eye position + + // The viewpoint is at (0., 0., 0.) in eye space. + // Turning this into a vector [0 0 0 1] and multiply it by + // the inverse of the view matrix, the resulting vector is the + // object space location of the camera. + + f32 floats[4] = {0,0,0,1}; + core::matrix4 minv(driver->getTransform(video::ETS_VIEW)); + minv.makeInverse(); + minv.multiplyWith1x4Matrix(floats); + services->setVertexShaderConstant(floats, 4, 1); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + f32 c96[] = {-1, 1, 1, 1}; + services->setVertexShaderConstant(c96, 96, 1); + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, 0}; + services->setPixelShaderConstant(c6, 6, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h new file mode 100644 index 0000000..cd5d316 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8ParallaxMapRenderer.h @@ -0,0 +1,61 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "CD3D8ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for parallax maps +class CD3D8ParallaxMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D8ParallaxMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + ~CD3D8ParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + + //! stores if this shader compiled the shaders and is + //! allowed to delete them again. D3D8 lacks reference counting + //! support for shaders. + bool CompiledShaders; + + f32 CurrentScale; +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp new file mode 100644 index 0000000..add9eab --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.cpp @@ -0,0 +1,316 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CD3D8ShaderMaterialRenderer.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include +#include +#pragma comment (lib, "d3dx8.lib") + +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + +namespace irr +{ +namespace video +{ + +//! Public constructor +CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD); +} + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData) +: pID3DDevice(d3ddev), Driver(driver), BaseMaterial(baseMaterial), CallBack(callback), + VertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + + +//! Destructor +CD3D8ShaderMaterialRenderer::~CD3D8ShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + pID3DDevice->DeleteVertexShader(VertexShader); + + if (PixelShader) + pID3DDevice->DeletePixelShader(PixelShader); + + if (BaseMaterial) + BaseMaterial->drop (); +} + + +void CD3D8ShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram, E_VERTEX_TYPE type) +{ + outMaterialTypeNr = -1; + + // create vertex shader + if (!createVertexShader(vertexShaderProgram, type)) + return; + + // create pixel shader + if (!createPixelShader(pixelShaderProgram)) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader)) + CallBack->OnSetConstants(service, UserData); + + return true; +} + + +void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexShader) + { + // We do not need to save and reset the old vertex shader, because + // in D3D8, this is mixed up with the fvf, and this is set by the driver + // every time. + //pID3DDevice->GetVertexShader(&OldVertexShader); + + // set new vertex shader + if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) + os::Printer::log("Could not set vertex shader."); + } + + // set new pixel shader + if (PixelShader) + { + if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) + os::Printer::log("Could not set pixel shader."); + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +void CD3D8ShaderMaterialRenderer::OnUnsetMaterial() +{ + // We do not need to save and reset the old vertex shader, because + // in D3D8, this is mixed up with the fvf, and this is set by the driver + // every time. + // if (VertexShader) + // pID3DDevice->SetVertexShader(OldVertexShader); + + if (PixelShader) + pID3DDevice->SetPixelShader(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. The scene managment needs to know this +//! for being able to sort the materials by opaque and transparent. +bool CD3D8ShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + D3DXAssembleShader(pxsh, strlen(pxsh), 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(pxsh, strlen(pxsh), 1, f); + fflush(f); + fclose(f); + + D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); + + #endif + + if (errors) + { + // print out compilation errors. + os::Printer::log("Pixel shader compilation failed:"); + os::Printer::log((c8*)errors->GetBufferPointer()); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) + { + os::Printer::log("Could not create pixel shader."); + code->Release(); + return false; + } + + code->Release(); + return true; +} + + + +bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX_TYPE type) +{ + if (!vtxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + D3DXAssembleShader(vtxsh, strlen(vtxsh), 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vtxsh, strlen(vtxsh), 1, f); + fflush(f); + fclose(f); + + D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); + + #endif + + + if (errors) + { + // print out compilation errors. + os::Printer::log("Vertex shader compilation failed:"); + os::Printer::log((c8*)errors->GetBufferPointer()); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + DWORD* decl = 0; + + DWORD dwStdDecl[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), // position 0 + D3DVSD_REG(1, D3DVSDT_FLOAT3), // normal 1 + D3DVSD_REG(2, D3DVSDT_D3DCOLOR ),// color 2 + D3DVSD_REG(3, D3DVSDT_FLOAT2 ), // tex1 3 + D3DVSD_REG(4, D3DVSDT_FLOAT2 ), // tex2 4 + D3DVSD_END() + }; + + DWORD dwTngtDecl[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0 , D3DVSDT_FLOAT3), // position 0 + D3DVSD_REG(1 , D3DVSDT_FLOAT3), // normal 1 + D3DVSD_REG(2 , D3DVSDT_D3DCOLOR ),// color 2 + D3DVSD_REG(3 , D3DVSDT_FLOAT2 ), // tex1 3 + D3DVSD_REG(4, D3DVSDT_FLOAT3 ), // tangent 4 + D3DVSD_REG(5, D3DVSDT_FLOAT3 ), // binormal 5 + D3DVSD_END() + }; + + if (type == EVT_TANGENTS) + decl = dwTngtDecl; + else + decl = dwStdDecl; + + if (FAILED(pID3DDevice->CreateVertexShader(decl, + (DWORD*)code->GetBufferPointer(), &VertexShader, 0))) + { + os::Printer::log("Could not create vertex shader."); + code->Release(); + return false; + } + + code->Release(); + return true; +} + + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h new file mode 100644 index 0000000..91bd8a4 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8ShaderMaterialRenderer.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include +#include + +#include "IMaterialRenderer.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with D3D8 +class CD3D8ShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Public constructor + CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + ~CD3D8ShaderMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual void OnUnsetMaterial(); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData=0); + + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + E_VERTEX_TYPE type); + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const char* vtxsh, E_VERTEX_TYPE type); + + IDirect3DDevice8* pID3DDevice; + video::IVideoDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + DWORD VertexShader; + DWORD OldVertexShader; + DWORD PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D8Texture.cpp b/src/dep/src/irrlicht/CD3D8Texture.cpp new file mode 100644 index 0000000..d073488 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8Texture.cpp @@ -0,0 +1,646 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D8Texture.h" +#include "CD3D8Driver.h" +#include "os.h" + + +#ifndef _IRR_COMPILE_WITH_DIRECT3D_9_ +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +//#define _IRR_USE_D3DXFilterTexture_ +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include + +#ifdef _IRR_USE_D3DXFilterTexture_ +#pragma comment (lib, "d3dx8.lib") +#endif // _IRR_USE_D3DXFilterTexture_ + +namespace irr +{ +namespace video +{ + +//! rendertarget constructor +CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, core::dimension2d size, const char* name) +: ITexture(name), Image(0), Texture(0), RTTSurface(0), Driver(driver), + TextureSize(size), ImageSize(size), Pitch(0), + HasMipMaps(false), IsRenderTarget(true) +{ + #ifdef _DEBUG + setDebugName("CD3D8Texture"); + #endif + + Device=driver->getExposedVideoData().D3D8.D3DDev8; + if (Device) + Device->AddRef(); + + createRenderTarget(); +} + + +//! constructor +CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver, + u32 flags, const char* name) +: ITexture(name), Image(image), Texture(0), RTTSurface(0), Driver(driver), +TextureSize(0,0), ImageSize(0,0), Pitch(0), +HasMipMaps(false), IsRenderTarget(false) +{ + #ifdef _DEBUG + setDebugName("CD3D8Texture"); + #endif + + const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + Device=driver->getExposedVideoData().D3D8.D3DDev8; + if (Device) + Device->AddRef(); + + if (Image) + { + Image->grab(); + + if (createTexture(flags)) + { + if (copyTexture() && generateMipLevels) + { + // create mip maps. + + #ifndef _IRR_USE_D3DXFilterTexture_ + // The D3DXFilterTexture function seems to get linked wrong when + // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. + // So mipmapgeneration is replaced with my own bad generation in d3d 8 when + // compiling with both D3D 8 and 9. + HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); + if (FAILED(hr)) + os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING); + else + HasMipMaps = true; + #else + createMipMaps(); + HasMipMaps = true; + #endif + } + } + else + os::Printer::log("Could not create DIRECT3D8 Texture.", ELL_WARNING); + } +} + + +//! destructor +CD3D8Texture::~CD3D8Texture() +{ + if (Device) + Device->Release(); + + if (Image) + Image->drop(); + + if (Texture) + Texture->Release(); + + if (RTTSurface) + RTTSurface->Release(); +} + + +//! creates the hardware texture +bool CD3D8Texture::createTexture(u32 flags) +{ + core::dimension2d optSize; + ImageSize = Image->getDimension(); + + if (Driver->queryFeature(EVDF_TEXTURE_NPOT)) + optSize=ImageSize; + else + { + optSize.Width = getTextureSizeFromImageSize(ImageSize.Width); + optSize.Height = getTextureSizeFromImageSize(ImageSize.Height); + } + + HRESULT hr; + D3DFORMAT format = D3DFMT_A1R5G5B5; + + switch(getTextureFormatFromFlags(flags)) + { + case ETCF_ALWAYS_16_BIT: + format = D3DFMT_A1R5G5B5; break; + case ETCF_ALWAYS_32_BIT: + format = D3DFMT_A8R8G8B8; break; + case ETCF_OPTIMIZED_FOR_QUALITY: + { + switch(Image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_A8R8G8B8: + format = D3DFMT_A8R8G8B8; break; + case ECF_A1R5G5B5: + case ECF_R5G6B5: + format = D3DFMT_A1R5G5B5; break; + } + } + break; + case ETCF_OPTIMIZED_FOR_SPEED: + format = D3DFMT_A1R5G5B5; break; + } + if (false && Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) + { + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_R8G8B8; + else if (format == D3DFMT_A1R5G5B5) + format = D3DFMT_R5G6B5; + } + + const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture); + + if (FAILED(hr)) + { + // try brute force 16 bit + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_A1R5G5B5; + else if (format == D3DFMT_R8G8B8) + format = D3DFMT_R5G6B5; + else + return false; + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture); + } + + ColorFormat = getColorFormatFromD3DFormat(format); + return (SUCCEEDED(hr)); +} + + + +//! copies the image to the texture +bool CD3D8Texture::copyTexture() +{ + if (Texture && Image) + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + + TextureSize.Width = desc.Width; + TextureSize.Height = desc.Height; + + D3DLOCKED_RECT rect; + HRESULT hr = Texture->LockRect(0, &rect, 0, 0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR); + return false; + } + + Pitch = rect.Pitch; + Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); + + hr = Texture->UnlockRect(0); + if (FAILED(hr)) + { + os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR); + return false; + } + } + + return true; +} + + +//! lock function +void* CD3D8Texture::lock() +{ + if (!Texture) + return 0; + + HRESULT hr; + D3DLOCKED_RECT rect; + if(!IsRenderTarget) + { + hr = Texture->LockRect(0, &rect, 0, 0); + } + else + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + if (!RTTSurface) + { + hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + } + + IDirect3DSurface8 *surface = NULL; + hr = Texture->GetSurfaceLevel(0, &surface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + hr = Device->CopyRects(surface, NULL, 0, RTTSurface, NULL); + surface->Release(); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + hr = RTTSurface->LockRect(&rect, NULL, 0); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + return rect.pBits; + } + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + + return rect.pBits; +} + + + +//! unlock function +void CD3D8Texture::unlock() +{ + if (!Texture) + return; + + if (!IsRenderTarget) + Texture->UnlockRect(0); + else if (RTTSurface) + RTTSurface->UnlockRect(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CD3D8Texture::getOriginalSize() const +{ + return ImageSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CD3D8Texture::getSize() const +{ + return TextureSize; +} + + +//! returns the size of a texture which would be the optimize size for rendering it +inline s32 CD3D8Texture::getTextureSizeFromImageSize(s32 size) const +{ + s32 ts = 0x01; + + while(ts < size) + ts <<= 1; + + return ts; +} + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CD3D8Texture::getDriverType() const +{ + return EDT_DIRECT3D8; +} + + + +//! returns color format of texture +ECOLOR_FORMAT CD3D8Texture::getColorFormat() const +{ + return ColorFormat; +} + + + +//! returns pitch of texture (in bytes) +u32 CD3D8Texture::getPitch() const +{ + return Pitch; +} + + + +//! returns the DIRECT3D8 Texture +IDirect3DTexture8* CD3D8Texture::getDX8Texture() const +{ + return Texture; +} + + +//! returns if texture has mipmap levels +bool CD3D8Texture::hasMipMaps() const +{ + return HasMipMaps; +} + + +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +bool CD3D8Texture::createMipMaps(u32 level) +{ + if (level==0) + return true; + + IDirect3DSurface8* upperSurface = 0; + IDirect3DSurface8* lowerSurface = 0; + + // get upper level + HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); + if (FAILED(hr) || !upperSurface) + { + os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); + return false; + } + + // get lower level + hr = Texture->GetSurfaceLevel(level, &lowerSurface); + if (FAILED(hr) || !lowerSurface) + { + os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); + upperSurface->Release(); + return false; + } + + D3DSURFACE_DESC upperDesc, lowerDesc; + upperSurface->GetDesc(&upperDesc); + lowerSurface->GetDesc(&lowerDesc); + + D3DLOCKED_RECT upperlr; + D3DLOCKED_RECT lowerlr; + + // lock upper surface + if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) + { + os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); + upperSurface->Release(); + lowerSurface->Release(); + return false; + } + + // lock lower surface + if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) + { + os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); + upperSurface->UnlockRect(); + upperSurface->Release(); + lowerSurface->Release(); + return false; + } + + if (upperDesc.Format != lowerDesc.Format) + { + os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); + } + else + { + if (upperDesc.Format == D3DFMT_A1R5G5B5) + copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + if (upperDesc.Format == D3DFMT_A8R8G8B8) + copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); + } + + bool result=true; + // unlock + if (FAILED(upperSurface->UnlockRect())) + result=false; + if (FAILED(lowerSurface->UnlockRect())) + result=false; + + // release + upperSurface->Release(); + lowerSurface->Release(); + + if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) + return result; // stop generating levels + + // generate next level + return createMipMaps(level+1); +} + + +ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format) +{ + switch(format) + { + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + Pitch = TextureSize.Width * 2; + return ECF_A1R5G5B5; + break; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + Pitch = TextureSize.Width * 4; + return ECF_A8R8G8B8; + break; + case D3DFMT_R5G6B5: + Pitch = TextureSize.Width * 2; + return ECF_R5G6B5; + break; + default: + return (ECOLOR_FORMAT)0; + }; +} + + + +void CD3D8Texture::copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, + s32 pitchsrc, s32 pitchtgt) const +{ + u16 c; + + for (int x=0; x>= 2; + r >>= 2; + g >>= 2; + b >>= 2; + + c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff); + *(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color; + } + } +} + + + +void CD3D8Texture::createRenderTarget() +{ + TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width); + TextureSize.Height = getTextureSizeFromImageSize(TextureSize.Height); + + // get backbuffer format to create the render target in the + // same format + + IDirect3DSurface8* bb; + D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; + + if (!FAILED(Device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &bb))) + { + D3DSURFACE_DESC desc; + bb->GetDesc(&desc); + d3DFormat = desc.Format; + + if (d3DFormat == D3DFMT_X8R8G8B8) + d3DFormat = D3DFMT_A8R8G8B8; + + bb->Release(); + } + else + { + os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", + ELL_WARNING); + return; + } + + // create texture + HRESULT hr; + + hr = Device->CreateTexture( + TextureSize.Width, + TextureSize.Height, + 1, // mip map level count, we don't want mipmaps here + D3DUSAGE_RENDERTARGET, + d3DFormat, + D3DPOOL_DEFAULT, + &Texture); + + // get irrlicht format from D3D format + ColorFormat = getColorFormatFromD3DFormat(d3DFormat); + + if (FAILED(hr)) + os::Printer::log("Could not create render target texture"); +} + + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CD3D8Texture::regenerateMipMapLevels() +{ + if (HasMipMaps) + createMipMaps(); +} + + +//! returns if it is a render target +bool CD3D8Texture::isRenderTarget() const +{ + return IsRenderTarget; +} + +//! Returns pointer to the render target surface +IDirect3DSurface8* CD3D8Texture::getRenderTargetSurface() +{ + if (!IsRenderTarget) + return 0; + + IDirect3DSurface8 *pRTTSurface = 0; + if (Texture) + Texture->GetSurfaceLevel(0, &pRTTSurface); + + if (pRTTSurface) + pRTTSurface->Release(); + + return pRTTSurface; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/dep/src/irrlicht/CD3D8Texture.h b/src/dep/src/irrlicht/CD3D8Texture.h new file mode 100644 index 0000000..a5c2679 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D8Texture.h @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DIRECTX8_TEXTURE_H_INCLUDED__ +#define __C_DIRECTX8_TEXTURE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "ITexture.h" +#include "IImage.h" +#include + +namespace irr +{ +namespace video +{ + +class CD3D8Driver; + +/*! + interface for a Video Driver dependent Texture. +*/ +class CD3D8Texture : public ITexture +{ +public: + + //! constructor + CD3D8Texture(IImage* image, CD3D8Driver* driver, + u32 flags, const char* name); + + //! rendertarget constructor + CD3D8Texture(CD3D8Driver* driver, core::dimension2d size, const char* name); + + //! destructor + virtual ~CD3D8Texture(); + + //! lock function + virtual void* lock(); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! returns the DIRECT3D8 Texture + IDirect3DTexture8* getDX8Texture() const; + + //! returns if texture has mipmap levels + bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(); + + //! returns if it is a render target + virtual bool isRenderTarget() const; + + //! Returns pointer to the render target surface + IDirect3DSurface8* getRenderTargetSurface(); + +private: + + void createRenderTarget(); + + //! returns the size of a texture which would be the optimize size for rendering it + inline s32 getTextureSizeFromImageSize(s32 size) const; + + //! creates the hardware texture + bool createTexture(u32 flags); + + //! copies the image to the texture + bool copyTexture(); + + //! convert color formats + ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format); + + bool createMipMaps(u32 level=1); + + void copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + void copy32BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + IImage* Image; + IDirect3DDevice8* Device; + IDirect3DTexture8* Texture; + IDirect3DSurface8* RTTSurface; + CD3D8Driver* Driver; + core::dimension2d TextureSize; + core::dimension2d ImageSize; + s32 Pitch; + ECOLOR_FORMAT ColorFormat; + bool HasMipMaps; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#endif // __C_DIRECTX8_TEXTURE_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CD3D9Driver.cpp b/src/dep/src/irrlicht/CD3D9Driver.cpp new file mode 100644 index 0000000..e85342d --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9Driver.cpp @@ -0,0 +1,2215 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D9Driver.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "os.h" +#include "S3DVertex.h" +#include "CD3D9Texture.h" +#include "CImage.h" +#include "CD3D9MaterialRenderer.h" +#include "CD3D9ShaderMaterialRenderer.h" +#include "CD3D9NormalMapRenderer.h" +#include "CD3D9ParallaxMapRenderer.h" +#include "CD3D9HLSLMaterialRenderer.h" +#include + +namespace irr +{ +namespace video +{ + +//! constructor +CD3D9Driver::CD3D9Driver(const core::dimension2d& screenSize, HWND window, + bool fullscreen, bool stencilbuffer, + io::IFileSystem* io, bool pureSoftware) +: CNullDriver(io, screenSize), CurrentRenderMode(ERM_NONE), + ResetRenderStates(true), Transformation3DChanged(false), StencilBuffer(stencilbuffer), + D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), + LastVertexType((video::E_VERTEX_TYPE)-1), MaxTextureUnits(0), MaxUserClipPlanes(0), + MaxLightDistance(sqrtf(FLT_MAX)), LastSetLight(-1), DeviceLost(false), + Fullscreen(fullscreen) +{ + #ifdef _DEBUG + setDebugName("CD3D9Driver"); + #endif + + printVersion(); + + for (u32 i=0; iRelease(); + + if (pID3D) + pID3D->Release(); +} + + + +void CD3D9Driver::createMaterialRenderers() +{ + // create D3D9 material renderers + + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); + + // add the same renderer for all lightmap types + + CD3D9MaterialRenderer_LIGHTMAP* lmr = new CD3D9MaterialRenderer_LIGHTMAP(pID3DDevice, this); + addMaterialRenderer(lmr); // for EMT_LIGHTMAP: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: + lmr->drop(); + + // add remaining fixed function pipeline material renderers + + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); + + // add normal map renderers + + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + + // add parallax map renderers + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + + // add basic 1 texture blending + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); + +} + + + +//! initialises the Direct3D API +bool CD3D9Driver::initDriver(const core::dimension2d& screenSize, HWND hwnd, + u32 bits, bool fullScreen, bool pureSoftware, + bool highPrecisionFPU, bool vsync, bool antiAlias) +{ + HRESULT hr; + Fullscreen = fullScreen; + + if (!pID3D) + { + D3DLibrary = LoadLibrary( "d3d9.dll" ); + + if (!D3DLibrary) + { + os::Printer::log("Error, could not load d3d9.dll.", ELL_ERROR); + return false; + } + + typedef IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT); + D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9"); + + if (!d3dCreate) + { + os::Printer::log("Error, could not get proc adress of Direct3DCreate9.", ELL_ERROR); + return false; + } + + //just like pID3D = Direct3DCreate9(D3D_SDK_VERSION); + pID3D = (*d3dCreate)(D3D_SDK_VERSION); + + if (!pID3D) + { + os::Printer::log("Error initializing D3D.", ELL_ERROR); + return false; + } + } + + // print device information + D3DADAPTER_IDENTIFIER9 dai; + if (!FAILED(pID3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &dai))) + { + char tmp[512]; + + s32 Product = HIWORD(dai.DriverVersion.HighPart); + s32 Version = LOWORD(dai.DriverVersion.HighPart); + s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); + s32 Build = LOWORD(dai.DriverVersion.LowPart); + + sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, + SubVersion, Build); + os::Printer::log(tmp, ELL_INFORMATION); + } + + D3DDISPLAYMODE d3ddm; + hr = pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); + if (FAILED(hr)) + { + os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); + return false; + } + + ZeroMemory(&present, sizeof(present)); + + present.BackBufferCount = 1; + present.EnableAutoDepthStencil = TRUE; + if (vsync) + present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else + present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + if (fullScreen) + { + present.BackBufferWidth = screenSize.Width; + present.BackBufferHeight = screenSize.Height; + // request 32bit mode if user specified 32 bit, added by Thomas Stuefe + if (bits == 32) + present.BackBufferFormat = D3DFMT_X8R8G8B8; + else + present.BackBufferFormat = D3DFMT_R5G6B5; + present.SwapEffect = D3DSWAPEFFECT_FLIP; + present.Windowed = FALSE; + present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + } + else + { + present.BackBufferFormat = d3ddm.Format; + present.SwapEffect = D3DSWAPEFFECT_COPY; + present.Windowed = TRUE; + } + + D3DDEVTYPE devtype = D3DDEVTYPE_HAL; + #ifndef _IRR_D3D_NO_SHADER_DEBUGGING + devtype = D3DDEVTYPE_REF; + #endif + + // enable anti alias if possible and desired + if (antiAlias) + { + DWORD qualityLevels = 0; + + if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, + devtype, present.BackBufferFormat, !fullScreen, + D3DMULTISAMPLE_4_SAMPLES, &qualityLevels))) + { + // enable multi sampling + present.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; + present.MultiSampleQuality = qualityLevels-1; + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + else + if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, + devtype, present.BackBufferFormat, !fullScreen, + D3DMULTISAMPLE_2_SAMPLES, &qualityLevels))) + { + // enable multi sampling + present.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES; + present.MultiSampleQuality = qualityLevels-1; + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + else + if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, + devtype, present.BackBufferFormat, !fullScreen, + D3DMULTISAMPLE_NONMASKABLE, &qualityLevels))) + { + // enable non maskable multi sampling + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + present.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; + present.MultiSampleQuality = qualityLevels-1; + } + else + { + os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); + antiAlias = false; + } + } + + // check stencil buffer compatibility + if (StencilBuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D24S8; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X4S4; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D15S1; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + } + } + else + if(FAILED(pID3D->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) + { + os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + } + // do not use else here to cope with flag change in previous block + if (!StencilBuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D32; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X8; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D16; + if(FAILED(pID3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); + return false; + } + } + } + } + + // create device + + DWORD fpuPrecision = highPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; + if (pureSoftware) + { + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, + fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR); + } + else + { + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, devtype, hwnd, + fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D9 device.", ELL_ERROR); + } + + if (!pID3DDevice) + { + os::Printer::log("Was not able to create DIRECT3D9 device.", ELL_ERROR); + return false; + } + + // get caps + pID3DDevice->GetDeviceCaps(&Caps); + + // disable stencilbuffer if necessary + if (StencilBuffer && + (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) + { + os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); + StencilBuffer = false; + } + + // set default vertex shader + setVertexShader(EVT_STANDARD); + + // enable antialiasing + if (antiAlias) + pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + + // set fog mode + setFog(FogColor, LinearFog, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); + + // set exposed data + ExposedData.D3D9.D3D9 = pID3D; + ExposedData.D3D9.D3DDev9 = pID3DDevice; + ExposedData.D3D9.HWnd = reinterpret_cast(hwnd); + + ResetRenderStates = true; + + // create materials + createMaterialRenderers(); + + MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); + MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; + + // set the renderstates + setRenderStates3DMode(); + + // set maximal anisotropy + pID3DDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, min(16ul, Caps.MaxAnisotropy)); + pID3DDevice->SetSamplerState(1, D3DSAMP_MAXANISOTROPY, min(16ul, Caps.MaxAnisotropy)); + pID3DDevice->SetSamplerState(2, D3DSAMP_MAXANISOTROPY, min(16ul, Caps.MaxAnisotropy)); + pID3DDevice->SetSamplerState(3, D3DSAMP_MAXANISOTROPY, min(16ul, Caps.MaxAnisotropy)); + + // so far so good. + return true; +} + + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color); + HRESULT hr; + + if (!pID3DDevice) + return false; + + if (DeviceLost) + { + if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) + { + if (hr == D3DERR_DEVICELOST) + return false; + + if (hr == D3DERR_DEVICENOTRESET) + reset(); + return false; + } + } + + DWORD flags = 0; + + if (backBuffer) + flags |= D3DCLEAR_TARGET; + + if (zBuffer) + flags |= D3DCLEAR_ZBUFFER; + + if (StencilBuffer) + flags |= D3DCLEAR_STENCIL; + + hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); + if (FAILED(hr)) + os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING); + + hr = pID3DDevice->BeginScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D9 begin scene failed.", ELL_WARNING); + return false; + } + + return true; +} + + + +//! applications must call this method after performing any rendering. returns false if failed. +bool CD3D9Driver::endScene( s32 windowId, core::rect* sourceRect ) +{ + if (DeviceLost) + return false; + + CNullDriver::endScene(); + + HRESULT hr = pID3DDevice->EndScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D9 end scene failed.", ELL_WARNING); + return false; + } + + RECT* srcRct = 0; + RECT sourceRectData; + if ( sourceRect ) + { + srcRct = &sourceRectData; + sourceRectData.left = sourceRect->UpperLeftCorner.X; + sourceRectData.top = sourceRect->UpperLeftCorner.Y; + sourceRectData.right = sourceRect->LowerRightCorner.X; + sourceRectData.bottom = sourceRect->LowerRightCorner.Y; + } + + hr = pID3DDevice->Present(srcRct, NULL, (HWND)windowId, NULL); + + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("DIRECT3D9 device lost.", ELL_WARNING); + } + else + if (FAILED(hr) && hr != D3DERR_INVALIDCALL) + { + os::Printer::log("DIRECT3D9 present failed.", ELL_WARNING); + return false; + } + + return true; +} + + + +//! queries the features of the driver, returns true if feature is available +bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_MULTITEXTURE: + case EVDF_BILINEAR_FILTER: + return true; + case EVDF_RENDER_TO_TARGET: + return Caps.NumSimultaneousRTs > 0; + case EVDF_HARDWARE_TL: + return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; + case EVDF_MIP_MAP: + return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; + case EVDF_MIP_MAP_AUTO_UPDATE: + // always return false because a lot of drivers claim they do + // this but actually don't do this at all. + return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0; + case EVDF_STENCIL_BUFFER: + return StencilBuffer && Caps.StencilCaps; + case EVDF_VERTEX_SHADER_1_1: + return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); + case EVDF_VERTEX_SHADER_2_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); + case EVDF_VERTEX_SHADER_3_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); + case EVDF_PIXEL_SHADER_1_1: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); + case EVDF_PIXEL_SHADER_1_2: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); + case EVDF_PIXEL_SHADER_1_3: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); + case EVDF_PIXEL_SHADER_1_4: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); + case EVDF_PIXEL_SHADER_2_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); + case EVDF_PIXEL_SHADER_3_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); + case EVDF_HLSL: + return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); + case EVDF_TEXTURE_NPOT: + return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; + default: + return false; + }; +} + + + +//! sets transformation +void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + Transformation3DChanged = true; + + switch(state) + { + case ETS_VIEW: + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_WORLD: + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_PROJECTION: + pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_TEXTURE_0: + case ETS_TEXTURE_1: + case ETS_TEXTURE_2: + case ETS_TEXTURE_3: + pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + if (mat.isIdentity()) + pID3DDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), &UnitMatrixD3D9 ); + else + pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), + (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_COUNT: + break; + } + + Matrices[state] = mat; +} + + + +//! sets the current Texture +bool CD3D9Driver::setTexture(s32 stage, const video::ITexture* texture) +{ + if (CurrentTexture[stage] == texture) + return true; + + if (texture && texture->getDriverType() != EDT_DIRECT3D9) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + CurrentTexture[stage] = texture; + + if (!texture) + { + pID3DDevice->SetTexture(stage, 0); + pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + } + else + { + pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture()); + } + return true; +} + + + +//! sets a material +void CD3D9Driver::setMaterial(const SMaterial& material) +{ + Material = material; + + for (u32 i=0; igetDriverType() != EDT_DIRECT3D9) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + // check for valid render target + + CD3D9Texture* tex = (CD3D9Texture*)texture; + + if (texture && !tex->isRenderTarget()) + { + os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); + return false; + } + + if (texture && (tex->getSize().Width > ScreenSize.Width || + tex->getSize().Height > ScreenSize.Height )) + { + os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); + return false; + } + + // check if we should set the previous RT back + + bool ret = true; + + if (tex == 0) + { + if (PrevRenderTarget) + { + if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget))) + { + os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); + ret = false; + } + + CurrentRendertargetSize = core::dimension2d(0,0); + PrevRenderTarget->Release(); + PrevRenderTarget = 0; + } + } + else + { + // we want to set a new target. so do this. + + // store previous target + + if (!PrevRenderTarget) + if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) + { + os::Printer::log("Could not get previous render target.", ELL_ERROR); + return false; + } + + // set new render target + + if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface()))) + { + os::Printer::log("Error: Could not set render target.", ELL_ERROR); + return false; + } + + CurrentRendertargetSize = tex->getSize(); + } + + if (clearBackBuffer || clearZBuffer) + { + DWORD flags = 0; + + if (clearBackBuffer) + flags |= D3DCLEAR_TARGET; + + if (clearZBuffer) + flags |= D3DCLEAR_ZBUFFER; + + pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); + } + + return ret; +} + + + +//! sets a viewport +void CD3D9Driver::setViewPort(const core::rect& area) +{ + core::rect vp = area; + core::rect rendert(0,0, ScreenSize.Width, ScreenSize.Height); + vp.clipAgainst(rendert); + + D3DVIEWPORT9 viewPort; + viewPort.X = vp.UpperLeftCorner.X; + viewPort.Y = vp.UpperLeftCorner.Y; + viewPort.Width = vp.getWidth(); + viewPort.Height = vp.getHeight(); + viewPort.MinZ = 0.0f; + viewPort.MaxZ = 1.0f; + + HRESULT hr = D3DERR_INVALIDCALL; + if (vp.getHeight()>0 && vp.getWidth()>0) + hr = pID3DDevice->SetViewport(&viewPort); + + if (FAILED(hr)) + os::Printer::log("Failed setting the viewport.", ELL_WARNING); + + ViewPort = vp; +} + + + +//! gets the area of the current viewport +const core::rect& CD3D9Driver::getViewPort() const +{ + return ViewPort; +} + + + +//! draws a vertex primitive list +void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType); + + if (!vertexCount || !primitiveCount) + return; + + setVertexShader(vType); + + const u32 stride = getVertexPitchFromType(vType); + + if (setRenderStates3DMode()) + { + switch (pType) + { + case scene::EPT_POINT_SPRITES: + case scene::EPT_POINTS: + { + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&Material.Thickness)); + f32 tmp=1.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); + tmp=0.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); + } + break; + case scene::EPT_LINE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_LINE_LOOP: + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + u16 tmpIndices[] = {0, primitiveCount}; + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + 1, tmpIndices, D3DFMT_INDEX16, vertices, stride); + } + break; + case scene::EPT_LINES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLE_FAN: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + case scene::EPT_TRIANGLES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, + primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); + break; + } + } +} + + + +void CD3D9Driver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + video::SColor* colors, bool useAlphaChannelOfTexture) +{ + if(!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; + tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; + tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; + tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + core::rect npos; + f32 xFact = 2.0f / ( renderTargetSize.Width ); + f32 yFact = 2.0f / ( renderTargetSize.Height ); + npos.UpperLeftCorner.X = ( destRect.UpperLeftCorner.X * xFact ) - 1.0f; + npos.UpperLeftCorner.Y = 1.0f - ( destRect.UpperLeftCorner.Y * yFact ); + npos.LowerRightCorner.X = ( destRect.LowerRightCorner.X * xFact ) - 1.0f; + npos.LowerRightCorner.Y = 1.0f - ( destRect.LowerRightCorner.Y * yFact ); + + video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + video::SColor* useColor = colors ? colors : temp; + + S3DVertex vtx[4]; // clock wise + vtx[0] = S3DVertex(npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, useColor[0], tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex(npos.LowerRightCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, useColor[3], tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex(npos.LowerRightCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, useColor[2], tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, useColor[1], tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); + + setTexture(0, const_cast(texture)); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + +} + + + +//! draws a 2d image, using a color and the alpha channel of the texture if +//! desired. The image is drawn at pos and clipped against clipRect (if != 0). +void CD3D9Driver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + if (!setTexture(0, const_cast(texture))) + return; + + core::position2d targetPos = pos; + core::position2d sourcePos = sourceRect.UpperLeftCorner; + core::dimension2d sourceSize(sourceRect.getSize()); + + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (targetPos.X + sourceSize.Width > renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + s32 xPlus = -renderTargetSize.Width / 2; + f32 xFact = 2.0f / renderTargetSize.Width; + + s32 yPlus = renderTargetSize.Height / 2; + f32 yFact = 2.0f / renderTargetSize.Height; + + core::rect tcoords; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)+0.5f) / texture->getOriginalSize().Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)+0.5f) / texture->getOriginalSize().Height; + tcoords.LowerRightCorner.X = (((f32)sourcePos.X +0.5f + (f32)sourceSize.Width)) / texture->getOriginalSize().Width; + tcoords.LowerRightCorner.Y = (((f32)sourcePos.Y +0.5f + (f32)sourceSize.Height)) / texture->getOriginalSize().Height; + + core::rect poss(targetPos, sourceSize); + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.UpperLeftCorner.Y ) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- poss.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); +} + + + +//!Draws a 2d rectangle with a gradient. +void CD3D9Driver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + core::rect pos(position); + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + s32 xPlus = -renderTargetSize.Width / 2; + f32 xFact = 2.0f / renderTargetSize.Width; + + s32 yPlus = renderTargetSize.Height / 2; + f32 yFact = 2.0f / renderTargetSize.Height; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); + vtx[1] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); + vtx[2] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); + vtx[3] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode( + colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + +} + + + +//! Draws a 2d line. +void CD3D9Driver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + // thanks to Vash TheStampede who sent in his implementation + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + const s32 xPlus = -renderTargetSize.Width / 2; + const f32 xFact = 2.0f / renderTargetSize.Width; + + const s32 yPlus = renderTargetSize.Height / 2; + const f32 yFact = 2.0f / renderTargetSize.Height; + + S3DVertex vtx[2]; + vtx[0] = S3DVertex((f32)(start.X + xPlus) * xFact, + (f32)(yPlus - start.Y) * yFact, + 0.0f, // z + 0.0f, 0.0f, 0.0f, // normal + color, + 0.0f, 0.0f); // texture + + vtx[1] = S3DVertex((f32)(end.X+xPlus) * xFact, + (f32)(yPlus- end.Y) * yFact, + 0.0f, + 0.0f, 0.0f, 0.0f, + color, + 0.0f, 0.0f); + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, + &vtx[0], sizeof(S3DVertex) ); +} + + + +//! sets right vertex shader +void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType) +{ + if (newType != LastVertexType) + { + LastVertexType = newType; + HRESULT hr = 0; + + switch(newType) + { + case EVT_STANDARD: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); + break; + case EVT_2TCOORDS: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); + break; + case EVT_TANGENTS: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | + D3DFVF_TEXCOORDSIZE2(0) | // real texture coord + D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent + D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal + ); + break; + } + + if (FAILED(hr)) + { + os::Printer::log("Could not set vertex Shader.", ELL_ERROR); + return; + } + } +} + + + +//! sets the needed renderstates +bool CD3D9Driver::setRenderStates3DMode() +{ + if (!pID3DDevice) + return false; + + if (CurrentRenderMode != ERM_3D) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + + ResetRenderStates = true; + } + + if (ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (CurrentRenderMode == ERM_3D && + LastMaterial.MaterialType != Material.MaterialType && + LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + } + + bool shaderOK = true; + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); + + LastMaterial = Material; + + ResetRenderStates = false; + + CurrentRenderMode = ERM_3D; + + return shaderOK; +} + + + +//! Can be called by an IMaterialRenderer to make its work easier. +void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates) +{ + if (resetAllRenderstates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.Shininess != material.Shininess) + { + D3DMATERIAL9 mat; + mat.Diffuse = colorToD3D(material.DiffuseColor); + mat.Ambient = colorToD3D(material.AmbientColor); + mat.Specular = colorToD3D(material.SpecularColor); + mat.Emissive = colorToD3D(material.EmissiveColor); + mat.Power = material.Shininess; + pID3DDevice->SetMaterial(&mat); + } + + // fillmode + if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) + { + if (material.Wireframe) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + else + if (material.PointCloud) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); + else + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } + + // shademode + + if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) + { + if (material.GouraudShading) + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + else + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + + // lighting + + if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) + { + if (material.Lighting) + pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); + else + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + } + + // zbuffer + + if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case 0: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + break; + case 1: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + break; + case 2: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + break; + } + } + + // zwrite + if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) + { + if ( material.ZWriteEnable ) + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); + else + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); + } + + // back face culling + + if (resetAllRenderstates || lastmaterial.BackfaceCulling != material.BackfaceCulling) + { + if (material.BackfaceCulling) + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + else + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE); + } + + // fog + if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) + { + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); + } + + // specular highlights + if (resetAllRenderstates || !core::equals(lastmaterial.Shininess,material.Shininess)) + { + bool enable = (material.Shininess!=0.0f); + pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); + } + + // normalization + if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); + } + + // thickness + if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) + { + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); + } + + // texture address mode + for (u32 st=0; stSetSamplerState(st, D3DSAMP_ADDRESSU, mode ); + pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, mode ); + } + + // Bilinear, trilinear, and anisotropic filter + if (resetAllRenderstates || + lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || + lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || + lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter) + { + if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter) + { + D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMip = material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT; + + pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, tftMag); + pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, tftMin); + pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, tftMip); + } + else + { + pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } + } + } +} + + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail) +{ + if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && + CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || + Transformation3DChanged) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + Transformation3DChanged = false; + + setTexture(0,0); + setTexture(1,0); + setTexture(2,0); + setTexture(3,0); + + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetFVF(D3DFVF_XYZ); + LastVertexType = (video::E_VERTEX_TYPE)(-1); + + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); + pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE ); + pID3DDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT); + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + + //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) + { + // USE THE ZPASS METHOD + + pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); + + pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x1 ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); + pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); + } + else + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) + { + // USE THE ZFAIL METHOD + + pID3DDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); + + pID3DDevice->SetRenderState( D3DRS_STENCILREF, 0x0 ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); + pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); + } + + CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; +} + + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) +{ + if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1); + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); + //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + + Transformation3DChanged = false; + + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_STENCIL_FILL; +} + + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (!pID3DDevice) + return; + + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); + + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); + + pID3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); + pID3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); + + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D9 ); + + Transformation3DChanged = false; + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + } + + if (texture) + { + pID3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + + if (alphaChannel) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + + if (alpha) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + } + else + { + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + } + else + { + if (alpha) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_2D; +} + + + +//! deletes all dynamic lights there are +void CD3D9Driver::deleteAllDynamicLights() +{ + for (s32 i=0; iLightEnable(i, false); + + LastSetLight = -1; + + CNullDriver::deleteAllDynamicLights(); +} + + + +//! adds a dynamic light +void CD3D9Driver::addDynamicLight(const SLight& dl) +{ + if ((u32)LastSetLight == Caps.MaxActiveLights-1) + return; + + CNullDriver::addDynamicLight(dl); + + D3DLIGHT9 light; + + switch (dl.Type) + { + case ELT_POINT: + light.Type = D3DLIGHT_POINT; + break; + case ELT_SPOT: + light.Type = D3DLIGHT_SPOT; + break; + case ELT_DIRECTIONAL: + light.Type = D3DLIGHT_DIRECTIONAL; + break; + } + + light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); + light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); + + light.Range = core::min_(dl.Radius, MaxLightDistance); + light.Falloff = dl.Falloff; + + light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); + light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); + light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); + + light.Attenuation0 = dl.Attenuation.X; + light.Attenuation1 = dl.Attenuation.Y; + light.Attenuation2 = dl.Attenuation.Z; + + light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; + light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; + + ++LastSetLight; + pID3DDevice->SetLight(LastSetLight, &light); + pID3DDevice->LightEnable(LastSetLight, true); +} + + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CD3D9Driver::getMaximalDynamicLightAmount() const +{ + return Caps.MaxActiveLights; +} + + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CD3D9Driver::setAmbientLight(const SColorf& color) +{ + if (!pID3DDevice) + return; + + AmbientLight = color; + D3DCOLOR col = color.toSColor().color; + pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); +} + + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D9 +//! driver, it would return "Direct3D9.0". +const wchar_t* CD3D9Driver::getName() const +{ + return L"Direct3D 9.0"; +} + + + +//! 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 +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail) +{ + if (!StencilBuffer || !count) + return; + + setRenderStatesStencilShadowMode(zfail); + + if (!zfail) + { + // ZPASS Method + + // Draw front-side of shadow volume in stencil/z only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + } + else + { + // ZFAIL Method + + // Draw front-side of shadow volume in stencil/z only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df)); + } +} + + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!StencilBuffer) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); + vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); + vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); + vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,1,3,2}; + + setRenderStatesStencilFillMode( + leftUpEdge.getAlpha() < 255 || + rightUpEdge.getAlpha() < 255 || + leftDownEdge.getAlpha() < 255 || + rightDownEdge.getAlpha() < 255); + + setTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + + if (clearStencilBuffer) + pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); +} + + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CD3D9Driver::getMaximalPrimitiveCount() const +{ + return Caps.MaxPrimitiveCount; +} + + + +//! Sets the fog mode. +void CD3D9Driver::setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, linearFog, start, end, density, pixelFog, rangeFog); + + if (!pID3DDevice) + return; + + pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); + + pID3DDevice->SetRenderState( + pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, + linearFog ? D3DFOG_LINEAR : D3DFOG_EXP); + + if(linearFog) + { + pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); + pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); + } + else + pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); + + if(!pixelFog) + pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); +} + + + +//! Draws a 3d line. +void CD3D9Driver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setVertexShader(EVT_STANDARD); + setRenderStates3DMode(); + video::S3DVertex v[2]; + v[0].Color = color; + v[1].Color = color; + v[0].Pos = start; + v[1].Pos = end; + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); +} + + + +//! resets the device +bool CD3D9Driver::reset() +{ + // reset + HRESULT hr; + os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION); + if (FAILED(hr = pID3DDevice->Reset(&present))) + { + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); + } + else + os::Printer::log("Resetting failed.", ELL_WARNING); + return false; + } + + DeviceLost = false; + ResetRenderStates = true; + LastVertexType = (E_VERTEX_TYPE)-1; + + for (u32 i=0; i& size) +{ + if (!pID3DDevice) + return; + + CNullDriver::OnResize(size); + present.BackBufferWidth = size.Width; + present.BackBufferHeight = size.Height; + + reset(); +} + + + +//! Returns type of video driver +E_DRIVER_TYPE CD3D9Driver::getDriverType() const +{ + return EDT_DIRECT3D9; +} + + + +//! Returns the transformation set by setTransform +const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + + + +//! Sets a vertex shader constant. +void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetVertexShaderConstantF(startRegister, data, constantAmount); +} + +//! Sets a pixel shader constant. +void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetPixelShaderConstantF(startRegister, data, constantAmount); +} + +//! Sets a constant for the vertex shader based on a name. +bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(true, name, floats, count); + } + + return false; +} + +//! Sets a constant for the pixel shader based on a name. +bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(false, name, floats, count); + } + + return false; +} + +//! Returns pointer to the IGPUProgrammingServices interface. +IGPUProgrammingServices* CD3D9Driver::getGPUProgrammingServices() +{ + return this; +} + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + CD3D9ShaderMaterialRenderer* r = new CD3D9ShaderMaterialRenderer( + pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + + +//! Adds a new material renderer to the VideoDriver, based on a high level shading +//! language. +s32 CD3D9Driver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + s32 nr = -1; + + CD3D9HLSLMaterialRenderer* hlsl = new CD3D9HLSLMaterialRenderer( + pID3DDevice, this, nr, + vertexShaderProgram, + vertexShaderEntryPointName, + vsCompileTarget, + pixelShaderProgram, + pixelShaderEntryPointName, + psCompileTarget, + callback, + getMaterialRenderer(baseMaterial), + userData); + + hlsl->drop(); + return nr; +} + + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* CD3D9Driver::getVideoDriver() +{ + return this; +} + + +//! Creates a render target texture. +ITexture* CD3D9Driver::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + return new CD3D9Texture(this, size, name); +} + + +//! Clears the ZBuffer. +void CD3D9Driver::clearZBuffer() +{ + HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); + + if (FAILED(hr)) + os::Printer::log("CD3D9Driver clearZBuffer() failed.", ELL_WARNING); +} + + +//! Returns an image created from the last rendered frame. +IImage* CD3D9Driver::createScreenShot() +{ + HRESULT hr; + + // query the screen dimensions of the current adapter + D3DDISPLAYMODE displayMode; + pID3DDevice->GetDisplayMode(0, &displayMode); + + // create the image surface to store the front buffer image [always A8R8G8B8] + LPDIRECT3DSURFACE9 lpSurface; + if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0))) + return 0; + + // read the front buffer into the image surface + if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface))) + { + lpSurface->Release(); + return 0; + } + + RECT clientRect; + { + POINT clientPoint; + clientPoint.x = 0; + clientPoint.y = 0; + + ClientToScreen((HWND)getExposedVideoData().D3D9.HWnd, &clientPoint); + + clientRect.left = clientPoint.x; + clientRect.top = clientPoint.y; + clientRect.right = clientRect.left + ScreenSize.Width; + clientRect.bottom = clientRect.top + ScreenSize.Height; + } + + // lock our area of the surface + D3DLOCKED_RECT lockedRect; + if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) + { + lpSurface->Release(); + return 0; + } + + // this could throw, but we aren't going to worry about that case very much + IImage* newImage = new CImage(ECF_A8R8G8B8, ScreenSize); + + // d3d pads the image, so we need to copy the correct number of bytes + u32* dP = (u32*)newImage->lock(); + u8 * sP = (u8 *)lockedRect.pBits; + + for (s32 y = 0; y < ScreenSize.Height; ++y) + { + memcpy(dP, sP, ScreenSize.Width * 4); + + sP += lockedRect.Pitch; + dP += ScreenSize.Width; + } + + newImage->unlock(); + + // we can unlock and release the surface + lpSurface->UnlockRect(); + + // release the image surface + lpSurface->Release(); + + // return status of save operation to caller + return newImage; +} + + +// returns the current size of the screen or rendertarget +core::dimension2d CD3D9Driver::getCurrentRenderTargetSize() +{ + if ( CurrentRendertargetSize.Width == 0 ) + return ScreenSize; + else + return CurrentRendertargetSize; +} + + + +// Set/unset a clipping plane. +bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + if (index >= MaxUserClipPlanes) + return false; + + pID3DDevice->SetClipPlane(index, (const float*)&plane); + enableClipPlane(index, enable); + return true; +} + + +// Enable/disable a clipping plane. +void CD3D9Driver::enableClipPlane(u32 index, bool enable) +{ + if (index >= MaxUserClipPlanes) + return; + DWORD renderstate; + pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); + if (enable) + renderstate |= (1 << index); + else + renderstate &= ~(1 << index); + pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + + + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +//! creates a video driver +IVideoDriver* createDirectX9Driver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool stencilbuffer, + io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU, + bool vsync, bool antiAlias) +{ + CD3D9Driver* dx9 = new CD3D9Driver(screenSize, window, fullscreen, stencilbuffer, io, pureSoftware); + if (!dx9->initDriver(screenSize, window, bits, fullscreen, pureSoftware, highPrecisionFPU, vsync, antiAlias)) + { + dx9->drop(); + dx9 = 0; + } + + return dx9; +} +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +} // end namespace video +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CD3D9Driver.h b/src/dep/src/irrlicht/CD3D9Driver.h new file mode 100644 index 0000000..c736376 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9Driver.h @@ -0,0 +1,305 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_DIRECTX_9_H_INCLUDED__ +#define __C_VIDEO_DIRECTX_9_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#ifdef _IRR_WINDOWS_ +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include "CNullDriver.h" +#include "IMaterialRendererServices.h" +#include "d3d9.h" + +namespace irr +{ +namespace video +{ + class CD3D9Driver : public CNullDriver, IMaterialRendererServices + { + public: + + //! constructor + CD3D9Driver(const core::dimension2d& screenSize, HWND window, bool fullscreen, + bool stencibuffer, io::IFileSystem* io, bool pureSoftware=false); + + //! destructor + virtual ~CD3D9Driver(); + + //! applications must call this method before performing any rendering. returns false if failed. + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + //! applications must call this method after performing any rendering. returns false if failed. + virtual bool endScene( s32 windowId = 0, core::rect* sourceRect=0 ); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=false, bool clearZBuffer=false, + SColor color=video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! initialises the Direct3D API + bool initDriver(const core::dimension2d& screenSize, HWND hwnd, + u32 bits, bool fullScreen, bool pureSoftware, + bool highPrecisionFPU, bool vsync, bool antiAlias); + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light + virtual void addDynamicLight(const SLight& light); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! 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 + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Sets the fog mode. + virtual void setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! Returns pointer to the IGPUProgrammingServices interface. + virtual IGPUProgrammingServices* getGPUProgrammingServices(); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Creates a render target texture. + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + private: + + // enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D, // 3d rendering mode + ERM_STENCIL_FILL, // stencil fill mode + ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode + ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode + }; + + //! sets right vertex shader + void setVertexShader(video::E_VERTEX_TYPE newType); + + //! sets the needed renderstates + bool setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + //! sets the needed renderstates + void setRenderStatesStencilFillMode(bool alpha); + + //! sets the needed renderstates + void setRenderStatesStencilShadowMode(bool zfail); + + //! sets the current Texture + bool setTexture(s32 stage, const video::ITexture* texture); + + //! resets the device + bool reset(); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name); + + // returns the current size of the screen or rendertarget + core::dimension2d getCurrentRenderTargetSize(); + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData); + + //! Adds a new material renderer to the VideoDriver, based on a high level shading + //! language. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + void createMaterialRenderers(); + + inline D3DCOLORVALUE colorToD3D(const SColor& col) + { + const f32 f = 1.0f / 255.0f; + D3DCOLORVALUE v; + v.r = col.getRed() * f; + v.g = col.getGreen() * f; + v.b = col.getBlue() * f; + v.a = col.getAlpha() * f; + return v; + } + + E_RENDER_MODE CurrentRenderMode; + D3DPRESENT_PARAMETERS present; + + SMaterial Material, LastMaterial; + bool ResetRenderStates; // bool to make all renderstates be reseted if set. + bool Transformation3DChanged; + bool StencilBuffer; + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + bool LastTextureMipMapsAvailable[MATERIAL_MAX_TEXTURES]; + core::matrix4 Matrices[ETS_COUNT]; // matrizes of the 3d mode we need to restore when we switch back from the 2d mode. + + HINSTANCE D3DLibrary; + IDirect3D9* pID3D; + IDirect3DDevice9* pID3DDevice; + + IDirect3DSurface9* PrevRenderTarget; + core::dimension2d CurrentRendertargetSize; + + D3DCAPS9 Caps; + + E_VERTEX_TYPE LastVertexType; + + u32 MaxTextureUnits; + u32 MaxUserClipPlanes; + f32 MaxLightDistance; + s32 LastSetLight; + bool DeviceLost; + bool Fullscreen; + + SColorf AmbientLight; + }; + + +} // end namespace video +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ +#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.cpp b/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.cpp new file mode 100644 index 0000000..00df36c --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.cpp @@ -0,0 +1,291 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9HLSLMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "irrString.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + + +namespace irr +{ +namespace video +{ + + +//! Public constructor +CD3D9HLSLMaterialRenderer::CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, callback, baseMaterial, userData), + VSConstantsTable(0), PSConstantsTable(0) +{ + outMaterialTypeNr = -1; + + // now create shaders + + if (vsCompileTarget < 0 || vsCompileTarget > EVST_COUNT) + { + os::Printer::log("Invalid HLSL vertex shader compilation target"); + return; + } + + if (!createHLSLVertexShader(vertexShaderProgram, + vertexShaderEntryPointName, VERTEX_SHADER_TYPE_NAMES[vsCompileTarget])) + return; + + if (!createHLSLPixelShader(pixelShaderProgram, + pixelShaderEntryPointName, PIXEL_SHADER_TYPE_NAMES[psCompileTarget])) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + //! Destructor +CD3D9HLSLMaterialRenderer::~CD3D9HLSLMaterialRenderer() +{ + if (VSConstantsTable) + VSConstantsTable->Release(); + + if (PSConstantsTable) + PSConstantsTable->Release(); +} + + +bool CD3D9HLSLMaterialRenderer::createHLSLVertexShader(const char* vertexShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName) +{ + if (!vertexShaderProgram) + return true; + + LPD3DXBUFFER buffer = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile without debug info + + HRESULT h = stubD3DXCompileShader( + vertexShaderProgram, + strlen(vertexShaderProgram), + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + 0, // no flags + &buffer, + &errors, + &VSConstantsTable); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_hlsl_file_nr = 0; + ++irr_dbg_hlsl_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.vsh", irr_dbg_hlsl_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vertexShaderProgram, strlen(vertexShaderProgram), 1, f); + fflush(f); + fclose(f); + + HRESULT h = stubD3DXCompileShaderFromFile( + tmp, + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, + &buffer, + &errors, + &VSConstantsTable); + + #endif + + if (FAILED(h)) + { + os::Printer::log("HLSL vertex shader compilation failed:"); + if (errors) + { + os::Printer::log((c8*)errors->GetBufferPointer()); + errors->Release(); + if (buffer) + buffer->Release(); + } + return false; + } + + if (errors) + errors->Release(); + + if (buffer) + { + if (FAILED(pID3DDevice->CreateVertexShader((DWORD*)buffer->GetBufferPointer(), + &VertexShader))) + { + os::Printer::log("Could not create hlsl vertex shader."); + buffer->Release(); + return false; + } + + buffer->Release(); + return true; + } + + return false; +} + + +bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName) +{ + if (!pixelShaderProgram) + return true; + + LPD3DXBUFFER buffer = 0; + LPD3DXBUFFER errors = 0; + + HRESULT h = stubD3DXCompileShader( + pixelShaderProgram, + strlen(pixelShaderProgram), + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + 0, // no flags (D3DXSHADER_DEBUG) + &buffer, + &errors, + &PSConstantsTable); + + if (FAILED(h)) + { + os::Printer::log("HLSL pixel shader compilation failed:"); + if (errors) + { + os::Printer::log((c8*)errors->GetBufferPointer()); + errors->Release(); + if (buffer) + buffer->Release(); + } + return false; + } + + if (errors) + errors->Release(); + + if (buffer) + { + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)buffer->GetBufferPointer(), + &PixelShader))) + { + os::Printer::log("Could not create hlsl pixel shader."); + buffer->Release(); + return false; + } + + buffer->Release(); + return true; + } + + return false; +} + + +bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, + const f32* floats, int count) +{ + LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; + if (!tbl) + return false; + + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); + if (!hndl) + { + core::stringc s = "HLSL Variable to set not found: '"; + s += name; + s += "'. Available variables are:"; + os::Printer::log(s.c_str(), ELL_WARNING); + printHLSLVariables(tbl); + return false; + } + + HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count); + if (FAILED(hr)) + { + os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING); + return false; + } + + return true; +} + +bool CD3D9HLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + if (VSConstantsTable) + VSConstantsTable->SetDefaults(pID3DDevice); + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); +} + +void CD3D9HLSLMaterialRenderer::printHLSLVariables(LPD3DXCONSTANTTABLE table) +{ + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + // print out constant names + D3DXCONSTANTTABLE_DESC tblDesc; + HRESULT hr = table->GetDesc(&tblDesc); + if (!FAILED(hr)) + { + for (int i=0; i<(int)tblDesc.Constants; ++i) + { + D3DXCONSTANT_DESC d; + UINT n = 1; + D3DXHANDLE cHndl = table->GetConstant(NULL, i); + if (!FAILED(table->GetConstantDesc(cHndl, &d, &n))) + { + core::stringc s = " '"; + s += d.Name; + s += "' Registers:[begin:"; + s += (int)d.RegisterIndex; + s += ", count:"; + s += (int)d.RegisterCount; + s += "]"; + os::Printer::log(s.c_str()); + } + } + } +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.h b/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.h new file mode 100644 index 0000000..06f1227 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9HLSLMaterialRenderer.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IGPUProgrammingServices.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders via HLSL with D3D9 +class CD3D9HLSLMaterialRenderer : public CD3D9ShaderMaterialRenderer +{ +public: + + //! Public constructor + CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData); + + //! Destructor + ~CD3D9HLSLMaterialRenderer(); + + //! sets a variable in the shader. + //! \param vertexShader: True if this should be set in the vertex shader, false if + //! in the pixel shader. + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count); + + bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + +protected: + + bool createHLSLVertexShader(const char* vertexShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName); + + bool createHLSLPixelShader(const char* pixelShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName); + + void printHLSLVariables(LPD3DXCONSTANTTABLE table); + + LPD3DXCONSTANTTABLE VSConstantsTable; + LPD3DXCONSTANTTABLE PSConstantsTable; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D9MaterialRenderer.h b/src/dep/src/irrlicht/CD3D9MaterialRenderer.h new file mode 100644 index 0000000..4e8835b --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9MaterialRenderer.h @@ -0,0 +1,622 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#include "d3d9.h" + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +D3DMATRIX UnitMatrixD3D9; +D3DMATRIX SphereMapMatrixD3D9; + +//! Base class for all internal D3D9 material renderers +class CD3D9MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver) + : pID3DDevice(d3ddev), Driver(driver) + { + } + + ~CD3D9MaterialRenderer() + { + } + + //! sets a variable in the shader. + //! \param vertexShader: True if this should be set in the vertex shader, false if + //! in the pixel shader. + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count) + { + os::Printer::log("Invalid material to set variable in."); + return false; + } + +protected: + + IDirect3DDevice9* pID3DDevice; + video::IVideoDriver* Driver; +}; + + +//! Solid material renderer +class CD3D9MaterialRenderer_SOLID : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + +//! Generic Texture Blend +class CD3D9MaterialRenderer_ONETEXTURE_BLEND : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || + material.MaterialTypeParam != lastMaterial.MaterialTypeParam || + resetAllRenderstates) + { + + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + unpack_texureBlendFunc ( srcFact, dstFact, modulate, material.MaterialTypeParam ); + + if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); + } + + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, getD3DModulate ( modulate ) ); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) ) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + } + + private: + + u32 getD3DBlend ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_ZERO: r = D3DBLEND_ZERO; break; + case EBF_ONE: r = D3DBLEND_ONE; break; + case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; + case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; + case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; + case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; + } + return r; + } + + u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_SRC_ALPHA: r = 1; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; + case EBF_DST_ALPHA: r = 1; break; + case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; + case EBF_SRC_ALPHA_SATURATE: r = 1; break; + } + return r; + } + + u32 getD3DModulate ( E_MODULATE_FUNC func ) const + { + u32 r = D3DTOP_MODULATE; + switch ( func ) + { + case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; + case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; + case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; + } + return r; + } + +}; + + + +//! Solid 2 layer material renderer +class CD3D9MaterialRenderer_SOLID_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + + +//! Transparent add color material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + //! Returns if the material is transparent. The scene management needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + s32 refValue = core::floor32(material.MaterialTypeParam * 255.f); + if ( !refValue ) + refValue = 127; // default value + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, refValue); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + + +//! Transparent alpha channel material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + s32 refValue = core::floor32(material.MaterialTypeParam * 255); + if ( !refValue ) + refValue = 127; // default value + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF,refValue); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + + ((SMaterial&)material).ZWriteEnable = false; + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + +//! material renderer for all kinds of linghtmaps +class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) + { + // with lighting + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + } + + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + + if (material.MaterialType == EMT_LIGHTMAP_ADD) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); + else + if (material.MaterialType == EMT_LIGHTMAP_M4) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE4X); + else + if (material.MaterialType == EMT_LIGHTMAP_M2) + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); + else + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + + + +//! material renderer for detail maps +class CD3D9MaterialRenderer_DETAIL_MAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED); + pID3DDevice->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } +}; + + +//! sphere map material renderer +class CD3D9MaterialRenderer_SPHERE_MAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D9 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D9MaterialRenderer_REFLECTION_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D9 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + pID3DDevice->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D9 ); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D9NormalMapRenderer.cpp b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.cpp new file mode 100644 index 0000000..558a0f1 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.cpp @@ -0,0 +1,296 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9NormalMapRenderer.h" +#include "IVideoDriver.h" +#include "IMaterialRendererServices.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + + // 1.1 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D9 render path normal map vertex shader + const char D3D9_NORMAL_MAP_VSH[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "dcl_position v0 ; position \n"\ + "dcl_normal v1 ; normal \n"\ + "dcl_color v2 ; color \n"\ + "dcl_texcoord0 v3 ; texture coord \n"\ + "dcl_texcoord1 v4 ; tangent \n"\ + "dcl_texcoord2 v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ + "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D9 render path normal map pixel shader + const char D3D9_NORMAL_MAP_PSH_1_1[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + "ps.1.1 \n"\ + "tex t0 ; sample color map \n"\ + "tex t1 ; sample normal map\n"\ + "texcoord t2 ; fetch light vector 1\n"\ + "texcoord t3 ; fetch light vector 2\n"\ + "\n"\ + "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ + "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ + "\n"\ + "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ + "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ + "\n"\ + "mul r0.xyz, t0, r0 ; total luminance * base color\n"\ + "+mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ + "\n"\ + ""; + + // Higher-quality normal map pixel shader (requires PS 2.0) + // uses per-pixel normalization for improved accuracy + const char D3D9_NORMAL_MAP_PSH_2_0[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + + "ps_2_0 \n"\ + "def c0, 0, 0, 0, 0\n"\ + "def c1, 1.0, 1.0, 1.0, 1.0\n"\ + "def c2, 2.0, 2.0, 2.0, 2.0\n"\ + "def c3, -.5, -.5, -.5, -.5\n"\ + "dcl t0\n"\ + "dcl t1\n"\ + "dcl t2\n"\ + "dcl t3\n"\ + "dcl v1\n"\ + "dcl v0\n"\ + "dcl_2d s0\n"\ + "dcl_2d s1\n"\ + + "texld r0, t0, s0 ; sample color map into r0 \n"\ + "texld r4, t0, s1 ; sample normal map into r4\n"\ + "add r4, r4, c3 ; bias the normal vector\n"\ + "add r5, t2, c3 ; bias the light 1 vector into r5\n"\ + "add r6, t3, c3 ; bias the light 2 vector into r6\n"\ + + "nrm r1, r4 ; normalize the normal vector into r1\n"\ + "nrm r2, r5 ; normalize the light1 vector into r2\n"\ + "nrm r3, r6 ; normalize the light2 vector into r3\n"\ + + "dp3 r2, r2, r1 ; let r2 = normal DOT light 1 vector\n"\ + "max r2, r2, c0 ; clamp result to positive numbers\n"\ + "mul r2, r2, v0 ; let r2 = luminance1 * light color 1 \n"\ + + "dp3 r3, r3, r1 ; let r3 = normal DOT light 2 vector\n"\ + "max r3, r3, c0 ; clamp result to positive numbers\n"\ + + "mad r2, r3, v1, r2 ; let r2 = (luminance2 * light color 2) + (luminance2 * light color 1) \n"\ + + "mul r2, r2, r0 ; let r2 = total luminance * base color\n"\ + "mov r2.w, v0.w ; write interpolated vertex alpha value \n"\ + + "mov oC0, r2 ; copy r2 to the output register \n"\ + + "\n"\ + ""; + + CD3D9NormalMapRenderer::CD3D9NormalMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial) + { + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D9NormalMapRenderer* nmr = (video::CD3D9NormalMapRenderer*)renderer; + VertexShader = nmr->VertexShader; + if (VertexShader) + VertexShader->AddRef(); + + PixelShader = nmr->PixelShader; + if (PixelShader) + PixelShader->AddRef(); + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + if (driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0)) + { + init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_2_0); + } + else + { + init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_1_1); + } + } + } + + CD3D9NormalMapRenderer::~CD3D9NormalMapRenderer() + { + if (CallBack == this) + CallBack = 0; + } + + bool CD3D9NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + + //! Returns the render capability of the material. + s32 CD3D9NormalMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + void CD3D9NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h new file mode 100644 index 0000000..0f84ea2 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9NormalMapRenderer.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#include "d3d9.h" + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps +class CD3D9NormalMapRenderer : + public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D9NormalMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + ~CD3D9NormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.cpp b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.cpp new file mode 100644 index 0000000..5a0423d --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.cpp @@ -0,0 +1,399 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ParallaxMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +//#define SHADER_EXTERNAL_DEBUG + +#ifdef SHADER_EXTERNAL_DEBUG +#include "CReadFile.h" +#endif + +namespace irr +{ +namespace video +{ + // 1.1/1.4 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D9 render path normal map vertex shader + const char D3D9_PARALLAX_MAP_VSH[] = + ";Irrlicht Engine 0.10 D3D9 render path parallax mapping vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c4: Eye position \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "dcl_position v0 ; position \n"\ + "dcl_normal v1 ; normal \n"\ + "dcl_color v2 ; color \n"\ + "dcl_texcoord0 v3 ; texture coord \n"\ + "dcl_texcoord1 v4 ; tangent \n"\ + "dcl_texcoord2 v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ + "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ + "add r1, -c4, r4 ; eye - vtxpos \n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ + "dp3 r10.y, r6, r1 \n"\ + "dp3 r10.z, r7, r1 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + ";mul r8, r8, c96 \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + ";mul r9, r9, c96 \n"\ + "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ + "rsq r10.w, r10.w \n"\ + "mul r10, r10, r10.w \n"\ + "mul r10, r10, c96 \n"\ + "\n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + + // Irrlicht Engine D3D9 render path normal map pixel shader version 1.4 + const char D3D9_PARALLAX_MAP_PSH[] = + ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.1.4 \n"\ + " \n"\ + ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ + "def c5, 0.5f, 0.5f, 0.5f, 0.0f ; for specular division \n"\ + " \n"\ + "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "texcrd r4.xyz, t4 ; fetch eye vector \n"\ + "texcrd r0.xyz, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to reduce swimming effect: \n"\ + "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ + "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "phase \n"\ + " \n"\ + "texld r0, r2 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2 ; sample normal map \n"\ + "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ + "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "dp3_sat r5, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r5, r5, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r5 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "+mov r0.a, v0.a ; write original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D9 render path normal map pixel shader version 2.0 + const char D3D9_PARALLAX_MAP_PSH_20[] = + ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + " \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.2.0 \n"\ + " \n"\ + "dcl_2d s0 ; Declare the s0 register to be the sampler for stage 0 \n"\ + "dcl t0.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ + "dcl t1.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ + "dcl_2d s1 ; Declare the s1 register to be the sampler for stage 1 \n"\ + " \n"\ + "dcl t2.xyz ; \n"\ + "dcl t3.xyz ; \n"\ + "dcl t4.xyz ; \n"\ + "dcl v0.xyzw; \n"\ + "dcl v1.xyzw; \n"\ + " \n"\ + "def c0, -1.0f, -1.0f, -1.0f, -1.0f ; for _bx2 emulation \n"\ + "def c1, 2.0f, 2.0f, 2.0f, 2.0f ; for _bx2 emulation \n"\ + "mov r11, c1; \n"\ + " \n"\ + "texld r1, t1, s1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "mov r4.xyz, t4 ; fetch eye vector \n"\ + "mov r0.xy, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r1.xyz, r1, r11, c0; \n"\ + " \n"\ + "mul r3, r1.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + " \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r4.xyz, r4, r11, c0; \n"\ + " \n"\ + "mad r2.xy, r3, r4, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to avoid swimming: \n"\ + ";mul r3, r1_bx2.wwww, r1_bx2.zzzz ; r3 = (h,h,h,h) * (n.z, n.z, n.z, n.z,) \n"\ + ";mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "texld r0, r2, s0 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2, s1 ; sample normal map \n"\ + "mov r2.xyz, t2 ; fetch light vector 1 \n"\ + "mov r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r1.xyz, r1, r11, c0; \n"\ + "mad r2.xyz, r2, r11, c0; \n"\ + "mad r3.xyz, r3, r11, c0; \n"\ + " \n"\ + "dp3_sat r2, r1, r2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1, r3 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "mov r0.a, v0.a ; write original alpha value \n"\ + "mov oC0, r0; \n"\ + "\n"; + + CD3D9ParallaxMapRenderer::CD3D9ParallaxMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CurrentScale(0.0f) + { + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled parallax map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D9ParallaxMapRenderer* nmr = (video::CD3D9ParallaxMapRenderer*)renderer; + VertexShader = nmr->VertexShader; + if (VertexShader) + VertexShader->AddRef(); + + PixelShader = nmr->PixelShader; + if (PixelShader) + PixelShader->AddRef(); + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + #ifdef SHADER_EXTERNAL_DEBUG + + // quickly load shader from external file + io::CReadFile* file = new io::CReadFile("parallax.psh"); + s32 sz = file->getSize(); + char* s = new char[sz+1]; + file->read(s, sz); + s[sz] = 0; + + init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, s); + + delete [] s; + file->drop(); + + #else + + // compile shaders on our own + init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, D3D9_PARALLAX_MAP_PSH); + + #endif // SHADER_EXTERNAL_DEBUG + } + } + + CD3D9ParallaxMapRenderer::~CD3D9ParallaxMapRenderer() + { + if (CallBack == this) + CallBack = 0; + } + + bool CD3D9ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Parallax map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + void CD3D9ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) + { + CD3D9ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; + } + + //! Returns the render capability of the material. + s32 CD3D9ParallaxMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + void CD3D9ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set eye position + + // The viewpoint is at (0., 0., 0.) in eye space. + // Turning this into a vector [0 0 0 1] and multiply it by + // the inverse of the view matrix, the resulting vector is the + // object space location of the camera. + + f32 floats[4] = {0,0,0,1}; + core::matrix4 minv = driver->getTransform(video::ETS_VIEW); + minv.makeInverse(); + minv.multiplyWith1x4Matrix(floats); + services->setVertexShaderConstant(floats, 4, 1); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj; + worldViewProj = driver->getTransform(video::ETS_PROJECTION); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the driver + // and set them as constants + + int cnt = driver->getDynamicLightCount(); + + for (int i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + f32 c96[] = {-1, 1, 1, 1}; + services->setVertexShaderConstant(c96, 96, 1); + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, 0}; + services->setPixelShaderConstant(c6, 6, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h new file mode 100644 index 0000000..28a2891 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9ParallaxMapRenderer.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#include "d3d9.h" + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps using parallax mapping +class CD3D9ParallaxMapRenderer : + public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D9ParallaxMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + ~CD3D9ParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + + virtual void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + +private: + + f32 CurrentScale; + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.cpp b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.cpp new file mode 100644 index 0000000..45bb3bb --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.cpp @@ -0,0 +1,528 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "irrString.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + + +namespace irr +{ +namespace video +{ + +//! Public constructor +CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram); +} + + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +void CD3D9ShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram) +{ + outMaterialTypeNr = -1; + + // create vertex shader + if (!createVertexShader(vertexShaderProgram)) + return; + + // create pixel shader + if (!createPixelShader(pixelShaderProgram)) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + + +//! Destructor +CD3D9ShaderMaterialRenderer::~CD3D9ShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + VertexShader->Release(); + + if (PixelShader) + PixelShader->Release(); + + if (BaseMaterial) + BaseMaterial->drop (); +} + +bool CD3D9ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader)) + CallBack->OnSetConstants(service, UserData); + + return true; +} + +void CD3D9ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexShader) + { + // save old vertex shader + pID3DDevice->GetVertexShader(&OldVertexShader); + + // set new vertex shader + if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) + os::Printer::log("Could not set vertex shader."); + } + + // set new pixel shader + if (PixelShader) + { + if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) + os::Printer::log("Could not set pixel shader."); + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +void CD3D9ShaderMaterialRenderer::OnUnsetMaterial() +{ + if (VertexShader) + pID3DDevice->SetVertexShader(OldVertexShader); + + if (PixelShader) + pID3DDevice->SetPixelShader(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. The scene managment needs to know this +//! for being able to sort the materials by opaque and transparent. +bool CD3D9ShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +bool CD3D9ShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + stubD3DXAssembleShader(pxsh, strlen(pxsh), 0, 0, 0, &code, &errors); + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_shader_%d.psh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(pxsh, strlen(pxsh), 1, f); + fflush(f); + fclose(f); + + stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); + + #endif + + + if (errors) + { + // print out compilation errors. + os::Printer::log("Pixel shader compilation failed:"); + os::Printer::log((c8*)errors->GetBufferPointer()); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) + { + os::Printer::log("Could not create pixel shader."); + code->Release(); + return false; + } + + code->Release(); + return true; +} + + + +bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh) +{ + if (!vtxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + stubD3DXAssembleShader(vtxsh, strlen(vtxsh), 0, 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_shader_%d.vsh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vtxsh, strlen(vtxsh), 1, f); + fflush(f); + fclose(f); + + stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); + + #endif + + + if (errors) + { + // print out compilation errors. + os::Printer::log("Vertex shader compilation failed:"); + os::Printer::log((c8*)errors->GetBufferPointer()); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (!code || FAILED(pID3DDevice->CreateVertexShader((DWORD*)code->GetBufferPointer(), &VertexShader))) + { + os::Printer::log("Could not create vertex shader."); + if (code) + code->Release(); + return false; + } + + code->Release(); + return true; +} + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, + DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs) +{ + // Because Irrlicht needs to be able to start up even without installed d3d dlls, it + // needs to load external d3d dlls manually. examples for the dlls are: + // SDK dll name D3DX_SDK_VERSION + // Summer 2004: no dll 22 + // February 2005: d3dx9_24.dll 24 + // April 2005: d3dx9_25.dll 25 + // June 2005: d3dx9_26.dll 26 + // August 2005: d3dx9_27.dll 27 + // October 2005, + // December 2005: d3dx9_28.dll 28 + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, pInclude, + Flags, ppShader, ppErrorMsgs); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXAssembleShader signature + typedef HRESULT (WINAPI *AssembleShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, + DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + static bool LoadFailed = false; + static AssembleShaderFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + core::stringc strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (AssembleShaderFunction)GetProcAddress(hMod, "D3DXAssembleShader"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXAssembleShader from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXAssembleShaderFromFile(pSrcFile, pDefines, pInclude, Flags, + ppShader, ppErrorMsgs); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXAssembleShaderFromFileA signature + typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); + + static bool LoadFailed = false; + static AssembleShaderFromFileFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + core::stringc strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (AssembleShaderFromFileFunction)GetProcAddress(hMod, "D3DXAssembleShaderFromFileA"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcFile, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXCompileShader(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXCompileShader + typedef HRESULT (WINAPI *D3DXCompileShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); + + static bool LoadFailed = false; + static D3DXCompileShaderFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + core::stringc strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (D3DXCompileShaderFunction)GetProcAddress(hMod, "D3DXCompileShader"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXCompileShader from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXCompileShaderFromFile(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXCompileShaderFromFileA + typedef HRESULT (WINAPI *D3DXCompileShaderFromFileFunction)(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + static bool LoadFailed = false; + static D3DXCompileShaderFromFileFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + core::stringc strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (D3DXCompileShaderFromFileFunction)GetProcAddress(hMod, "D3DXCompileShaderFromFileA"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h new file mode 100644 index 0000000..35ca974 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9ShaderMaterialRenderer.h @@ -0,0 +1,100 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#include "d3d9.h" +#include + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with D3D9 +class CD3D9ShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Public constructor + CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + ~CD3D9ShaderMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual void OnUnsetMaterial(); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData=0); + + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram); + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const char* vtxsh); + + HRESULT stubD3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, + DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + HRESULT stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); + + HRESULT stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); + + HRESULT stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + IDirect3DDevice9* pID3DDevice; + video::IVideoDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + IDirect3DVertexShader9* VertexShader; + IDirect3DVertexShader9* OldVertexShader; + IDirect3DPixelShader9* PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/dep/src/irrlicht/CD3D9Texture.cpp b/src/dep/src/irrlicht/CD3D9Texture.cpp new file mode 100644 index 0000000..56abaf4 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9Texture.cpp @@ -0,0 +1,689 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D9Texture.h" +#include "CD3D9Driver.h" +#include "os.h" + +#include + +#ifndef _IRR_COMPILE_WITH_DIRECT3D_8_ +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +// #define _IRR_USE_D3DXFilterTexture_ +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#ifdef _IRR_USE_D3DXFilterTexture_ +#pragma comment(lib, "d3dx9.lib") +#endif + +namespace irr +{ +namespace video +{ + +//! rendertarget constructor +CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, core::dimension2d size, const char* name) +: ITexture(name), Image(0), Texture(0), RTTSurface(0), Driver(driver), + TextureSize(size), ImageSize(size), Pitch(0), + HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true) +{ + #ifdef _DEBUG + setDebugName("CD3D9Texture"); + #endif + + Device=driver->getExposedVideoData().D3D9.D3DDev9; + if (Device) + Device->AddRef(); + + createRenderTarget(); +} + + +//! constructor +CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, + u32 flags, const char* name) +: ITexture(name), Image(image), Texture(0), RTTSurface(0), Driver(driver), +TextureSize(0,0), ImageSize(0,0), Pitch(0), +HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) +{ + #ifdef _DEBUG + setDebugName("CD3D9Texture"); + #endif + + const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + Device=driver->getExposedVideoData().D3D9.D3DDev9; + if (Device) + Device->AddRef(); + + if (Image) + { + Image->grab(); + + if (createTexture(flags)) + { + if (copyTexture() && generateMipLevels) + { + // create mip maps. + #ifdef _IRR_USE_D3DXFilterTexture_ + // The D3DXFilterTexture function seems to get linked wrong when + // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. + // So mipmapgeneration is replaced with my own bad generation + HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT); + if (FAILED(hr)) + os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING); + else + HasMipMaps = true; + #else + createMipMaps(); + HasMipMaps = true; + #endif + } + } + else + os::Printer::log("Could not create DIRECT3D9 Texture.", ELL_WARNING); + } +} + + +//! destructor +CD3D9Texture::~CD3D9Texture() +{ + if (Device) + Device->Release(); + + if (Image) + Image->drop(); + + if (Texture) + Texture->Release(); + + if (RTTSurface) + RTTSurface->Release(); +} + + +void CD3D9Texture::createRenderTarget() +{ + TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width); + TextureSize.Height = getTextureSizeFromImageSize(TextureSize.Height); + + // get backbuffer format to create the render target in the + // same format + + IDirect3DSurface9* bb; + D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; + + if (!FAILED(Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb))) + { + D3DSURFACE_DESC desc; + bb->GetDesc(&desc); + d3DFormat = desc.Format; + + if (d3DFormat == D3DFMT_X8R8G8B8) + d3DFormat = D3DFMT_A8R8G8B8; + + bb->Release(); + } + else + { + os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", + ELL_WARNING); + return; + } + + // create texture + HRESULT hr; + + hr = Device->CreateTexture( + TextureSize.Width, + TextureSize.Height, + 1, // mip map level count, we don't want mipmaps here + D3DUSAGE_RENDERTARGET, + d3DFormat, + D3DPOOL_DEFAULT, + &Texture, + NULL); + + // get irrlicht format from D3D format + ColorFormat = getColorFormatFromD3DFormat(d3DFormat); + + if (FAILED(hr)) + os::Printer::log("Could not create render target texture"); +} + + +bool CD3D9Texture::createMipMaps(u32 level) +{ + if (level==0) + return true; + + if (HardwareMipMaps && Texture) + { + // generate mipmaps in hardware + Texture->GenerateMipSubLevels(); + return true; + } + // os::Printer::log("manual mipmap"); + + IDirect3DSurface9* upperSurface = 0; + IDirect3DSurface9* lowerSurface = 0; + + // get upper level + HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); + if (FAILED(hr) || !upperSurface) + { + os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); + return false; + } + + // get lower level + hr = Texture->GetSurfaceLevel(level, &lowerSurface); + if (FAILED(hr) || !lowerSurface) + { + os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); + upperSurface->Release(); + return false; + } + + D3DSURFACE_DESC upperDesc, lowerDesc; + upperSurface->GetDesc(&upperDesc); + lowerSurface->GetDesc(&lowerDesc); + + D3DLOCKED_RECT upperlr; + D3DLOCKED_RECT lowerlr; + + // lock upper surface + if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) + { + upperSurface->Release(); + lowerSurface->Release(); + os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); + return false; + } + + // lock lower surface + if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) + { + upperSurface->UnlockRect(); + upperSurface->Release(); + lowerSurface->Release(); + os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); + return false; + } + + if (upperDesc.Format != lowerDesc.Format) + { + os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); + } + else + { + if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5)) + copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + if (upperDesc.Format == D3DFMT_A8R8G8B8) + copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); + } + + bool result=true; + // unlock + if (FAILED(upperSurface->UnlockRect())) + result=false; + if (FAILED(lowerSurface->UnlockRect())) + result=false; + + // release + upperSurface->Release(); + lowerSurface->Release(); + + if (!result || (upperDesc.Width < 3 && upperDesc.Height < 3)) + return result; // stop generating levels + + // generate next level + return createMipMaps(level+1); +} + + +//! creates the hardware texture +bool CD3D9Texture::createTexture(u32 flags) +{ + core::dimension2d optSize; + ImageSize = Image->getDimension(); + + if (Driver->queryFeature(EVDF_TEXTURE_NPOT)) + optSize=ImageSize; + else + { + optSize.Width = getTextureSizeFromImageSize(ImageSize.Width); + optSize.Height = getTextureSizeFromImageSize(ImageSize.Height); + } + + HRESULT hr; + D3DFORMAT format = D3DFMT_A1R5G5B5; + + switch(getTextureFormatFromFlags(flags)) + { + case ETCF_ALWAYS_16_BIT: + format = D3DFMT_A1R5G5B5; break; + case ETCF_ALWAYS_32_BIT: + format = D3DFMT_A8R8G8B8; break; + case ETCF_OPTIMIZED_FOR_QUALITY: + { + switch(Image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_A8R8G8B8: + format = D3DFMT_A8R8G8B8; break; + case ECF_A1R5G5B5: + case ECF_R5G6B5: + format = D3DFMT_A1R5G5B5; break; + } + } + break; + case ETCF_OPTIMIZED_FOR_SPEED: + format = D3DFMT_A1R5G5B5; + break; + default: + break; + } + if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) + { + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_R8G8B8; + else if (format == D3DFMT_A1R5G5B5) + format = D3DFMT_R5G6B5; + } + + const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + DWORD usage = 0; + + // This enables hardware mip map generation. + if (mipmaps && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9; + D3DDISPLAYMODE d3ddm; + intf->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); + + if (D3D_OK==intf->CheckDeviceFormat(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format)) + { + usage = D3DUSAGE_AUTOGENMIPMAP; + HardwareMipMaps = true; + } + } + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + usage, // usage + format, D3DPOOL_MANAGED , &Texture, NULL); + + if (FAILED(hr)) + { + // try brute force 16 bit + HardwareMipMaps = false; + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_A1R5G5B5; + else if (format == D3DFMT_R8G8B8) + format = D3DFMT_R5G6B5; + else + return false; + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture, NULL); + } + + ColorFormat = getColorFormatFromD3DFormat(format); + return (SUCCEEDED(hr)); +} + + +D3DFORMAT CD3D9Texture::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const +{ + switch(format) + { + case ECF_A1R5G5B5: + return D3DFMT_A1R5G5B5; + case ECF_R5G6B5: + return D3DFMT_R5G6B5; + case ECF_R8G8B8: + return D3DFMT_R8G8B8; + case ECF_A8R8G8B8: + return D3DFMT_A8R8G8B8; + } + return D3DFMT_UNKNOWN; +} + + +ECOLOR_FORMAT CD3D9Texture::getColorFormatFromD3DFormat(D3DFORMAT format) +{ + switch(format) + { + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + Pitch = TextureSize.Width * 2; + return ECF_A1R5G5B5; + case D3DFMT_A8B8G8R8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + Pitch = TextureSize.Width * 4; + return ECF_A8R8G8B8; + case D3DFMT_R5G6B5: + Pitch = TextureSize.Width * 2; + return ECF_R5G6B5; + case D3DFMT_R8G8B8: + Pitch = TextureSize.Width * 3; + return ECF_R8G8B8; + default: + return (ECOLOR_FORMAT)0; + }; +} + + +//! copies the image to the texture +bool CD3D9Texture::copyTexture() +{ + if (Texture && Image) + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + + TextureSize.Width = desc.Width; + TextureSize.Height = desc.Height; + + D3DLOCKED_RECT rect; + HRESULT hr = Texture->LockRect(0, &rect, 0, 0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock D3D9 Texture.", ELL_ERROR); + return false; + } + + Pitch = rect.Pitch; + Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); + + hr = Texture->UnlockRect(0); + if (FAILED(hr)) + { + os::Printer::log("Could not unlock D3D9 Texture.", ELL_ERROR); + return false; + } + } + + return true; +} + + +//! lock function +void* CD3D9Texture::lock() +{ + if (!Texture) + return 0; + + HRESULT hr; + D3DLOCKED_RECT rect; + if(!IsRenderTarget) + { + hr = Texture->LockRect(0, &rect, 0, 0); + } + else + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + if (!RTTSurface) + { + hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, NULL); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + } + + IDirect3DSurface9 *surface = NULL; + hr = Texture->GetSurfaceLevel(0, &surface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + hr = Device->GetRenderTargetData(surface, RTTSurface); + surface->Release(); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + hr = RTTSurface->LockRect(&rect, NULL, 0); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + return rect.pBits; + } + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + + return rect.pBits; +} + + + +//! unlock function +void CD3D9Texture::unlock() +{ + if (!Texture) + return; + + if (!IsRenderTarget) + Texture->UnlockRect(0); + else if (RTTSurface) + RTTSurface->UnlockRect(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CD3D9Texture::getOriginalSize() const +{ + return ImageSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CD3D9Texture::getSize() const +{ + return TextureSize; +} + + +//! returns the size of a texture which would be the optimize size for rendering it +inline s32 CD3D9Texture::getTextureSizeFromImageSize(s32 size) const +{ + s32 ts = 0x01; + + while(ts < size) + ts <<= 1; + + return ts; +} + + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CD3D9Texture::getDriverType() const +{ + return EDT_DIRECT3D9; +} + + + +//! returns color format of texture +ECOLOR_FORMAT CD3D9Texture::getColorFormat() const +{ + return ColorFormat; +} + + + +//! returns pitch of texture (in bytes) +u32 CD3D9Texture::getPitch() const +{ + return Pitch; +} + + + +//! returns the DIRECT3D9 Texture +IDirect3DTexture9* CD3D9Texture::getDX9Texture() const +{ + return Texture; +} + + +//! returns if texture has mipmap levels +bool CD3D9Texture::hasMipMaps() const +{ + return HasMipMaps; +} + + +void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, + s32 pitchsrc, s32 pitchtgt) const +{ + for (s32 y=0; yGetSurfaceLevel(0, &pRTTSurface); + + if (pRTTSurface) + pRTTSurface->Release(); + + return pRTTSurface; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/dep/src/irrlicht/CD3D9Texture.h b/src/dep/src/irrlicht/CD3D9Texture.h new file mode 100644 index 0000000..802b8f5 --- /dev/null +++ b/src/dep/src/irrlicht/CD3D9Texture.h @@ -0,0 +1,127 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DIRECTX9_TEXTURE_H_INCLUDED__ +#define __C_DIRECTX9_TEXTURE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "ITexture.h" +#include "IImage.h" +#include "d3d9.h" + +namespace irr +{ +namespace video +{ + +class CD3D9Driver; +/*! + interface for a Video Driver dependent Texture. +*/ +class CD3D9Texture : public ITexture +{ +public: + + //! constructor + CD3D9Texture(IImage* image, CD3D9Driver* driver, + u32 flags, const char* name); + + //! rendertarget constructor + CD3D9Texture(CD3D9Driver* driver, core::dimension2d size, const char* name); + + //! destructor + virtual ~CD3D9Texture(); + + //! lock function + virtual void* lock(); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! returns the DIRECT3D9 Texture + IDirect3DTexture9* getDX9Texture() const; + + //! returns if texture has mipmap levels + bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(); + + //! returns if it is a render target + virtual bool isRenderTarget() const; + + //! Returns pointer to the render target surface + IDirect3DSurface9* getRenderTargetSurface(); + +private: + + void createRenderTarget(); + + //! returns the size of a texture which would be the optimize size for rendering it + inline s32 getTextureSizeFromImageSize(s32 size) const; + + //! creates the hardware texture + bool createTexture(u32 flags); + + //! copies the image to the texture + bool copyTexture(); + + //! Get D3D color format from Irrlicht color format. + D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const; + + //! Get Irrlicht color format from D3D color format. + ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format); + + //! Helper function for mipmap generation. + bool createMipMaps(u32 level=1); + + //! Helper function for mipmap generation. + void copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + //! Helper function for mipmap generation. + void copy32BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + IImage* Image; + IDirect3DDevice9* Device; + IDirect3DTexture9* Texture; + IDirect3DSurface9* RTTSurface; + CD3D9Driver* Driver; + core::dimension2d TextureSize; + core::dimension2d ImageSize; + s32 Pitch; + ECOLOR_FORMAT ColorFormat; + + bool HasMipMaps; + bool HardwareMipMaps; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +#endif // __C_DIRECTX9_TEXTURE_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CDMFLoader.cpp b/src/dep/src/irrlicht/CDMFLoader.cpp new file mode 100644 index 0000000..6090d63 --- /dev/null +++ b/src/dep/src/irrlicht/CDMFLoader.cpp @@ -0,0 +1,448 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by Salvatore Russo. +// I (Nikolaus Gebhardt) did some minor modifications and changes to it and +// integrated it into Irrlicht. +// Thanks a lot to Salvatore for his work on this and that he gave me +// his permission to add it into Irrlicht using the zlib license. +/* + CDMFLoader by Salvatore Russo (September 2005) + + See the header file for additional information including use and distribution rights. +*/ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ + +#include "CDMFLoader.h" +#include "ISceneManager.h" +#include "IAttributes.h" +#include "SAnimatedMesh.h" +#include "SMeshBufferLightMap.h" +#include "irrString.h" +#include "irrMath.h" +#include "dmfsupport.h" + +namespace irr +{ +namespace scene +{ + +/** Constructor*/ +CDMFLoader::CDMFLoader(video::IVideoDriver* driver, ISceneManager* smgr) +: Driver(driver) , SceneMgr(smgr) +{ + #ifdef _DEBUG + IReferenceCounted::setDebugName("CDMFLoader"); + #endif + + if (Driver) + Driver->grab(); +} + + +/** Destructor*/ +CDMFLoader::~CDMFLoader() +{ + if (Driver) + Driver->drop(); +} + + + +/** Given first three points of a face, returns a face normal*/ +void CDMFLoader::GetFaceNormal( f32 a[3], //First point + f32 b[3], //Second point + f32 c[3], //Third point + f32 out[3]) //Normal computed +{ + f32 v1[3], v2[3]; + + v1[0] = a[0] - b[0]; + v1[1] = a[1] - b[1]; + v1[2] = a[2] - b[2]; + + v2[0] = b[0] - c[0]; + v2[1] = b[1] - c[1]; + v2[2] = b[2] - c[2]; + + out[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + out[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + out[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + + f32 dist = (f32)sqrtf((out[0] * out[0]) + (out[1] * out[1]) + (out[2] * out[2])); + + if (dist == 0.0f) + dist = 0.001f; + + out[0] /= dist; + out[1] /= dist; + out[2] /= dist; +} + + +/**Creates/loads an animated mesh from the file. + \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information.*/ +IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + //Load stringlist + StringList dmfRawFile(file); + + if (dmfRawFile.size()==0) + return 0; + + SMesh * Mesh = new SMesh(); + + u32 i; + + dmfHeader header; + + //load header + if (GetDMFHeader(dmfRawFile, header)) + { + //let's set ambient light + SceneMgr->setAmbientLight( header.dmfAmbient); + + //let's create the correct number of materials, vertices and faces + dmfMaterial *materiali=new dmfMaterial[header.numMaterials]; + dmfVert *verts=new dmfVert[header.numVertices]; + dmfFace *faces=new dmfFace[header.numFaces]; + + //let's get the materials + bool use_mat_dirs=false; + use_mat_dirs=SceneMgr->getParameters()->getAttributeAsBool(DMF_USE_MATERIALS_DIRS); + + GetDMFMaterials(dmfRawFile , materiali,header.numMaterials,use_mat_dirs); + + //let's get vertices and faces + GetDMFVerticesFaces(dmfRawFile, verts,faces); + + //create a meshbuffer for each material, then we'll remove empty ones + for (i=0; iMaterial.MaterialType = video::EMT_LIGHTMAP_LIGHTING; + buffer->Material.Wireframe = false; + buffer->Material.Lighting = true; + Mesh->addMeshBuffer(buffer); + buffer->drop(); + } + + // Build the mesh buffers + for (i = 0; i < header.numFaces; i++) + { + if (faces[i].numVerts < 3) + continue; + + f32 normal[3]; + + GetFaceNormal(verts[faces[i].firstVert].pos, + verts[faces[i].firstVert+1].pos, verts[faces[i].firstVert+2].pos, normal); + + SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer( + faces[i].materialID); + + u32 base = meshBuffer->Vertices.size(); + + // Add this face's verts + u32 v; + for (v = 0; v < faces[i].numVerts; v++) + { + dmfVert * vv = &verts[faces[i].firstVert + v]; + video::S3DVertex2TCoords vert(vv->pos[0], vv->pos[1], vv->pos[2], + normal[0], normal[1], normal[2], video::SColor(0,255,255,255), 0.0f, 0.0f); + if ( materiali[faces[i].materialID].textureBlend==4 && + SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES)) + { + vert.TCoords.set(vv->tc[0],-vv->tc[1]); + vert.TCoords2.set(vv->lc[0],vv->lc[1]); + } + else + { + vert.TCoords.set(vv->tc[0], vv->tc[1]); + vert.TCoords2.set(vv->lc[0], vv->lc[1]); + } + meshBuffer->Vertices.push_back(vert); + } + + // Now add the indices + // This weird loop turns convex polygons into triangle strips. + // I do it this way instead of a simple fan because it usually + // looks a lot better in wireframe, for example. + u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center + for (v = 0; v < faces[i].numVerts - 2; v++) + { + if (v & 1) + c = h - 1; + else + c = l + 1; + + meshBuffer->Indices.push_back(base + h); + meshBuffer->Indices.push_back(base + l); + meshBuffer->Indices.push_back(base + c); + + if (v & 1) + h--; + else + l++; + } + } + + //load textures and lightmaps in materials. + //don't worry if you receive a could not load texture, cause if you don't need + //a particular material in your scene it will be loaded and then destroyed. + for (i=0; igetParameters()->existsAttribute(DMF_TEXTURE_PATH) ) + { + //get the right path for textures + StringList filepath = SubdivideString(String(file->getFileName()),"\\"); + StringList filepath1 = SubdivideString(String(file->getFileName()),"/"); + if(filepath1.size()>filepath.size()) + { + filepath.clear(); + filepath=filepath1; + } + + for (u32 j=0; jgetParameters()->getAttributeAsString(DMF_TEXTURE_PATH)) + String("\\"); + + //texture and lightmap + ITexture *tex = 0; + ITexture *lig = 0; + + //current buffer to apply material + SMeshBufferLightMap* buffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(i); + + //Primary texture is normal + if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4)) + Driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true); + tex = Driver->getTexture((path+String(materiali[i].textureName)).c_str()); + + //Primary texture is just a colour + if(materiali[i].textureFlag==1) + { + String colour(materiali[i].textureName); + String alpha,red,green,blue; + + alpha.append((char*)&colour[0]); + alpha.append((char*)&colour[1]); + blue.append((char*)&colour[2]); + blue.append((char*)&colour[3]); + green.append((char*)&colour[4]); + green.append((char*)&colour[5]); + red.append((char*)&colour[6]); + red.append((char*)&colour[7]); + + SColor color(axtoi(alpha.c_str()), + axtoi(red.c_str()),axtoi(green.c_str()), + axtoi(blue.c_str())); + + s32 col = color.color; + s32 buf[64]; + + for (int k=0; k<64; k++) + buf[k]=col; + + //just for compatibility with older Irrlicht versions + //to support transparent materials + if (color.getAlpha()!=255 && materiali[i].textureBlend==4) + Driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true); + + IImage *immagine=Driver->createImageFromData(ECF_A8R8G8B8, + core::dimension2d(8,8),buf); + + tex = Driver->addTexture("", immagine); + + //to support transparent materials + if(color.getAlpha()!=255 && materiali[i].textureBlend==4) + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + buffer->Material.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f); + } + immagine->drop(); + } + + //Lightmap is present + if (materiali[i].lightmapFlag == 0) + lig = Driver->getTexture((path+String(materiali[i].lightmapName)).c_str()); + else //no lightmap + { + lig = 0; + buffer->Material.MaterialType = video::EMT_SOLID; + const f32 mult = 100.0f - header.dmfShadow; + buffer->Material.AmbientColor=header.dmfAmbient.getInterpolated(SColor(255,0,0,0),mult/100.f); + } + + if(materiali[i].textureBlend==4) + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + buffer->Material.MaterialTypeParam =SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF); + } + + core::dimension2d texsize; + core::dimension2d ligsize; + + if (tex && header.dmfVersion<1.1) + texsize=tex->getSize(); + + if (lig && header.dmfVersion<1.1) + ligsize=lig->getSize(); + + //if texture is present mirror vertically owing to DeleD rapresentation + if (tex && header.dmfVersion<1.1) + { + void* pp = tex->lock(); + if (pp) + { + video::ECOLOR_FORMAT format = tex->getColorFormat(); + if (format == video::ECF_A1R5G5B5) + { + s16* p = (s16*)pp; + s16 tmp=0; + for (s32 x=0; xunlock(); + tex->regenerateMipMapLevels(); + } + + //if lightmap is present mirror vertically owing to DeleD rapresentation + if (lig && header.dmfVersion<1.1) + { + void* pp = lig->lock(); + if (pp) + { + video::ECOLOR_FORMAT format = lig->getColorFormat(); + if (format == video::ECF_A1R5G5B5) + { + s16* p = (s16*)pp; + s16 tmp=0; + for (s32 x=0; xunlock(); + lig->regenerateMipMapLevels(); + } + + buffer->Material.setTexture(0, tex); + buffer->Material.setTexture(1, lig); + } + + delete verts; + delete faces; + delete materiali; + } + + // delete all buffers without geometry in it. + i = 0; + while(i < Mesh->MeshBuffers.size()) + { + if (Mesh->MeshBuffers[i]->getVertexCount() == 0 || + Mesh->MeshBuffers[i]->getIndexCount() == 0 || + Mesh->MeshBuffers[i]->getMaterial().getTexture(0) == 0) + { + // Meshbuffer is empty -- drop it + Mesh->MeshBuffers[i]->drop(); + Mesh->MeshBuffers.erase(i); + } + else + { + i++; + } + } + + // create bounding box + for (i = 0; i < Mesh->MeshBuffers.size(); i++) + { + ((SMeshBufferLightMap*)Mesh->MeshBuffers[i])->recalculateBoundingBox(); + } + Mesh->recalculateBoundingBox(); + + // Set up an animated mesh to hold the mesh + SAnimatedMesh* AMesh = new SAnimatedMesh(); + AMesh->Type = EAMT_UNKNOWN; + AMesh->addMesh(Mesh); + AMesh->recalculateBoundingBox(); + Mesh->drop(); + + return AMesh; +} + + +/** \brief Tell us if this file is able to be loaded by this class + based on the file extension (e.g. ".bsp") + \return true if file is loadable.*/ +bool CDMFLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".dmf") != 0; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DMF_LOADER_ + diff --git a/src/dep/src/irrlicht/CDMFLoader.h b/src/dep/src/irrlicht/CDMFLoader.h new file mode 100644 index 0000000..65db4e0 --- /dev/null +++ b/src/dep/src/irrlicht/CDMFLoader.h @@ -0,0 +1,97 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by Salvatore Russo. +// I (Nikolaus Gebhardt) did some minor modifications changes to it and integrated +// it into Irrlicht: +// - removed STL dependency +// - removed log file and replaced it with irrlicht logging +// - adapted code formatting a bit to Irrlicht style +// - removed memory leaks +// Thanks a lot to Salvatore for his work on this and that he gave me +// his permission to add it into Irrlicht. + +/* + CDMFLoader by Salvatore Russo + Version 1.3 + + This loader is used to load DMF files in Irrlicht. + Look at the documentation for a sample application. + + Parts of this code are from Irrlicht's CQ3LevelMesh and C3DSMeshFileLoader, + and are Copyright (C) 2002-2004 Nikolaus Gebhardt. + + Parts of this code are from Murphy McCauley COCTLoader just like GetFaceNormal() or indexes + creation routines and a routine to add faces. So please refer to COCTLoader.h to know more + about rights granted. + + You can use this software as you wish but you must not remove these notes about license nor + credits to others for parts of this code. +*/ + +#ifndef __C_DMF_LOADER_H_INCLUDED__ +#define __C_DMF_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IReadFile.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "SAnimatedMesh.h" + +namespace irr +{ +namespace scene +{ + /** A class to load DeleD mesh files.*/ + class CDMFLoader : public IMeshLoader + { + public: + + /** constructor*/ + CDMFLoader(video::IVideoDriver* driver, ISceneManager* smgr); + + /** destructor*/ + virtual ~CDMFLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + /** creates/loads an animated mesh from the file. + \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information.*/ + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + /** loads dynamic lights present in this scene. + Note that loaded lights from DeleD must have the suffix \b dynamic_ and must be \b pointlight. + Irrlicht correctly loads specular color, diffuse color , position and distance of object affected by light. + \return number of lights loaded or 0 if loading failed.*/ + int loadLights(const c8 * filename, ISceneManager* smgr, + ISceneNode* parent = 0, s32 base_id = 1000); + + /** loads water plains present in this scene. + Note that loaded water plains from DeleD must have the suffix \b water_ and must be \b rectangle (with just 1 rectangular face). + Irrlicht correctly loads position and rotation of water plain as well as texture layers. + \return number of water plains loaded or 0 if loading failed.*/ + int loadWaterPlains ( const c8 *filename, + ISceneManager* smgr, + ISceneNode * parent = 0, + s32 base_id = 2000, + bool mode = true); + + private: + + void GetFaceNormal(f32 a[3], f32 b[3], f32 c[3], f32 out[3]); + + video::IVideoDriver* Driver; + ISceneManager* SceneMgr; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CDefaultGUIElementFactory.cpp b/src/dep/src/irrlicht/CDefaultGUIElementFactory.cpp new file mode 100644 index 0000000..534c77a --- /dev/null +++ b/src/dep/src/irrlicht/CDefaultGUIElementFactory.cpp @@ -0,0 +1,154 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CDefaultGUIElementFactory.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IGUIButton.h" +#include "IGUICheckBox.h" +#include "IGUIComboBox.h" +#include "IGUIContextMenu.h" +#include "IGUIEditBox.h" +#include "IGUISpinBox.h" +#include "IGUIFileOpenDialog.h" +#include "IGUIColorSelectDialog.h" +#include "IGUIInOutFader.h" +#include "IGUIImage.h" +#include "IGUIListBox.h" +#include "IGUIMeshViewer.h" +#include "IGUIScrollBar.h" +#include "IGUIStaticText.h" +#include "IGUITabControl.h" +#include "IGUIToolbar.h" +#include "IGUIWindow.h" + +#include + +namespace irr +{ +namespace gui +{ + +CDefaultGUIElementFactory::CDefaultGUIElementFactory(IGUIEnvironment* env) +: Environment(env) +{ + // don't grab the gui environment here to prevent cyclic references +} + + +//! adds an element to the env based on its type id +IGUIElement* CDefaultGUIElementFactory::addGUIElement(EGUI_ELEMENT_TYPE type, IGUIElement* parent) +{ + switch(type) + { + case EGUIET_BUTTON: + return Environment->addButton(core::rect(0,0,100,100),parent); + case EGUIET_CHECK_BOX: + return Environment->addCheckBox(false, core::rect(0,0,100,100), parent); + case EGUIET_COLOR_SELECT_DIALOG: + return Environment->addColorSelectDialog(0,true,parent); + case EGUIET_COMBO_BOX: + return Environment->addComboBox(core::rect(0,0,100,100),parent); + case EGUIET_CONTEXT_MENU: + return Environment->addContextMenu(core::rect(0,0,100,100),parent); + case EGUIET_MENU: + return Environment->addMenu(parent); + case EGUIET_EDIT_BOX: + return Environment->addEditBox(0,core::rect(0,0,100,100),true, parent); + case EGUIET_FILE_OPEN_DIALOG: + return Environment->addFileOpenDialog(0,true,parent); + case EGUIET_IMAGE: + return Environment->addImage(0,core::position2di(0,0), true, parent); + case EGUIET_IN_OUT_FADER: + return Environment->addInOutFader(0,parent); + case EGUIET_LIST_BOX: + return Environment->addListBox(core::rect(0,0,100,100),parent); + case EGUIET_MESH_VIEWER: + return Environment->addMeshViewer(core::rect(0,0,100,100),parent); + case EGUIET_MODAL_SCREEN: + return Environment->addModalScreen(parent); + case EGUIET_MESSAGE_BOX: + return Environment->addMessageBox(0,0,false,0,parent); + case EGUIET_SCROLL_BAR: + return Environment->addScrollBar(false,core::rect(0,0,100,100),parent); + case EGUIET_STATIC_TEXT: + return Environment->addStaticText(0,core::rect(0,0,100,100),false,true,parent); + case EGUIET_TAB: + return Environment->addTab(core::rect(0,0,100,100),parent); + case EGUIET_TAB_CONTROL: + return Environment->addTabControl(core::rect(0,0,100,100),parent); + case EGUIET_TOOL_BAR: + return Environment->addToolBar(parent); + case EGUIET_WINDOW: + return Environment->addWindow(core::rect(0,0,100,100),false,0,parent); + case EGUIET_SPIN_BOX: + return Environment->addSpinBox(L"0.0", core::rect(0,0,100,100), parent); + default: + return 0; + } +} + + +//! adds an element to the environment based on its type name +IGUIElement* CDefaultGUIElementFactory::addGUIElement(const c8* typeName, IGUIElement* parent) +{ + return addGUIElement( getTypeFromName(typeName), parent ); +} + + +//! Returns the amount of element types this factory is able to create. +s32 CDefaultGUIElementFactory::getCreatableGUIElementTypeCount() const +{ + return EGUIET_COUNT; +} + + +//! Returns the type of a createable element type. +EGUI_ELEMENT_TYPE CDefaultGUIElementFactory::getCreateableGUIElementType(s32 idx) const +{ + if (idx>=0 && idx=0 && idx=0 && typecreateFlyCircleAnimator(core::vector3df(0,0,0), 10); + break; + case ESNAT_FLY_STRAIGHT: + anim = Manager->createFlyStraightAnimator(core::vector3df(0,0,0), core::vector3df(100,100,100), 10000, true ); + break; + case ESNAT_FOLLOW_SPLINE: + { + core::array points; + points.push_back(core::vector3df(0,0,0)); + points.push_back(core::vector3df(10,5,10)); + anim = Manager->createFollowSplineAnimator(0, points); + } + break; + case ESNAT_ROTATION: + anim = Manager->createRotationAnimator(core::vector3df(0.3f,0,0)); + break; + case ESNAT_TEXTURE: + { + core::array textures; + anim = Manager->createTextureAnimator(textures, 250); + } + break; + case ESNAT_DELETION: + anim = Manager->createDeleteAnimator(5000); + break; + case ESNAT_COLLISION_RESPONSE: + anim = Manager->createCollisionResponseAnimator(0, target); + break; + default: + break; + } + + if (anim && target) + target->addAnimator(anim); + + return anim; +} + + +//! creates a scene node animator based on its type name +ISceneNodeAnimator* CDefaultSceneNodeAnimatorFactory::createSceneNodeAnimator(const c8* typeName, ISceneNode* target) +{ + return createSceneNodeAnimator( getTypeFromName(typeName), target ); +} + + +//! returns amount of scene node animator types this factory is able to create +u32 CDefaultSceneNodeAnimatorFactory::getCreatableSceneNodeAnimatorTypeCount() const +{ + return ESNAT_COUNT; +} + + +//! returns type of a createable scene node animator type +ESCENE_NODE_ANIMATOR_TYPE CDefaultSceneNodeAnimatorFactory::getCreateableSceneNodeAnimatorType(u32 idx) const +{ + if (idxaddCubeSceneNode(10, parent); + case ESNT_SPHERE: + return Manager->addSphereSceneNode(5, 16, parent); + case ESNT_TEXT: + return Manager->addTextSceneNode(0, L"example"); + case ESNT_WATER_SURFACE: + return Manager->addWaterSurfaceSceneNode(0, 2.0f, 300.0f, 10.0f, parent); + case ESNT_TERRAIN: + return Manager->addTerrainSceneNode((const char*)0, parent, -1, + core::vector3df(0.0f,0.0f,0.0f), + core::vector3df(0.0f,0.0f,0.0f), + core::vector3df(1.0f,1.0f,1.0f), + video::SColor(255,255,255,255), + 4, ETPS_17, 0, true); + case ESNT_SKY_BOX: + return Manager->addSkyBoxSceneNode(0,0,0,0,0,0, parent); + case ESNT_SHADOW_VOLUME: + return 0; + case ESNT_OCT_TREE: + return Manager->addOctTreeSceneNode((IMesh*)0, parent, -1, 128, true); + case ESNT_MESH: + return Manager->addMeshSceneNode(0, parent, -1, core::vector3df(), + core::vector3df(), core::vector3df(1,1,1), true); + case ESNT_LIGHT: + return Manager->addLightSceneNode(parent); + case ESNT_EMPTY: + return Manager->addEmptySceneNode(parent); + case ESNT_DUMMY_TRANSFORMATION: + return Manager->addDummyTransformationSceneNode(parent); + case ESNT_CAMERA: + return Manager->addCameraSceneNode(parent); + case ESNT_CAMERA_MAYA: + return Manager->addCameraSceneNodeMaya(parent); + case ESNT_CAMERA_FPS: + return Manager->addCameraSceneNodeFPS(parent); + case ESNT_BILLBOARD: + return Manager->addBillboardSceneNode(parent); + case ESNT_ANIMATED_MESH: + return Manager->addAnimatedMeshSceneNode(0, parent, -1, core::vector3df(), + core::vector3df(), core::vector3df(1,1,1), true); + case ESNT_PARTICLE_SYSTEM: + return Manager->addParticleSystemSceneNode(true, parent); + default: + break; + } + + return 0; +} + + +//! adds a scene node to the scene graph based on its type name +ISceneNode* CDefaultSceneNodeFactory::addSceneNode(const c8* typeName, ISceneNode* parent) +{ + return addSceneNode( getTypeFromName(typeName), parent ); +} + + +//! returns amount of scene node types this factory is able to create +u32 CDefaultSceneNodeFactory::getCreatableSceneNodeTypeCount() const +{ + return SupportedSceneNodeTypes.size(); +} + + +//! returns type of a createable scene node type +ESCENE_NODE_TYPE CDefaultSceneNodeFactory::getCreateableSceneNodeType(u32 idx) const +{ + if (idx SupportedSceneNodeTypes; + + ISceneManager* Manager; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CDepthBuffer.cpp b/src/dep/src/irrlicht/CDepthBuffer.cpp new file mode 100644 index 0000000..74d6479 --- /dev/null +++ b/src/dep/src/irrlicht/CDepthBuffer.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "SoftwareDriver2_compile_config.h" +#include "CDepthBuffer.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! constructor +CDepthBuffer::CDepthBuffer(const core::dimension2d& size) +: Buffer(0), Size(0,0) +{ + #ifdef _DEBUG + setDebugName("CDepthBuffer"); + #endif + + setSize(size); +} + + + +//! destructor +CDepthBuffer::~CDepthBuffer() +{ + if (Buffer) + delete [] Buffer; +} + + + +//! clears the zbuffer +void CDepthBuffer::clear() +{ + +#ifdef SOFTWARE_DRIVER_2_USE_WBUFFER + f32 zMax = 0.f; +#else + f32 zMax = 1.f; +#endif + + u32 zMaxValue; + zMaxValue = *(u32*) &zMax; + + memset32 ( Buffer, zMaxValue, TotalSize ); +} + + + +//! sets the new size of the zbuffer +void CDepthBuffer::setSize(const core::dimension2d& size) +{ + if (size == Size) + return; + + Size = size; + + if (Buffer) + delete [] Buffer; + + TotalSize = size.Width * size.Height * sizeof ( fp24 ); + Buffer = new u8[TotalSize]; +} + + + +//! returns the size of the zbuffer +const core::dimension2d& CDepthBuffer::getSize() const +{ + return Size; +} + + + +//! locks the zbuffer +fp24* CDepthBuffer::lock() +{ + return (fp24*) Buffer; +} + + + +//! unlocks the zbuffer +void CDepthBuffer::unlock() +{ +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a ZBuffer +IDepthBuffer* createDepthBuffer(const core::dimension2d& size) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CDepthBuffer(size); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CDepthBuffer.h b/src/dep/src/irrlicht/CDepthBuffer.h new file mode 100644 index 0000000..799053d --- /dev/null +++ b/src/dep/src/irrlicht/CDepthBuffer.h @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Z_BUFFER_H_INCLUDED__ +#define __C_Z_BUFFER_H_INCLUDED__ + +#include "IDepthBuffer.h" + +namespace irr +{ +namespace video +{ + + class CDepthBuffer : public IDepthBuffer + { + public: + + //! constructor + CDepthBuffer(const core::dimension2d& size); + + //! destructor + virtual ~CDepthBuffer(); + + //! clears the zbuffer + virtual void clear(); + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size); + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const; + + //! locks the zbuffer + virtual fp24* lock(); + + //! unlocks the zbuffer + virtual void unlock(); + + private: + + u8* Buffer; + core::dimension2d Size; + u32 TotalSize; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CDummyTransformationSceneNode.cpp b/src/dep/src/irrlicht/CDummyTransformationSceneNode.cpp new file mode 100644 index 0000000..2aee01e --- /dev/null +++ b/src/dep/src/irrlicht/CDummyTransformationSceneNode.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CDummyTransformationSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CDummyTransformationSceneNode::CDummyTransformationSceneNode( + ISceneNode* parent, ISceneManager* mgr, s32 id) + : IDummyTransformationSceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CDummyTransformationSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); +} + + + +//! destructor +CDummyTransformationSceneNode::~CDummyTransformationSceneNode() +{ +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CDummyTransformationSceneNode::getBoundingBox() const +{ + return Box; +} + + + +//! Returns a reference to the current relative transformation matrix. +//! This is the matrix, this scene node uses instead of scale, translation +//! and rotation. +core::matrix4& CDummyTransformationSceneNode::getRelativeTransformationMatrix() +{ + return RelativeTransformationMatrix; +} + + +//! Returns the relative transformation of the scene node. +core::matrix4 CDummyTransformationSceneNode::getRelativeTransformation() const +{ + return RelativeTransformationMatrix; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CDummyTransformationSceneNode.h b/src/dep/src/irrlicht/CDummyTransformationSceneNode.h new file mode 100644 index 0000000..eb3c432 --- /dev/null +++ b/src/dep/src/irrlicht/CDummyTransformationSceneNode.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ +#define __C_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ + +#include "IDummyTransformationSceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CDummyTransformationSceneNode : public IDummyTransformationSceneNode + { + public: + + //! constructor + CDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id); + + //! destructor + ~CDummyTransformationSceneNode(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns a reference to the current relative transformation matrix. + //! This is the matrix, this scene node uses instead of scale, translation + //! and rotation. + virtual core::matrix4& getRelativeTransformationMatrix(); + + //! Returns the relative transformation of the scene node. + virtual core::matrix4 getRelativeTransformation() const; + + //! does nothing. + virtual void render() {} + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_DUMMY_TRANSFORMATION; } + + private: + + core::matrix4 RelativeTransformationMatrix; + core::aabbox3d Box; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CEmptySceneNode.cpp b/src/dep/src/irrlicht/CEmptySceneNode.cpp new file mode 100644 index 0000000..4b21672 --- /dev/null +++ b/src/dep/src/irrlicht/CEmptySceneNode.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CEmptySceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CEmptySceneNode::CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) +: ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CEmptySceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); +} + + +//! pre render event +void CEmptySceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! render +void CEmptySceneNode::render() +{ + // do nothing +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CEmptySceneNode::getBoundingBox() const +{ + return Box; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CEmptySceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CEmptySceneNode* nb = new CEmptySceneNode(newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + nb->Box = Box; + + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr diff --git a/src/dep/src/irrlicht/CEmptySceneNode.h b/src/dep/src/irrlicht/CEmptySceneNode.h new file mode 100644 index 0000000..186192d --- /dev/null +++ b/src/dep/src/irrlicht/CEmptySceneNode.h @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_EMPTY_SCENE_NODE_H_INCLUDED__ +#define __C_EMPTY_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CEmptySceneNode : public ISceneNode + { + public: + + //! constructor + CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! This method is called just before the rendering process of the whole scene. + virtual void OnRegisterSceneNode(); + + //! does nothing. + virtual void render(); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_EMPTY; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + core::aabbox3d Box; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CFPSCounter.cpp b/src/dep/src/irrlicht/CFPSCounter.cpp new file mode 100644 index 0000000..c3abe00 --- /dev/null +++ b/src/dep/src/irrlicht/CFPSCounter.cpp @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CFPSCounter.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + + +CFPSCounter::CFPSCounter() +: FPS(60), Primitive(0), StartTime(0), FramesCounted(0), + PrimitivesCounted(0), PrimitiveAverage(0), PrimitiveTotal(0) +{ + +} + + +//! returns current fps +s32 CFPSCounter::getFPS() const +{ + return FPS; +} + + +//! returns current primitive count +u32 CFPSCounter::getPrimitive() const +{ + return Primitive; +} + + +//! returns average primitive count of last period +u32 CFPSCounter::getPrimitiveAverage() const +{ + return PrimitiveAverage; +} + + +//! returns accumulated primitive count since start +u32 CFPSCounter::getPrimitiveTotal() const +{ + return PrimitiveTotal; +} + + +//! to be called every frame +void CFPSCounter::registerFrame(u32 now, u32 primitivesDrawn) +{ + ++FramesCounted; + PrimitiveTotal += primitivesDrawn; + PrimitivesCounted += primitivesDrawn; + Primitive = primitivesDrawn; + + const u32 milliseconds = now - StartTime; + + if (milliseconds >= 1500 ) + { + const f32 invMilli = core::reciprocal ( (f32) milliseconds ); + + FPS = core::ceil32 ( ( 1000 * FramesCounted ) * invMilli ); + PrimitiveAverage = core::ceil32 ( ( 1000 * PrimitivesCounted ) * invMilli ); + + FramesCounted = 0; + PrimitivesCounted = 0; + StartTime = now; + } +} + + +} // end namespace video +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CFPSCounter.h b/src/dep/src/irrlicht/CFPSCounter.h new file mode 100644 index 0000000..f5341e3 --- /dev/null +++ b/src/dep/src/irrlicht/CFPSCounter.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FPSCOUNTER_H_INCLUDED__ +#define __C_FPSCOUNTER_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace video +{ + + +class CFPSCounter +{ +public: + CFPSCounter(); + + //! returns current fps + s32 getFPS() const; + + //! returns primitive count + u32 getPrimitive() const; + + //! returns average primitive count of last period + u32 getPrimitiveAverage() const; + + //! returns accumulated primitive count since start + u32 getPrimitiveTotal() const; + + //! to be called every frame + void registerFrame(u32 now, u32 primitive); + +private: + + s32 FPS; + u32 Primitive; + u32 StartTime; + + u32 FramesCounted; + u32 PrimitivesCounted; + u32 PrimitiveAverage; + u32 PrimitiveTotal; +}; + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CFileList.cpp b/src/dep/src/irrlicht/CFileList.cpp new file mode 100644 index 0000000..bd786f7 --- /dev/null +++ b/src/dep/src/irrlicht/CFileList.cpp @@ -0,0 +1,183 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CFileList.h" +#include "IrrCompileConfig.h" +#include "irrArray.h" +#include + +namespace irr +{ +namespace io +{ + +#if (defined(_IRR_POSIX_API_) || defined(MACOSX)) +#include +#include +#include + +#include +#include +#include +#include +#endif + +#ifdef _IRR_WINDOWS_API_ +#include +#include +#endif + + +CFileList::CFileList() +{ + #ifdef _DEBUG + setDebugName("CFileList"); + #endif + + // -------------------------------------------- + // Windows version + #ifdef _IRR_WINDOWS_API_ + + char tmp[_MAX_PATH]; + _getcwd(tmp, _MAX_PATH); + Path = tmp; + + struct _finddata_t c_file; + long hFile; + FileEntry entry; + + if( (hFile = _findfirst( "*", &c_file )) != -1L ) + { + do + { + entry.Name = c_file.name; + entry.Size = c_file.size; + entry.isDirectory = (_A_SUBDIR & c_file.attrib) != 0; + Files.push_back(entry); + } + while( _findnext( hFile, &c_file ) == 0 ); + + _findclose( hFile ); + } + + //TODO add drives + //entry.Name = "E:\\"; + //entry.isDirectory = true; + //Files.push_back(entry); + #endif + + // -------------------------------------------- + // Linux version + #if (defined(_IRR_POSIX_API_) || defined(MACOSX)) + + FileEntry entry; + + // Add default parent - even when at /, this is available + entry.Name = ".."; + entry.Size = 0; + entry.isDirectory = true; + Files.push_back(entry); + + // getting the CWD is rather complex as we do not know the size + // so try it until the call was successful + // Note that neither the first nor the second parameter may be 0 according to POSIX + u32 pathSize=256; + char *tmpPath = new char[pathSize]; + while ((pathSize < (1<<16)) && !(getcwd(tmpPath,pathSize))) + { + delete [] tmpPath; + pathSize *= 2; + tmpPath = new char[pathSize]; + } + if (!tmpPath) + return; + Path = tmpPath; + delete [] tmpPath; + // We use the POSIX compliant methods instead of scandir + DIR* dirHandle=opendir(Path.c_str()); + if (!dirHandle) + return; + + struct dirent *dirEntry; + while ((dirEntry=readdir(dirHandle))) + { + if((strcmp(dirEntry->d_name, ".")==0) || + (strcmp(dirEntry->d_name, "..")==0)) + continue; + entry.Name = dirEntry->d_name; + entry.Size = 0; + entry.isDirectory = false; + struct stat buf; + if (stat(dirEntry->d_name, &buf)==0) + { + entry.Size = buf.st_size; + entry.isDirectory = S_ISDIR(buf.st_mode); + } + #if !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__CYGWIN__) + // only available on some systems + else + { + entry.isDirectory = dirEntry->d_type == DT_DIR; + } + #endif + Files.push_back(entry); + } + closedir(dirHandle); + #endif + // sort the list on all platforms + Files.sort(); +} + + +u32 CFileList::getFileCount() const +{ + return Files.size(); +} + + +const c8* CFileList::getFileName(u32 index) const +{ + if (index < Files.size()) + return Files[index].Name.c_str(); + else + return 0; +} + + +//! Gets the full name of a file in the list, path included, based on an index. +const c8* CFileList::getFullFileName(u32 index) +{ + if (index >= Files.size()) + return 0; + + if (Files[index].FullName.size() < Files[index].Name.size()) + { + // create full name + Files[index].FullName = Path; + + if (Path.size() > 3) + Files[index].FullName.append('/'); + + Files[index].FullName.append(Files[index].Name); + } + + return Files[index].FullName.c_str(); +} + + +bool CFileList::isDirectory(u32 index) const +{ + bool ret; + if (index >= Files.size()) + ret = false; + else + ret = Files[index].isDirectory; + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +} // end namespace irr +} // end namespace io + diff --git a/src/dep/src/irrlicht/CFileList.h b/src/dep/src/irrlicht/CFileList.h new file mode 100644 index 0000000..a6c9753 --- /dev/null +++ b/src/dep/src/irrlicht/CFileList.h @@ -0,0 +1,78 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FILE_LIST_H_INCLUDED__ +#define __C_FILE_LIST_H_INCLUDED__ + +#include "IFileList.h" +#include "irrString.h" +#include "irrArray.h" + +namespace irr +{ +namespace io +{ + +/*! + FileSystem, which manages where files are, so that modules which + use the the io do not need to know where every file is located. +*/ +class CFileList : public IFileList +{ +public: + + //! constructor + CFileList(); + + //! Returns the amount of files in the filelist. + //! \return + //! Returns the amount of files and directories in the file list. + virtual u32 getFileCount() const; + + //! Gets the name of a file in the list, based on an index. + //! \param index is the zero based index of the file which name should + //! be returned. The index has to be smaller than the amount getFileCount() returns. + //! \return + //! Returns the file name of the file. Returns 0, if an error occured. + virtual const c8* getFileName(u32 index) const; + + //! Gets the full name of a file in the list, path included, based on an index. + virtual const c8* getFullFileName(u32 index); + + //! Returns of the file is a directory + //! \param index is the zero based index of the file which name should + //! be returned. The index has to be smaller than the amount getFileCount() returns. + //! \return + //! Returns true, if the file is a directory, and false, if it is not. + //! If an error occurs, the result is undefined. + virtual bool isDirectory(u32 index) const; + +private: + + struct FileEntry + { + core::stringc Name; + core::stringc FullName; + long Size; + bool isDirectory; + + bool operator <(const struct FileEntry& other) const + { + if ( isDirectory ^ other.isDirectory ) + return isDirectory; + + return Name.lower_ignore_case ( other.Name ); + } + }; + + core::stringc Path; + core::array< FileEntry > Files; +}; + +} // end namespace irr +} // end namespace io + + +#endif + diff --git a/src/dep/src/irrlicht/CFileSystem.cpp b/src/dep/src/irrlicht/CFileSystem.cpp new file mode 100644 index 0000000..0b2dcfa --- /dev/null +++ b/src/dep/src/irrlicht/CFileSystem.cpp @@ -0,0 +1,359 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CFileSystem.h" +#include "IReadFile.h" +#include "IWriteFile.h" +#include "CZipReader.h" +#include "CPakReader.h" +#include "CFileList.h" +#include "CXMLReader.h" +#include "CXMLWriter.h" +#include "stdio.h" +#include "os.h" +#include "IrrCompileConfig.h" +#include "CAttributes.h" +#include "CMemoryReadFile.h" + +#ifdef _IRR_WINDOWS_API_ +#include // for _chdir +#else +#include +#include +#include +#endif + +namespace irr +{ +namespace io +{ + + +//! constructor +CFileSystem::CFileSystem() +{ + #ifdef _DEBUG + setDebugName("CFileSystem"); + #endif +} + + + +//! destructor +CFileSystem::~CFileSystem() +{ + u32 i; + + for ( i=0; idrop(); + + for ( i=0; idrop(); + + for ( i= 0; idrop(); +} + + + +//! opens a file for read access +IReadFile* CFileSystem::createAndOpenFile(const c8* filename) +{ + IReadFile* file = 0; + u32 i; + + for ( i=0; iopenFile(filename); + if (file) + return file; + } + + for ( i = 0; iopenFile(filename); + if (file) + return file; + } + + for ( i = 0; iopenFile(filename); + if (file) + return file; + } + + file = createReadFile(filename); + return file; +} + +//! Creates an IReadFile interface for treating memory like a file. +IReadFile* CFileSystem::createMemoryReadFile(void* memory, s32 len, + const c8* fileName, bool deleteMemoryWhenDropped) +{ + if (!memory) + return 0; + else + return new CMemoryReadFile(memory, len, fileName, deleteMemoryWhenDropped); +} + +//! Opens a file for write access. +IWriteFile* CFileSystem::createAndWriteFile(const c8* filename, bool append) +{ + return createWriteFile(filename, append); +} + + +bool CFileSystem::addFolderFileArchive(const c8* filename, bool ignoreCase, bool ignorePaths) +{ + bool ret = false; + + CUnZipReader* zr = new CUnZipReader( this, filename, ignoreCase, ignorePaths); + if (zr) + { + UnZipFileSystems.push_back(zr); + ret = true; + } + + #ifdef _DEBUG + if ( false == ret ) + { + os::Printer::log("Could not open file. UnZipfile not added", filename, ELL_ERROR); + } + #endif + + return ret; + +} + + +//! adds an zip archive to the filesystem +bool CFileSystem::addZipFileArchive(const c8* filename, bool ignoreCase, bool ignorePaths) +{ + IReadFile* file = createReadFile(filename); + if (file) + { + CZipReader* zr = new CZipReader(file, ignoreCase, ignorePaths); + if (zr) + ZipFileSystems.push_back(zr); + + file->drop(); + + bool ret = (zr != 0); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; + } + + #ifdef _DEBUG + os::Printer::log("Could not open file. Zipfile not added", filename, ELL_ERROR); + #endif + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! adds an pak archive to the filesystem +bool CFileSystem::addPakFileArchive(const c8* filename, bool ignoreCase, bool ignorePaths) +{ + IReadFile* file = createReadFile(filename); + if (file) + { + CPakReader* zr = new CPakReader(file, ignoreCase, ignorePaths); + if (zr) + PakFileSystems.push_back(zr); + + file->drop(); + + bool ret = (zr != 0); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; + } + + #ifdef _DEBUG + os::Printer::log("Could not open file. Pakfile not added", filename, ELL_ERROR); + #endif + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! Returns the string of the current working directory +const c8* CFileSystem::getWorkingDirectory() +{ +#ifdef _IRR_WINDOWS_API_ + _getcwd(WorkingDirectory, FILE_SYSTEM_MAX_PATH); +#endif + +#if (defined(_IRR_POSIX_API_) || defined(MACOSX)) + getcwd(WorkingDirectory, (size_t)FILE_SYSTEM_MAX_PATH); +#endif + return WorkingDirectory; +} + + +//! Changes the current Working Directory to the given string. +//! The string is operating system dependent. Under Windows it will look +//! like this: "drive:\directory\sudirectory\" +//! \return Returns true if successful, otherwise false. +bool CFileSystem::changeWorkingDirectoryTo(const c8* newDirectory) +{ + bool success=false; +#ifdef _MSC_VER + success=(_chdir(newDirectory) == 0); +#else + success=(chdir(newDirectory) == 0); +#endif + return success; +} + +core::stringc CFileSystem::getAbsolutePath(const core::stringc& filename) const +{ + c8 *p=0; + core::stringc ret; + +#ifdef _IRR_WINDOWS_API_ + + c8 fpath[_MAX_PATH]; + p = _fullpath( fpath, filename.c_str(), _MAX_PATH); + ret = p; + +#elif (defined(_IRR_POSIX_API_) || defined(MACOSX)) + + c8 fpath[4096]; + p = realpath(filename.c_str(), fpath); + ret = p; + +#endif + + return ret; +} + +core::stringc CFileSystem::getFileDir(const core::stringc& filename) const +{ + // find last forward or backslash + s32 lastSlash = filename.findLast('/'); + const s32 lastBackSlash = filename.findLast('\\'); + lastSlash = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; + + if ((u32)lastSlash < filename.size()) + return filename.subString(0, lastSlash); + else + return "."; +} + +//! Creates a list of files and directories in the current working directory +IFileList* CFileSystem::createFileList() const +{ + return new CFileList(); +} + + +//! determines if a file exists and would be able to be opened. +bool CFileSystem::existFile(const c8* filename) const +{ + u32 i; + + for (i=0; ifindFile(filename)!=-1) + return true; + + for (i=0; ifindFile(filename)!=-1) + return true; + + for (i=0; ifindFile(filename)!=-1) + return true; + + FILE* f = fopen(filename, "rb"); + if (f) + { + fclose(f); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! Creates a XML Reader from a file. +IXMLReader* CFileSystem::createXMLReader(const c8* filename) +{ + IReadFile* file = createAndOpenFile(filename); + if (!file) + return 0; + + IXMLReader* reader = createXMLReader(file); + file->drop(); + return reader; +} + + +//! Creates a XML Reader from a file. +IXMLReader* CFileSystem::createXMLReader(IReadFile* file) +{ + if (!file) + return 0; + + return createIXMLReader(file); +} + +//! Creates a XML Reader from a file. +IXMLReaderUTF8* CFileSystem::createXMLReaderUTF8(const c8* filename) +{ + IReadFile* file = createAndOpenFile(filename); + if (!file) + return 0; + + IXMLReaderUTF8* reader = createIXMLReaderUTF8(file); + file->drop(); + return reader; +} + +//! Creates a XML Reader from a file. +IXMLReaderUTF8* CFileSystem::createXMLReaderUTF8(IReadFile* file) +{ + if (!file) + return 0; + + return createIXMLReaderUTF8(file); +} + + +//! Creates a XML Writer from a file. +IXMLWriter* CFileSystem::createXMLWriter(const c8* filename) +{ + IWriteFile* file = createAndWriteFile(filename); + IXMLWriter* writer = createXMLWriter(file); + file->drop(); + return writer; +} + + +//! Creates a XML Writer from a file. +IXMLWriter* CFileSystem::createXMLWriter(IWriteFile* file) +{ + return new CXMLWriter(file); +} + + +//! creates a filesystem which is able to open files from the ordinary file system, +//! and out of zipfiles, which are able to be added to the filesystem. +IFileSystem* createFileSystem() +{ + return new CFileSystem(); +} + +//! Creates a new empty collection of attributes, usable for serialization and more. +IAttributes* CFileSystem::createEmptyAttributes(video::IVideoDriver* driver) +{ + return new CAttributes(driver); +} + +} // end namespace irr +} // end namespace io + diff --git a/src/dep/src/irrlicht/CFileSystem.h b/src/dep/src/irrlicht/CFileSystem.h new file mode 100644 index 0000000..ad8a2d2 --- /dev/null +++ b/src/dep/src/irrlicht/CFileSystem.h @@ -0,0 +1,106 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FILE_SYSTEM_H_INCLUDED__ +#define __C_FILE_SYSTEM_H_INCLUDED__ + +#include "IFileSystem.h" +#include "irrArray.h" + +namespace irr +{ +namespace io +{ + + class CZipReader; + class CPakReader; + class CUnZipReader; + const s32 FILE_SYSTEM_MAX_PATH = 1024; + +/*! + FileSystem which uses normal files and one zipfile +*/ +class CFileSystem : public IFileSystem +{ +public: + + //! constructor + CFileSystem(); + + //! destructor + virtual ~CFileSystem(); + + //! opens a file for read access + virtual IReadFile* createAndOpenFile(const c8* filename); + + //! Creates an IReadFile interface for accessing memory like a file. + virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped = false); + + //! Opens a file for write access. + virtual IWriteFile* createAndWriteFile(const c8* filename, bool append=false); + + //! adds an zip archive to the filesystem + virtual bool addZipFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true); + virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true); + + //! adds an pak archive to the filesystem + virtual bool addPakFileArchive(const c8* filename, bool ignoreCase = true, bool ignorePaths = true); + + //! Returns the string of the current working directory + virtual const c8* getWorkingDirectory(); + + //! Changes the current Working Directory to the string given. + //! The string is operating system dependent. Under Windows it will look + //! like this: "drive:\directory\sudirectory\" + virtual bool changeWorkingDirectoryTo(const c8* newDirectory); + + //! Converts a relative path to an absolute (unique) path, resolving symbolic links + virtual core::stringc getAbsolutePath(const core::stringc& filename) const; + + //! Returns the directory a file is located in. + /** \param filename: The file to get the directory from */ + virtual core::stringc getFileDir(const core::stringc& filename) const; + + //! Creates a list of files and directories in the current working directory + //! and returns it. + virtual IFileList* createFileList() const; + + //! determinates if a file exists and would be able to be opened. + virtual bool existFile(const c8* filename) const; + + //! Creates a XML Reader from a file. + virtual IXMLReader* createXMLReader(const c8* filename); + + //! Creates a XML Reader from a file. + virtual IXMLReader* createXMLReader(IReadFile* file); + + //! Creates a XML Reader from a file. + virtual IXMLReaderUTF8* createXMLReaderUTF8(const c8* filename); + + //! Creates a XML Reader from a file. + virtual IXMLReaderUTF8* createXMLReaderUTF8(IReadFile* file); + + //! Creates a XML Writer from a file. + virtual IXMLWriter* createXMLWriter(const c8* filename); + + //! Creates a XML Writer from a file. + virtual IXMLWriter* createXMLWriter(IWriteFile* file); + + //! Creates a new empty collection of attributes, usable for serialization and more. + virtual IAttributes* createEmptyAttributes(video::IVideoDriver* driver); + +private: + + core::array ZipFileSystems; + core::array PakFileSystems; + core::array UnZipFileSystems; + c8 WorkingDirectory[FILE_SYSTEM_MAX_PATH]; +}; + + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/dep/src/irrlicht/CGUIButton.cpp b/src/dep/src/irrlicht/CGUIButton.cpp new file mode 100644 index 0000000..21ca02e --- /dev/null +++ b/src/dep/src/irrlicht/CGUIButton.cpp @@ -0,0 +1,469 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIButton.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool noclip) +: IGUIButton(environment, parent, id, rectangle), Pressed(false), + IsPushButton(false), UseAlphaChannel(false), Border(true), + MouseOverTime(0), FocusTime(0), ClickTime(0), SpriteBank(0), + OverrideFont(0), Image(0), PressedImage(0) +{ + #ifdef _DEBUG + setDebugName("CGUIButton"); + #endif + setNotClipped(noclip); + + // Initialize the sprites. + for (u32 i=0; idrop(); + + if (Image) + Image->drop(); + + if (PressedImage) + PressedImage->drop(); + + if (SpriteBank) + SpriteBank->drop(); +} + +//! Sets if the button should use the skin to draw its border +void CGUIButton::setDrawBorder(bool border) +{ + Border = border; +} + +void CGUIButton::setSpriteBank(IGUISpriteBank* sprites) +{ + if (sprites) + sprites->grab(); + + if (SpriteBank) + SpriteBank->drop(); + + SpriteBank = sprites; +} + +void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop) +{ + if (SpriteBank) + { + ButtonSprites[(u32)state].Index = index; + ButtonSprites[(u32)state].Color = color; + ButtonSprites[(u32)state].Loop = loop; + } + else + { + ButtonSprites[(u32)state].Index = -1; + } +} + +//! called if an event happened. +bool CGUIButton::OnEvent(const SEvent& event) +{ + if (!IsEnabled) + return Parent ? Parent->OnEvent(event) : false; + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_RETURN || + event.KeyInput.Key == KEY_SPACE)) + { + if (!IsPushButton) + setPressed(true); + else + setPressed(!Pressed); + + return true; + } + if (Pressed && !IsPushButton && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + setPressed(false); + return true; + } + else + if (!event.KeyInput.PressedDown && Pressed && + (event.KeyInput.Key == KEY_RETURN || + event.KeyInput.Key == KEY_SPACE)) + { + //Environment->removeFocus(this); + + if (!IsPushButton) + setPressed(false); + + if (Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this && !IsPushButton) + setPressed(false); + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + if (Environment->hasFocus(this) && + !AbsoluteClippingRect.isPointInside(core::position2d(event.MouseInput.X, event.MouseInput.Y))) + { + Environment->removeFocus(this); + return false; + } + + if (!IsPushButton) + setPressed(true); + + Environment->setFocus(this); + return true; + } + else + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + { + bool wasPressed = Pressed; + //Environment->removeFocus(this); + + if ( !AbsoluteClippingRect.isPointInside( core::position2d(event.MouseInput.X, event.MouseInput.Y ) ) ) + { + if (!IsPushButton) + setPressed(false); + return true; + } + + if (!IsPushButton) + setPressed(false); + else + { + setPressed(!Pressed); + } + + if ((!IsPushButton && wasPressed && Parent) || + (IsPushButton && wasPressed != Pressed)) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + + return true; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + + +//! draws the element and its children +void CGUIButton::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(EGDF_BUTTON); + + core::rect rect = AbsoluteRect; + + // todo: move sprite up and text down if the pressed state has a sprite + // draw sprites for focused and mouse-over + core::position2di spritePos = AbsoluteRect.getCenter(); + + if (!Pressed) + { + if (Border) + skin->draw3DButtonPaneStandard(this, rect, &AbsoluteClippingRect); + + if (Image) + { + core::position2d pos = AbsoluteRect.getCenter(); + pos.X -= ImageRect.getWidth() / 2; + pos.Y -= ImageRect.getHeight() / 2; + + driver->draw2DImage(Image, pos, ImageRect, &AbsoluteClippingRect, + video::SColor(255,255,255,255), UseAlphaChannel); + } + if (SpriteBank && ButtonSprites[EGBS_BUTTON_UP].Index != -1) + { + // draw pressed sprite + SpriteBank->draw2DSprite(ButtonSprites[EGBS_BUTTON_UP].Index, spritePos, + &AbsoluteClippingRect, ButtonSprites[EGBS_BUTTON_UP].Color, ClickTime, os::Timer::getTime(), + ButtonSprites[EGBS_BUTTON_UP].Loop, true); + } + } + else + { + if (Border) + skin->draw3DButtonPanePressed(this, rect, &AbsoluteClippingRect); + + if (PressedImage) + { + core::position2d pos = AbsoluteRect.getCenter(); + pos.X -= PressedImageRect.getWidth() / 2; + pos.Y -= PressedImageRect.getHeight() / 2; + // patch by Alan Tyndall/Jonas Petersen + if (Image == PressedImage && PressedImageRect == ImageRect) + { + pos.X += 1; + pos.Y += 1; + } + driver->draw2DImage(PressedImage, pos, PressedImageRect, &AbsoluteClippingRect, + video::SColor(255,255,255,255), UseAlphaChannel); + } + + if (SpriteBank && ButtonSprites[EGBS_BUTTON_DOWN].Index != -1) + { + // draw sprite + SpriteBank->draw2DSprite(ButtonSprites[EGBS_BUTTON_DOWN].Index, spritePos, + &AbsoluteClippingRect, ButtonSprites[EGBS_BUTTON_DOWN].Color, ClickTime, os::Timer::getTime(), + ButtonSprites[EGBS_BUTTON_DOWN].Loop, true); + } + + } + + if (Text.size()) + { + rect = AbsoluteRect; + if (Pressed) + rect.UpperLeftCorner.Y += 2; + + if (font) + font->draw(Text.c_str(), rect, + skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), true, true, + &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + + +//! sets another skin independent font. if this is set to zero, the button uses the font of the skin. +void CGUIButton::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); +} + + +//! Sets an image which should be displayed on the button when it is in normal state. +void CGUIButton::setImage(video::ITexture* image) +{ + if (Image) + Image->drop(); + + Image = image; + if (image) + ImageRect = core::rect(core::position2d(0,0), image->getOriginalSize()); + + if (Image) + Image->grab(); + + if (!PressedImage) + setPressedImage(Image); +} + +//! Sets the image which should be displayed on the button when it is in its normal state. +void CGUIButton::setImage(video::ITexture* image, const core::rect& pos) +{ + if (Image) + Image->drop(); + + Image = image; + ImageRect = pos; + + if (Image) + Image->grab(); + + if (!PressedImage) + setPressedImage(Image, pos); +} + +//! Sets an image which should be displayed on the button when it is in pressed state. +void CGUIButton::setPressedImage(video::ITexture* image) +{ + if (PressedImage) + PressedImage->drop(); + + PressedImage = image; + if (image) + PressedImageRect = core::rect(core::position2d(0,0), image->getOriginalSize()); + + if (PressedImage) + PressedImage->grab(); +} + +//! Sets the image which should be displayed on the button when it is in its pressed state. +void CGUIButton::setPressedImage(video::ITexture* image, const core::rect& pos) +{ + if (PressedImage) + PressedImage->drop(); + + PressedImage = image; + PressedImageRect = pos; + + if (PressedImage) + PressedImage->grab(); +} + + +//! Sets if the button should behave like a push button. Which means it +//! can be in two states: Normal or Pressed. With a click on the button, +//! the user can change the state of the button. +void CGUIButton::setIsPushButton(bool isPushButton) +{ + IsPushButton = isPushButton; +} + + +//! Returns if the button is currently pressed +bool CGUIButton::isPressed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Pressed; +} + +//! Sets the pressed state of the button if this is a pushbutton +void CGUIButton::setPressed(bool pressed) +{ + if (Pressed != pressed) + { + ClickTime = os::Timer::getTime(); + Pressed = pressed; + } +} + +//! Returns whether the button is a push button +bool CGUIButton::isPushButton() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsPushButton; +} + +//! Sets if the alpha channel should be used for drawing images on the button (default is false) +void CGUIButton::setUseAlphaChannel(bool useAlphaChannel) +{ + UseAlphaChannel = useAlphaChannel; +} + +//! Returns if the alpha channel should be used for drawing images on the button +bool CGUIButton::isAlphaChannelUsed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return UseAlphaChannel; +} + +bool CGUIButton::isDrawingBorder() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Border; +} + +//! Writes attributes of the element. +void CGUIButton::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + + IGUIButton::serializeAttributes(out,options); + + out->addBool ("PushButton", IsPushButton ); + if (IsPushButton) + out->addBool("Pressed", Pressed); + + out->addTexture ("Image", Image); + out->addRect ("ImageRect", ImageRect); + out->addTexture ("PressedImage", PressedImage); + out->addRect ("PressedImageRect", PressedImageRect); + + out->addBool ("Border", Border); + out->addBool ("UseAlphaChannel", UseAlphaChannel); + + // out->addString ("OverrideFont", OverrideFont); +} + +//! Reads attributes of the element +void CGUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIButton::deserializeAttributes(in,options); + + IsPushButton = in->getAttributeAsBool("PushButton"); + Pressed = IsPushButton ? in->getAttributeAsBool("Pressed") : false; + + core::rect rec = in->getAttributeAsRect("ImageRect"); + if (rec.isValid()) + setImage( in->getAttributeAsTexture("Image"), rec); + else + setImage( in->getAttributeAsTexture("Image") ); + + rec = in->getAttributeAsRect("PressedImageRect"); + if (rec.isValid()) + setPressedImage( in->getAttributeAsTexture("PressedImage"), rec); + else + setPressedImage( in->getAttributeAsTexture("PressedImage") ); + + setDrawBorder(in->getAttributeAsBool("Border")); + UseAlphaChannel = in->getAttributeAsBool("UseAlphaChannel"); + + // setOverrideFont(in->getAttributeAsString("OverrideFont")); + + updateAbsolutePosition(); +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIButton.h b/src/dep/src/irrlicht/CGUIButton.h new file mode 100644 index 0000000..4b6e12d --- /dev/null +++ b/src/dep/src/irrlicht/CGUIButton.h @@ -0,0 +1,133 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_BUTTON_H_INCLUDED__ +#define __C_GUI_BUTTON_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIButton.h" +#include "IGUISpriteBank.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + + class CGUIButton : public IGUIButton + { + public: + + //! constructor + CGUIButton(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool noclip=false); + + //! destructor + virtual ~CGUIButton(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! sets another skin independent font. if this is set to zero, the button uses the font of the skin. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image); + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image, const core::rect& pos); + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image); + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image, const core::rect& pos); + + //! Sets the sprite bank used by the button + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! Sets the animated sprite for a specific button state + /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite + \param state: State of the button to set the sprite for + \param index: The sprite number from the current sprite bank + \param color: The color of the sprite + */ + virtual void setSprite(EGUI_BUTTON_STATE state, s32 index, + video::SColor color=video::SColor(255,255,255,255), bool loop=false); + + //! Sets if the button should behave like a push button. Which means it + //! can be in two states: Normal or Pressed. With a click on the button, + //! the user can change the state of the button. + virtual void setIsPushButton(bool isPushButton); + + //! Returns if the button is currently pressed + virtual bool isPressed() const; + + //! Sets the pressed state of the button if this is a pushbutton + virtual void setPressed(bool pressed); + + //! Sets if the button should use the skin to draw its border + virtual void setDrawBorder(bool border); + + //! Sets if the alpha channel should be used for drawing images on the button (default is false) + virtual void setUseAlphaChannel(bool useAlphaChannel); + + //! Returns if the alpha channel should be used for drawing images on the button + virtual bool isAlphaChannelUsed() const; + + //! Returns if the button face and border are being drawn + virtual bool isDrawingBorder() const; + + //! Returns whether the button is a push button + virtual bool isPushButton() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + struct ButtonSprite + { + s32 Index; + video::SColor Color; + bool Loop; + }; + + bool Pressed; + bool IsPushButton; + bool UseAlphaChannel; + + bool Border; + + u32 MouseOverTime; + u32 FocusTime; + u32 ClickTime; + + IGUISpriteBank* SpriteBank; + IGUIFont* OverrideFont; + + ButtonSprite ButtonSprites[EGBS_COUNT]; + + video::ITexture* Image; + video::ITexture* PressedImage; + + core::rect ImageRect; + core::rect PressedImageRect; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_BUTTON_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUICheckBox.cpp b/src/dep/src/irrlicht/CGUICheckBox.cpp new file mode 100644 index 0000000..a99735f --- /dev/null +++ b/src/dep/src/irrlicht/CGUICheckBox.cpp @@ -0,0 +1,198 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUICheckBox.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUICheckBox::CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUICheckBox(environment, parent, id, rectangle), Pressed(false), Checked(checked), checkTime(0) +{ + #ifdef _DEBUG + setDebugName("CGUICheckBox"); + #endif + + // this element can be tabbed into + setTabStop(true); + setTabOrder(-1); +} + + + +//! called if an event happened. +bool CGUICheckBox::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_RETURN || + event.KeyInput.Key == KEY_SPACE)) + { + Pressed = true; + return true; + } + else + if (Pressed && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + Pressed = false; + return true; + } + else + if (!event.KeyInput.PressedDown && Pressed && + (event.KeyInput.Key == KEY_RETURN || + event.KeyInput.Key == KEY_SPACE)) + { + Pressed = false; + if (Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + Checked = !Checked; + newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + Pressed = false; + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + Pressed = true; + checkTime = os::Timer::getTime(); + Environment->setFocus(this); + return true; + } + else + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + { + bool wasPressed = Pressed; + Environment->removeFocus(this); + Pressed = false; + + if (wasPressed && Parent) + { + if ( !AbsoluteClippingRect.isPointInside( core::position2d(event.MouseInput.X, event.MouseInput.Y) ) ) + { + Pressed = false; + return true; + } + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + Checked = !Checked; + newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED; + Parent->OnEvent(newEvent); + } + + return true; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + + +//! draws the element and its children +void CGUICheckBox::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + core::rect rect = AbsoluteRect; + + s32 height = skin->getSize(EGDS_CHECK_BOX_WIDTH); + + core::rect checkRect(AbsoluteRect.UpperLeftCorner.X, + ((AbsoluteRect.getHeight() - height) / 2) + AbsoluteRect.UpperLeftCorner.Y, + 0, 0); + + checkRect.LowerRightCorner.X = checkRect.UpperLeftCorner.X + height; + checkRect.LowerRightCorner.Y = checkRect.UpperLeftCorner.Y + height; + + skin->draw3DSunkenPane(this, skin->getColor(Pressed ? EGDC_3D_FACE : EGDC_ACTIVE_CAPTION), + false, true, checkRect, &AbsoluteClippingRect); + + if (Checked && Environment->getSkin()) + Environment->getSkin()->drawIcon(this, EGDI_CHECK_BOX_CHECKED, checkRect.getCenter(), + checkTime, os::Timer::getTime(), false, &AbsoluteClippingRect); + + if (Text.size()) + { + checkRect = AbsoluteRect; + checkRect.UpperLeftCorner.X += height + 5; + + IGUIFont* font = skin->getFont(); + if (font) + font->draw(Text.c_str(), checkRect, + skin->getColor(EGDC_BUTTON_TEXT), false, true, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! set if box is checked +void CGUICheckBox::setChecked(bool checked) +{ + Checked = checked; +} + + +//! returns if box is checked +bool CGUICheckBox::isChecked() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Checked; +} + +//! Writes attributes of the element. +void CGUICheckBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUICheckBox::serializeAttributes(out,options); + out->addBool ("Checked", Checked ); +} + +//! Reads attributes of the element +void CGUICheckBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Checked = in->getAttributeAsBool ("Checked"); + + IGUICheckBox::deserializeAttributes(in,options); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUICheckBox.h b/src/dep/src/irrlicht/CGUICheckBox.h new file mode 100644 index 0000000..140ce74 --- /dev/null +++ b/src/dep/src/irrlicht/CGUICheckBox.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_CHECKBOX_H_INCLUDED__ +#define __C_GUI_CHECKBOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUICheckBox.h" + +namespace irr +{ +namespace gui +{ + + class CGUICheckBox : public IGUICheckBox + { + public: + + //! constructor + CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! set if box is checked + virtual void setChecked(bool checked); + + //! returns if box is checked + virtual bool isChecked() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + bool Pressed; + bool Checked; + u32 checkTime; + }; + +} // end namespace gui +} // end namespace irr + +#endif // __C_GUI_CHECKBOX_H_INCLUDED__ + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIColorSelectDialog.cpp b/src/dep/src/irrlicht/CGUIColorSelectDialog.cpp new file mode 100644 index 0000000..a58d567 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIColorSelectDialog.cpp @@ -0,0 +1,486 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIColorSelectDialog.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIStaticText.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "IFileList.h" +#include "os.h" +#include "SoftwareDriver2_helper.h" +#include "CImage.h" + +namespace irr +{ +namespace gui +{ + +const s32 CSD_WIDTH = 350; +const s32 CSD_HEIGHT = 300; + +struct sTemplate +{ + const wchar_t *pre; + const wchar_t *init; + const wchar_t *pos; + int x, y; + int range_down ,range_up; +}; + +static const sTemplate Template [] = +{ + { L"A:", L"0", 0,20,165, 0, 255 }, + { L"R:", L"0", 0,20,205, 0, 255 }, + { L"G:", L"0", 0,20,230, 0, 255 }, + { L"B:", L"0", 0,20,255, 0, 255 }, + { L"H:", L"0", L"°",180,205, 0, 360 }, + { L"S:", L"0", L"%",180,230, 0, 100 }, + { L"L:", L"0", L"%",180,255, 0, 100 }, +}; + +//! constructor +CGUIColorSelectDialog::CGUIColorSelectDialog( const wchar_t* title, IGUIEnvironment* environment, IGUIElement* parent, s32 id) +: IGUIColorSelectDialog(environment, parent, id, + core::rect((parent->getAbsolutePosition().getWidth()-CSD_WIDTH)/2, + (parent->getAbsolutePosition().getHeight()-CSD_HEIGHT)/2, + (parent->getAbsolutePosition().getWidth()-CSD_WIDTH)/2+CSD_WIDTH, + (parent->getAbsolutePosition().getHeight()-CSD_HEIGHT)/2+CSD_HEIGHT)), + Dragging(false) +{ + #ifdef _DEBUG + IGUIElement::setDebugName("CGUIColorSelectDialog"); + #endif + + Text = title; + + IGUISkin* skin = Environment->getSkin(); + core::rect rec; + + s32 buttonw = environment->getSkin()->getSize(EGDS_WINDOW_BUTTON_WIDTH); + s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), + this, -1, L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close"); + if (skin && skin->getSpriteBank()) + { + CloseButton->setSpriteBank(skin->getSpriteBank()); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), skin->getColor(EGDC_WINDOW_SYMBOL)); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), skin->getColor(EGDC_WINDOW_SYMBOL)); + } + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CloseButton->grab(); + + OKButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK"); + OKButton->setSubElement(true); + OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + OKButton->grab(); + + CancelButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel"); + CancelButton->setSubElement(true); + CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CancelButton->grab(); + + core::rect r; + + video::IVideoDriver* driver = Environment->getVideoDriver(); + ColorRing.Texture = driver->getTexture ( "#colorring" ); + if ( 0 == ColorRing.Texture ) + { + buildColorRing(core::dimension2d(128, 128), 1, + Environment->getSkin()->getColor(EGDC_3D_SHADOW).color); + } + + r.UpperLeftCorner.X = 20; + r.UpperLeftCorner.Y = 20; + ColorRing.Control = Environment->addImage(ColorRing.Texture, r.UpperLeftCorner, true, this); + ColorRing.Control->setSubElement(true); + ColorRing.Control->grab(); + + for ( u32 i = 0; i != sizeof (Template) / sizeof ( sTemplate ); ++i ) + { + if ( Template[i].pre ) + { + r.UpperLeftCorner.X = Template[i].x; + r.UpperLeftCorner.Y = Template[i].y; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 15; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + IGUIElement *t = Environment->addStaticText( Template[i].pre, r, false, false, this); + t->setSubElement(true); + } + + if ( Template[i].pos ) + { + r.UpperLeftCorner.X = Template[i].x + 52; + r.UpperLeftCorner.Y = Template[i].y; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 15; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + IGUIElement *t = Environment->addStaticText( Template[i].pos, r, false, false, this); + t->setSubElement(true); + } + + SBatteryItem item; + + r.UpperLeftCorner.X = Template[i].x + 15; + r.UpperLeftCorner.Y = Template[i].y; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 35; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + + item.Edit = Environment->addEditBox( Template[i].init, r, true, this); + item.Edit->setSubElement(true); + item.Edit->grab(); + + r.UpperLeftCorner.X = Template[i].x + 70; + r.UpperLeftCorner.Y = Template[i].y + 4; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 60; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 12; + + item.Scrollbar = Environment->addScrollBar(true, r, this); + item.Scrollbar->grab (); + item.Scrollbar->setSubElement(true); + item.Scrollbar->setMax ( Template[i].range_up - Template[i].range_down ); + item.Scrollbar->setSmallStep ( 1 ); + + Battery.push_back ( item ); + } + + bringToFront(CancelButton); + bringToFront(OKButton); +} + + + +//! destructor +CGUIColorSelectDialog::~CGUIColorSelectDialog() +{ + if (CloseButton) + CloseButton->drop(); + + if (OKButton) + OKButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + for ( u32 i = 0; i != Battery.size ();++i ) + { + Battery[i].Edit->drop (); + Battery[i].Scrollbar->drop (); + } + + if ( ColorRing.Control ) + { + ColorRing.Control->drop (); + } +} + +//! renders a antialiased, colored ring +void CGUIColorSelectDialog::buildColorRing( const core::dimension2d & dim, s32 supersample, const u32 borderColor ) +{ + video::CImage *RawTexture; + + core::dimension2d d; + d.Width = dim.Width * supersample; + d.Height = dim.Height * supersample; + + RawTexture = new video::CImage ( video::ECF_A8R8G8B8, d ); + + RawTexture->fill ( 0x00808080 ); + + + u8 * data= (u8*) RawTexture->lock(); + const u32 pitch = RawTexture->getPitch (); + + s32 radiusOut = ( d.Width / 2 ) - 4; + + const s32 fullR2 = radiusOut * radiusOut; + + + video::SColorHSL hsl; + video::SColor rgb; + + rgb.color = 0xFF000000; + hsl.Luminance = 0.5f; + hsl.Saturation = 1.f; + + + + core::position2d p; + u32 *dst; + for ( p.Y = -radiusOut; p.Y <= radiusOut; p.Y += 1 ) + { + s32 y2 = p.Y * p.Y; + + dst = (u32*) ( (u8* ) data + ( ( 4 + p.Y + radiusOut ) * pitch ) + (4 << 2 ) ); + + for ( p.X = -radiusOut; p.X <= radiusOut; p.X += 1, dst += 1 ) + { + s32 r2 = y2 + ( p.X * p.X ); + + // test point in circle + s32 testa = r2 - fullR2; + + if ( testa < 0 ) + { + // dotproduct u ( x,y ) * v ( 1, 0 ) = cosinus(a) + + f32 r = (f32) sqrt ( (f32) r2 ); + + // normalize, dotproduct = xnorm + f32 t = (f32) 1.0 / r; + f32 xn = -p.X * t; + + hsl.Hue = (f32) acos ( xn ); + if ( p.Y > 0 ) + hsl.Hue = (2.f * core::PI ) - hsl.Hue; + + hsl.Hue -= core::PI / 2.f; + + f32 rTest = r / radiusOut; +/* + if ( rTest < 0.25f ) + { + hsl.Luminance = rTest / 0.25f; + hsl.Saturation = 0.f; + hsl.settoRGB ( rgb ); + *dst = rgb.color; + } + else + if ( rTest < 0.4f ) + { + hsl.Saturation = ( rTest - 0.25f ) / 0.15f; + hsl.Luminance = 1.f - ( hsl.Saturation / 2.4f ); + hsl.Luminance = 0.5f; + hsl.settoRGB ( rgb ); + // *dst = rgb.color; + } + else + if ( rTest < 0.75f ) + { + hsl.Luminance = 0.5f; + hsl.Saturation = 1.f; + hsl.settoRGB ( rgb ); + *dst = rgb.color; + } + else + if ( rTest < 0.98f ) + { + hsl.Luminance = 0.5f - ( ( rTest - 0.75f ) / 0.75f ); + hsl.Saturation = 1.f; + hsl.settoRGB ( rgb ); + *dst = rgb.color; + } +*/ + + if ( rTest >= 0.5f ) + { + hsl.Luminance = 0.5f; + hsl.Saturation = 1.f; + hsl.settoRGB ( rgb ); + *dst = rgb.color; + } + + if ( rTest >= 0.5f && rTest <= 0.55f ) + { + u32 alpha = (s32) ( (rTest - 0.5f ) * ( 255.f / 0.05f ) ); + *dst = *dst & 0x00ffffff | (alpha << 24); + } + + if ( rTest >= 0.95f ) + { + u32 alpha = (s32) ( (rTest - 0.95f ) * ( 255.f / 0.05f ) ); + alpha = 255 - alpha; + *dst = *dst & 0x00ffffff | (alpha << 24); + } + + } + } + + } + + RawTexture->unlock (); + + if ( supersample > 1 ) + { + video::CImage * filter = new video::CImage(video::ECF_A8R8G8B8, dim ); + RawTexture->copyToScalingBoxFilter ( filter, 0 ); + RawTexture->drop (); + RawTexture = filter; + } + + + video::IVideoDriver* driver = Environment->getVideoDriver(); + + bool generateMipLevels = driver->getTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS ); + driver->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, false); + + ColorRing.Texture = driver->addTexture ( "#colorring", RawTexture ); + RawTexture->drop (); + + driver->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, generateMipLevels); + +} + + + +//! called if an event happened. +bool CGUIColorSelectDialog::OnEvent(const SEvent& event) +{ + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_SCROLL_BAR_CHANGED: + { + for ( u32 i = 0; i!= Battery.size (); ++i ) + { + if ( event.GUIEvent.Caller == Battery[i].Scrollbar ) + { + s32 pos = Battery[i].Scrollbar->getPos (); + s32 value = Template[i].range_down + ( pos ); + core::stringw s ( value ); + Battery[i].Edit->setText ( s.c_str() ); + } + } + return true; + } + + case EGET_ELEMENT_FOCUS_LOST: + Dragging = false; + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == CloseButton || + event.GUIEvent.Caller == CancelButton) + { + sendCancelEvent(); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == OKButton) + { + sendSelectedEvent(); + remove(); + return true; + } + break; + + case EGET_LISTBOX_CHANGED: + case EGET_LISTBOX_SELECTED_AGAIN: + default: + break; + + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = true; + Environment->setFocus(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + Environment->removeFocus(this); + return true; + case EMIE_MOUSE_MOVED: + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent) + if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) + + return true; + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + default: + break; + } + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void CGUIColorSelectDialog::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + core::rect rect = AbsoluteRect; + + rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), + rect, &AbsoluteClippingRect); + + if (Text.size()) + { + rect.UpperLeftCorner.X += 2; + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, + &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + + + +//! sends the event that the file has been selected. +void CGUIColorSelectDialog::sendSelectedEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_SELECTED; + Parent->OnEvent(event); +} + +//! sends the event that the file choose process has been canceld +void CGUIColorSelectDialog::sendCancelEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED; + Parent->OnEvent(event); +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIColorSelectDialog.h b/src/dep/src/irrlicht/CGUIColorSelectDialog.h new file mode 100644 index 0000000..f037015 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIColorSelectDialog.h @@ -0,0 +1,80 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ +#define __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIColorSelectDialog.h" +#include "IGUIButton.h" +#include "IGUIEditBox.h" +#include "IGUIScrollBar.h" +#include "IGUIImage.h" +#include "irrArray.h" + + +namespace irr +{ +namespace gui +{ + + class CGUIColorSelectDialog : public IGUIColorSelectDialog + { + public: + + //! constructor + CGUIColorSelectDialog(const wchar_t* title, IGUIEnvironment* environment, IGUIElement* parent, s32 id); + + //! destructor + virtual ~CGUIColorSelectDialog(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + private: + + //! sends the event that the file has been selected. + void sendSelectedEvent(); + + //! sends the event that the file choose process has been canceld + void sendCancelEvent(); + + core::position2d DragStart; + bool Dragging; + IGUIButton* CloseButton; + IGUIButton* OKButton; + IGUIButton* CancelButton; + + struct SBatteryItem + { + f32 Incoming; + f32 Outgoing; + IGUIEditBox * Edit; + IGUIScrollBar *Scrollbar; + }; + core::array< SBatteryItem > Battery; + + struct SColorCircle + { + IGUIImage * Control; + video::ITexture * Texture; + }; + SColorCircle ColorRing; + + void buildColorRing( const core::dimension2d & dim, s32 supersample, const u32 borderColor ); + + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ diff --git a/src/dep/src/irrlicht/CGUIComboBox.cpp b/src/dep/src/irrlicht/CGUIComboBox.cpp new file mode 100644 index 0000000..60fb2d6 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIComboBox.cpp @@ -0,0 +1,433 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIComboBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IGUIButton.h" +#include "CGUIListBox.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : IGUIComboBox(environment, parent, id, rectangle), + ListButton(0), ListBox(0), Selected(-1), HasFocus(false), LastFocus(0) +{ + #ifdef _DEBUG + setDebugName("CGUICheckBox"); + #endif + + IGUISkin* skin = Environment->getSkin(); + + s32 width = 15; + if (skin) + width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + + core::rect r; + r.UpperLeftCorner.X = rectangle.getWidth() - width - 2; + r.LowerRightCorner.X = rectangle.getWidth() - 2; + + r.UpperLeftCorner.Y = 2; + r.LowerRightCorner.Y = rectangle.getHeight() - 2; + + ListButton = Environment->addButton(r, this, -1, L""); + if (skin && skin->getSpriteBank()) + { + ListButton->setSpriteBank(skin->getSpriteBank()); + ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + } + ListButton->setSubElement(true); + ListButton->setTabStop(false); + + setNotClipped(true); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); +} + + +//! Returns amount of items in box +u32 CGUIComboBox::getItemCount() const +{ + return Items.size(); +} + + +//! returns string of an item. the idx may be a value from 0 to itemCount-1 +const wchar_t* CGUIComboBox::getItem(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].c_str(); +} + + +//! Removes an item from the combo box. +void CGUIComboBox::removeItem(u32 idx) +{ + if (idx >= Items.size()) + return; + + if (Selected == (s32)idx) + Selected = -1; + + Items.erase(idx); +} + +//! Returns caption of this element. +const wchar_t* CGUIComboBox::getText() const +{ + return getItem(Selected); +} + + +//! adds an item and returns the index of it +u32 CGUIComboBox::addItem(const wchar_t* text) +{ + Items.push_back(core::stringw(text)); + + if (Selected == -1) + Selected = 0; + + return Items.size() - 1; +} + + + +//! deletes all items in the combo box +void CGUIComboBox::clear() +{ + Items.clear(); + Selected = -1; +} + + + +//! returns id of selected item. returns -1 if no item is selected. +s32 CGUIComboBox::getSelected() const +{ + return Selected; +} + + + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUIComboBox::setSelected(s32 id) +{ + if (id < -1 || id >= (s32)Items.size()) + return; + + Selected = id; +} + +void CGUIComboBox::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + + const s32 width = Environment->getSkin()->getSize(EGDS_WINDOW_BUTTON_WIDTH); + + ListButton->setRelativePosition(core::rect(RelativeRect.getWidth() - width - 2, 2, + RelativeRect.getWidth() - 2, RelativeRect.getHeight() - 2)); +} + + +//! called if an event happened. +bool CGUIComboBox::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + + case EET_KEY_INPUT_EVENT: + if (ListBox && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + // hide list box + openCloseMenu(); + return true; + } + else + if (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE) + { + if (!event.KeyInput.PressedDown) + openCloseMenu(); + + ListButton->setPressed(ListBox == 0); + + return true; + } + else + if (event.KeyInput.PressedDown) + { + s32 oldSelected = Selected; + bool absorb = true; + switch (event.KeyInput.Key) + { + case KEY_DOWN: + Selected += 1; + break; + case KEY_UP: + Selected -= 1; + break; + case KEY_HOME: + case KEY_PRIOR: + Selected = 0; + break; + case KEY_END: + case KEY_NEXT: + Selected = (s32)Items.size()-1; + break; + default: + absorb = false; + } + + if (Selected <0) + Selected = 0; + + if (Selected >= (s32)Items.size()) + Selected = (s32)Items.size() -1; + + if (Selected != oldSelected) + sendSelectionChangedEvent(); + + if (absorb) + return true; + } + break; + + case EET_GUI_EVENT: + + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + if (ListBox && + (Environment->hasFocus(ListBox) || ListBox->isMyChild(event.GUIEvent.Caller) ) && + event.GUIEvent.Element != this && + event.GUIEvent.Element != ListButton && + event.GUIEvent.Element != ListBox && + !ListBox->isMyChild(event.GUIEvent.Element)) + { + openCloseMenu(); + } + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == ListButton) + { + openCloseMenu(); + return true; + } + break; + case EGET_LISTBOX_SELECTED_AGAIN: + case EGET_LISTBOX_CHANGED: + if (event.GUIEvent.Caller == ListBox) + { + Selected = ListBox->getSelected(); + if (Selected <0 || Selected >= (s32)Items.size()) + Selected = -1; + openCloseMenu(); + + sendSelectionChangedEvent(); + } + return true; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + // send to list box + if (ListBox && ListBox->isPointInside(p) && ListBox->OnEvent(event)) + return true; + + return true; + } + case EMIE_LMOUSE_LEFT_UP: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + // send to list box + if (ListBox && ListBox->getAbsolutePosition().isPointInside(p) && + ListBox->OnEvent(event)) + return true; + else + { + openCloseMenu(); + return true; + } + } + break; + case EMIE_MOUSE_WHEEL: + { + s32 oldSelected = Selected; + Selected += (event.MouseInput.Wheel < 0) ? 1 : -1; + + if (Selected <0) + Selected = 0; + + if (Selected >= (s32)Items.size()) + Selected = (s32)Items.size() -1; + + if (Selected != oldSelected) + sendSelectionChangedEvent(); + } + default: + break; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + + +void CGUIComboBox::sendSelectionChangedEvent() +{ + if (Parent) + { + SEvent event; + + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_COMBO_BOX_CHANGED; + Parent->OnEvent(event); + } +} + + + +//! draws the element and its children +void CGUIComboBox::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + IGUIElement *currentFocus = Environment->getFocus(); + if (currentFocus != LastFocus) + { + HasFocus = currentFocus == this || isMyChild(currentFocus); + LastFocus = currentFocus; + } + + core::rect frameRect(AbsoluteRect); + + // draw the border + + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), + true, true, frameRect, &AbsoluteClippingRect); + + // Draw text + + if (Selected != -1) + { + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X += 2; + frameRect.UpperLeftCorner.Y += 2; + frameRect.LowerRightCorner.X -= ListButton->getAbsolutePosition().getWidth() + 2; + frameRect.LowerRightCorner.Y -= 2; + if (HasFocus) + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + IGUIFont* font = skin->getFont(); + if (font) + font->draw(Items[Selected].c_str(), frameRect, + skin->getColor(HasFocus ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT), + false, true, &AbsoluteClippingRect); + } + + // draw buttons + IGUIElement::draw(); +} + + +void CGUIComboBox::openCloseMenu() +{ + if (ListBox) + { + // close list box + Environment->setFocus(this); + ListBox->remove(); + ListBox = 0; + } + else + { + if (Parent) + Parent->bringToFront(this); + + IGUISkin* skin = Environment->getSkin(); + s32 h = Items.size(); + + if (h > 5) + h = 5; + if (h == 0) + h = 1; + + IGUIFont* font = skin->getFont(); + if (font) + h *= (font->getDimension(L"A").Height + 4); + + // open list box + core::rect r(0, AbsoluteRect.getHeight(), + AbsoluteRect.getWidth(), AbsoluteRect.getHeight() + h); + + ListBox = new CGUIListBox(Environment, this, -1, r, false, true, true); + ListBox->setSubElement(true); + ListBox->drop(); + + for (s32 i=0; i<(s32)Items.size(); ++i) + ListBox->addItem(Items[i].c_str()); + + ListBox->setSelected(Selected); + + // set focus + Environment->setFocus(ListBox); + } +} + +//! Writes attributes of the element. +void CGUIComboBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIComboBox::serializeAttributes(out,options); + + out->addInt ("Selected", Selected ); + out->addArray ("Items", Items); +} + +//! Reads attributes of the element +void CGUIComboBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Items = in->getAttributeAsArray("Items"); + IGUIComboBox::deserializeAttributes(in,options); + + setSelected(in->getAttributeAsInt("Selected")); +} + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIComboBox.h b/src/dep/src/irrlicht/CGUIComboBox.h new file mode 100644 index 0000000..f6e4a86 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIComboBox.h @@ -0,0 +1,90 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_COMBO_BOX_H_INCLUDED__ +#define __C_GUI_COMBO_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIComboBox.h" +#include "irrString.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + class IGUIListBox; + + //! Single line edit box for editing simple text. + class CGUIComboBox : public IGUIComboBox + { + public: + + //! constructor + CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle); + + //! Returns amount of items in box + virtual u32 getItemCount() const; + + //! returns string of an item. the idx may be a value from 0 to itemCount-1 + virtual const wchar_t* getItem(u32 idx) const; + + //! adds an item and returns the index of it + virtual u32 addItem(const wchar_t* text); + + //! Removes an item from the combo box. + virtual void removeItem(u32 id); + + //! deletes all items in the combo box + virtual void clear(); + + //! returns the text of the currently selected item + virtual const wchar_t* getText() const; + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 id); + + //! update the position + virtual void updateAbsolutePosition(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void openCloseMenu(); + void sendSelectionChangedEvent(); + + IGUIButton* ListButton; + IGUIListBox* ListBox; + core::array< core::stringw > Items; + s32 Selected; + bool HasFocus; + IGUIElement *LastFocus; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_COMBO_BOX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIContextMenu.cpp b/src/dep/src/irrlicht/CGUIContextMenu.cpp new file mode 100644 index 0000000..ef2efe9 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIContextMenu.cpp @@ -0,0 +1,754 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIContextMenu.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIContextMenu::CGUIContextMenu(IGUIEnvironment* environment, + IGUIElement* parent, s32 id, + core::rect rectangle, bool getFocus, bool allowFocus) + : IGUIContextMenu(environment, parent, id, rectangle), HighLighted(-1), + ChangeTime(0), EventParent(0), AllowFocus(allowFocus), LastFont(0) +{ + #ifdef _DEBUG + setDebugName("CGUIContextMenu"); + #endif + + Pos = rectangle.UpperLeftCorner; + recalculateSize(); + + if (getFocus) + Environment->setFocus(this); + + setNotClipped(true); +} + + +//! destructor +CGUIContextMenu::~CGUIContextMenu() +{ + for (u32 i=0; idrop(); + + if (LastFont) + LastFont->drop(); +} + + +//! Returns amount of menu items +u32 CGUIContextMenu::getItemCount() const +{ + return Items.size(); +} + + +//! Adds a menu item. +u32 CGUIContextMenu::addItem(const wchar_t* text, s32 id, bool enabled, bool hasSubMenu, bool checked) +{ + SItem s; + s.Enabled = enabled; + s.Checked = checked; + s.Text = text; + s.IsSeparator = (text == 0); + s.SubMenu = 0; + s.CommandId = id; + + if (hasSubMenu) + { + s.SubMenu = new CGUIContextMenu(Environment, this, id, + core::rect(0,0,100,100), false, false); + s.SubMenu->setVisible(false); + } + + Items.push_back(s); + + recalculateSize(); + return Items.size() - 1; +} + + +//! Adds a sub menu from an element that already exists. +void CGUIContextMenu::setSubMenu(u32 index, CGUIContextMenu* menu) +{ + if (index >= Items.size()) + return; + + if (Items[index].SubMenu) + Items[index].SubMenu->drop(); + + Items[index].SubMenu = menu; + menu->setVisible(false); + + if (Items[index].SubMenu) + { + menu->grab(); + menu->AllowFocus = false; + if ( Environment->getFocus() == menu ) + { + Environment->setFocus( this ); + } + } + + recalculateSize(); +} + + +//! Adds a separator item to the menu +void CGUIContextMenu::addSeparator() +{ + addItem(0, -1, true, false, false); +} + + +//! Returns text of the menu item. +const wchar_t* CGUIContextMenu::getItemText(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].Text.c_str(); +} + + +//! Sets text of the menu item. +void CGUIContextMenu::setItemText(u32 idx, const wchar_t* text) +{ + if (idx >= Items.size()) + return; + + Items[idx].Text = text; + recalculateSize(); +} + + +//! Returns if a menu item is enabled +bool CGUIContextMenu::isItemEnabled(u32 idx) const +{ + if (idx >= Items.size()) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Items[idx].Enabled; +} + + +//! Returns if a menu item is checked +bool CGUIContextMenu::isItemChecked(u32 idx) const +{ + if (idx >= Items.size()) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Items[idx].Checked; +} + + +//! Sets if the menu item should be enabled. +void CGUIContextMenu::setItemEnabled(u32 idx, bool enabled) +{ + if (idx >= Items.size()) + return; + + Items[idx].Enabled = enabled; +} + + +//! Sets if the menu item should be checked. +void CGUIContextMenu::setItemChecked(u32 idx, bool checked ) +{ + if (idx >= Items.size()) + return; + + Items[idx].Checked = checked; +} + + +//! Removes a menu item +void CGUIContextMenu::removeItem(u32 idx) +{ + if (idx >= Items.size()) + return; + + if (Items[idx].SubMenu) + { + Items[idx].SubMenu->drop(); + Items[idx].SubMenu = 0; + } + + Items.erase(idx); + recalculateSize(); +} + + +//! Removes all menu items +void CGUIContextMenu::removeAllItems() +{ + for (u32 i=0; idrop(); + + Items.clear(); + recalculateSize(); +} + + +//! called if an event happened. +bool CGUIContextMenu::OnEvent(const SEvent& event) +{ + if (!IsEnabled) + return Parent ? Parent->OnEvent(event) : false; + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + if (event.GUIEvent.Caller == this && !isMyChild(event.GUIEvent.Element) && AllowFocus) + { + // set event parent of submenus + setEventParent(Parent); + remove(); + return false; + } + break; + case EGET_ELEMENT_FOCUSED: + if (event.GUIEvent.Caller == this && !AllowFocus) + { + return true; + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_LEFT_UP: + { + // menu might be removed if it loses focus in sendClick, so grab a reference + grab(); + const u32 t = sendClick(core::position2d(event.MouseInput.X, event.MouseInput.Y)); + if ((t==0 || t==1) && Environment->hasFocus(this)) + Environment->removeFocus(this); + drop(); + } + return true; + case EMIE_LMOUSE_PRESSED_DOWN: + return true; + case EMIE_MOUSE_MOVED: + if (Environment->hasFocus(this)) + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), true); + return true; + default: + break; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! Sets the visible state of this element. +void CGUIContextMenu::setVisible(bool visible) +{ + HighLighted = -1; + ChangeTime = os::Timer::getTime(); + for (u32 j=0; jsetVisible(false); + + IGUIElement::setVisible(visible); +} + + +//! sends a click Returns: +//! 0 if click went outside of the element, +//! 1 if a valid button was clicked, +//! 2 if a nonclickable element was clicked +u32 CGUIContextMenu::sendClick(const core::position2d& p) +{ + u32 t = 0; + + // get number of open submenu + s32 openmenu = -1; + s32 j; + for (j=0; j<(s32)Items.size(); ++j) + if (Items[j].SubMenu && Items[j].SubMenu->isVisible()) + { + openmenu = j; + break; + } + + // delegate click operation to submenu + if (openmenu != -1) + { + t = Items[j].SubMenu->sendClick(p); + if (t != 0) + return t; // clicked something + } + + // check click on myself + if (isPointInside(p) && + (u32)HighLighted < Items.size()) + { + if (!Items[HighLighted].Enabled || + Items[HighLighted].IsSeparator || + Items[HighLighted].SubMenu) + return 2; + + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_MENU_ITEM_SELECTED; + if (Parent) + Parent->OnEvent(event); + else + if (EventParent) + EventParent->OnEvent(event); + + return 1; + } + + return 0; +} + + +//! returns true, if an element was highligted +bool CGUIContextMenu::highlight(const core::position2d& p, bool canOpenSubMenu) +{ + // get number of open submenu + s32 openmenu = -1; + s32 i; + for (i=0; i<(s32)Items.size(); ++i) + if (Items[i].SubMenu && Items[i].SubMenu->isVisible()) + { + openmenu = i; + break; + } + + // delegate highlight operation to submenu + if (openmenu != -1) + { + if (Items[openmenu].SubMenu->highlight(p, canOpenSubMenu)) + { + HighLighted = openmenu; + ChangeTime = os::Timer::getTime(); + return true; + } + } + + // highlight myself + for (i=0; i<(s32)Items.size(); ++i) + if (getHRect(Items[i], AbsoluteRect).isPointInside(p)) + { + HighLighted = i; + ChangeTime = os::Timer::getTime(); + + // make submenus visible/invisible + for (s32 j=0; j<(s32)Items.size(); ++j) + if (Items[j].SubMenu) + { + if ( j == i && canOpenSubMenu ) + Items[j].SubMenu->setVisible(true); + else if ( j != i ) + Items[j].SubMenu->setVisible(false); + } + return true; + } + + HighLighted = openmenu; + return false; +} + + +//! returns the item highlight-area +core::rect CGUIContextMenu::getHRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.Y += i.PosY; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height; + return r; +} + + +//! Gets drawing rect of Item +core::rect CGUIContextMenu::getRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.Y += i.PosY; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height; + r.UpperLeftCorner.X += 20; + return r; +} + + +//! draws the element and its children +void CGUIContextMenu::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + if (!skin) + return; + + IGUIFont* font = skin->getFont(EGDF_MENU); + if (font != LastFont) + { + if (LastFont) + LastFont->drop(); + LastFont = font; + if (LastFont) + LastFont->grab(); + + recalculateSize(); + } + + IGUISpriteBank* sprites = skin->getSpriteBank(); + + core::rect rect = AbsoluteRect; + core::rect* clip = 0; + + // draw frame + skin->draw3DMenuPane(this, AbsoluteRect, clip); + + // loop through all menu items + + rect = AbsoluteRect; + s32 y = AbsoluteRect.UpperLeftCorner.Y; + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (Items[i].IsSeparator) + { + // draw separator + rect = AbsoluteRect; + rect.UpperLeftCorner.Y += Items[i].PosY + 3; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + rect.UpperLeftCorner.X += 5; + rect.LowerRightCorner.X -= 5; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), rect, clip); + + rect.LowerRightCorner.Y += 1; + rect.UpperLeftCorner.Y += 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + y += 10; + } + else + { + rect = getRect(Items[i], AbsoluteRect); + + // draw highlighted + + if (i == HighLighted && Items[i].Enabled) + { + core::rect r = AbsoluteRect; + r.LowerRightCorner.Y = rect.LowerRightCorner.Y; + r.UpperLeftCorner.Y = rect.UpperLeftCorner.Y; + r.LowerRightCorner.X -= 5; + r.UpperLeftCorner.X += 5; + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), r, clip); + } + + // draw text + + EGUI_DEFAULT_COLOR c = EGDC_BUTTON_TEXT; + + if (i == HighLighted) + c = EGDC_HIGH_LIGHT_TEXT; + + if (!Items[i].Enabled) + c = EGDC_GRAY_TEXT; + + if (font) + font->draw(Items[i].Text.c_str(), rect, + skin->getColor(c), false, true, clip); + + // draw submenu symbol + if (Items[i].SubMenu && sprites) + { + core::rect r = rect; + r.UpperLeftCorner.X = r.LowerRightCorner.X - 15; + + sprites->draw2DSprite(skin->getIcon(EGDI_CURSOR_RIGHT), + r.getCenter(), clip, skin->getColor(c), + (i == HighLighted) ? ChangeTime : 0, + (i == HighLighted) ? os::Timer::getTime() : 0, + (i == HighLighted), true); + } + + // draw checked symbol + if (Items[i].Checked && sprites) + { + core::rect r = rect; + r.LowerRightCorner.X = r.UpperLeftCorner.X - 15; + r.UpperLeftCorner.X = r.LowerRightCorner.X + 15; + sprites->draw2DSprite(skin->getIcon(EGDI_CHECK_BOX_CHECKED), + r.getCenter(), clip, skin->getColor(c), + (i == HighLighted) ? ChangeTime : 0, + (i == HighLighted) ? os::Timer::getTime() : 0, + (i == HighLighted), true); + } + } + } + + IGUIElement::draw(); +} + + +void CGUIContextMenu::recalculateSize() +{ + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(EGDF_MENU); + + if (!font) + return; + + core::rect rect; + rect.UpperLeftCorner = RelativeRect.UpperLeftCorner; + s32 width = 100; + s32 height = 3; + + u32 i; + for (i=0; igetDimension(Items[i].Text.c_str()); + Items[i].Dim.Width += 40; + + if (Items[i].Dim.Width > width) + width = Items[i].Dim.Width; + } + + Items[i].PosY = height; + height += Items[i].Dim.Height; + } + + height += 5; + + if (height < 10) + height = 10; + + rect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + width; + rect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + height; + + setRelativePosition(rect); + + // recalculate submenus + for (i=0; igetAbsolutePosition().getWidth(); + const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); + + Items[i].SubMenu->setRelativePosition( + core::rect(width-5, Items[i].PosY, + width+w-5, Items[i].PosY+h)); + } + } +} + + +//! Returns the selected item in the menu +s32 CGUIContextMenu::getSelectedItem() const +{ + return HighLighted; +} + + +//! \return Returns a pointer to the submenu of an item. +IGUIContextMenu* CGUIContextMenu::getSubMenu(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].SubMenu; +} + + +//! Returns command id of a menu item +s32 CGUIContextMenu::getItemCommandId(u32 idx) const +{ + if (idx >= Items.size()) + return -1; + + return Items[idx].CommandId; +} + + +//! Sets the command id of a menu item +void CGUIContextMenu::setItemCommandId(u32 idx, s32 id) +{ + if (idx >= Items.size()) + return; + + Items[idx].CommandId = id; +} + + +//! Writes attributes of the element. +void CGUIContextMenu::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIElement::serializeAttributes(out,options); + out->addPosition2d("Position", Pos); + + if (Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU ) + { + const IGUIContextMenu* const ptr = (const IGUIContextMenu*)Parent; + // find the position of this item in its parent's list + u32 i; + // VC6 needs the cast for this + for (i=0; (igetItemCount()) && (ptr->getSubMenu(i) != (const IGUIContextMenu*)this); ++i) + ; // do nothing + + out->addInt("ParentItem", i); + } + + // write out the item list + out->addInt("ItemCount", Items.size()); + + core::stringc tmp; + + for (u32 i=0; i < Items.size(); ++i) + { + tmp = "IsSeparator"; tmp += i; + out->addBool(tmp.c_str(), Items[i].IsSeparator); + + if (!Items[i].IsSeparator) + { + tmp = "Text"; tmp += i; + out->addString(tmp.c_str(), Items[i].Text.c_str()); + tmp = "CommandID"; tmp += i; + out->addInt(tmp.c_str(), Items[i].CommandId); + tmp = "Enabled"; tmp += i; + out->addBool(tmp.c_str(), Items[i].Enabled); + } + } +} + + +//! Reads attributes of the element +void CGUIContextMenu::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIElement::deserializeAttributes(in,options); + + Pos = in->getAttributeAsPosition2d("Position"); + + // link to this item's parent + if (Parent && ( Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU ) ) + ((CGUIContextMenu*)Parent)->setSubMenu(in->getAttributeAsInt("ParentItem"),this); + + + removeAllItems(); + + // read the item list + const s32 count = in->getAttributeAsInt("ItemCount"); + + for (s32 i=0; igetAttributeAsBool(tmp.c_str()) ) + addSeparator(); + else + { + tmp = "Text"; tmp += i; + txt = in->getAttributeAsStringW(tmp.c_str()); + + tmp = "CommandID"; tmp += i; + commandid = in->getAttributeAsInt(tmp.c_str()); + + tmp = "Enabled"; tmp += i; + enabled = in->getAttributeAsBool(tmp.c_str()); + + tmp = "Checked"; tmp += i; + checked = in->getAttributeAsBool(tmp.c_str()); + + addItem(core::stringw(txt.c_str()).c_str(), commandid, enabled, false, checked); + } + } + + recalculateSize(); +} + + +// because sometimes the element has no parent at click time +void CGUIContextMenu::setEventParent(IGUIElement *parent) +{ + EventParent = parent; + + for (u32 i=0; isetEventParent(parent); +} + + +bool CGUIContextMenu::hasOpenSubMenu() const +{ + for (u32 i=0; iisVisible() ) + return true; + return false; +} + + +void CGUIContextMenu::closeAllSubMenus() +{ + for (u32 i=0; isetVisible(false); + + //HighLighted = -1; +} + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIContextMenu.h b/src/dep/src/irrlicht/CGUIContextMenu.h new file mode 100644 index 0000000..2ff910f --- /dev/null +++ b/src/dep/src/irrlicht/CGUIContextMenu.h @@ -0,0 +1,151 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_CONTEXT_MENU_H_INCLUDED__ +#define __C_GUI_CONTEXT_MENU_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIContextMenu.h" +#include "irrString.h" +#include "irrArray.h" +#include "IGUIFont.h" + +namespace irr +{ +namespace gui +{ + + //! GUI Context menu interface. + class CGUIContextMenu : public IGUIContextMenu + { + public: + + //! constructor + CGUIContextMenu(IGUIEnvironment* environment, + IGUIElement* parent, s32 id, core::rect rectangle, + bool getFocus = true, bool allowFocus = true); + + //! destructor + virtual ~CGUIContextMenu(); + + //! Returns amount of menu items + virtual u32 getItemCount() const; + + //! Adds a menu item. + virtual u32 addItem(const wchar_t* text, s32 commandid, + bool enabled, bool hasSubMenu, bool checked); + + //! Adds a separator item to the menu + virtual void addSeparator(); + + //! Returns text of the menu item. + virtual const wchar_t* getItemText(u32 idx) const; + + //! Sets text of the menu item. + virtual void setItemText(u32 idx, const wchar_t* text); + + //! Returns if a menu item is enabled + virtual bool isItemEnabled(u32 idx) const; + + //! Sets if the menu item should be enabled. + virtual void setItemEnabled(u32 idx, bool enabled); + + //! Returns if a menu item is checked + virtual bool isItemChecked(u32 idx) const; + + //! Sets if the menu item should be checked. + virtual void setItemChecked(u32 idx, bool enabled); + + //! Removes a menu item + virtual void removeItem(u32 idx); + + //! Removes all menu items + virtual void removeAllItems(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Returns the selected item in the menu + virtual s32 getSelectedItem() const; + + //! Returns a pointer to the submenu of an item. + //! \return Pointer to the submenu of an item. + virtual IGUIContextMenu* getSubMenu(u32 idx) const; + + //! Sets the visible state of this element. + virtual void setVisible(bool visible); + + //! Returns command id of a menu item + virtual s32 getItemCommandId(u32 idx) const; + + //! Sets the command id of a menu item + virtual void setItemCommandId(u32 idx, s32 id); + + //! Adds a sub menu from an element that already exists. + virtual void setSubMenu(u32 index, CGUIContextMenu* menu); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + + void closeAllSubMenus(); + bool hasOpenSubMenu() const; + + struct SItem + { + core::stringw Text; + bool IsSeparator; + bool Enabled; + bool Checked; + core::dimension2d Dim; + s32 PosY; + CGUIContextMenu* SubMenu; + s32 CommandId; + }; + + virtual void recalculateSize(); + + //! returns true, if an element was highlighted + virtual bool highlight(const core::position2d& p, bool canOpenSubMenu); + + //! sends a click Returns: + //! 0 if click went outside of the element, + //! 1 if a valid button was clicked, + //! 2 if a nonclickable element was clicked + virtual u32 sendClick(const core::position2d& p); + + //! returns the item highlight-area + virtual core::rect getHRect(const SItem& i, const core::rect& absolute) const; + + //! Gets drawing rect of Item + virtual core::rect getRect(const SItem& i, const core::rect& absolute) const; + + void setEventParent(IGUIElement *parent); + + s32 HighLighted; + core::array Items; + core::position2d Pos; + u32 ChangeTime; + IGUIElement* EventParent; + bool AllowFocus; + IGUIFont *LastFont; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_CONTEXT_MENU_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIEditBox.cpp b/src/dep/src/irrlicht/CGUIEditBox.cpp new file mode 100644 index 0000000..7fe7ce8 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIEditBox.cpp @@ -0,0 +1,1360 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIEditBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" +#include "os.h" +#include "Keycodes.h" + +/* + todo: + optional scrollbars + ctrl+left/right to select word + double click/ctrl click: word select + drag to select whole words, triple click to select line + optional? dragging selected text + numerical +*/ + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, + const core::rect& rectangle) +: IGUIEditBox(environment, parent, id, rectangle), MouseMarking(false), + Border(border), OverrideColorEnabled(false), MarkBegin(0), MarkEnd(0), + OverrideColor(video::SColor(101,255,255,255)), + OverrideFont(0), LastBreakFont(0), CursorPos(0), HScrollPos(0), VScrollPos(0), Max(0), + WordWrap(false), MultiLine(false), AutoScroll(true), PasswordBox(false), + PasswordChar(L'*'), + HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER) + +{ + #ifdef _DEBUG + setDebugName("CGUIEditBox"); + #endif + + Text = text; + + Operator = environment->getOSOperator(); + + if (Operator) + Operator->grab(); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + breakText(); +} + + +//! destructor +CGUIEditBox::~CGUIEditBox() +{ + if (OverrideFont) + OverrideFont->drop(); + + if (Operator) + Operator->drop(); +} + + +//! Sets another skin independent font. +void CGUIEditBox::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + breakText(); +} + + +//! Sets another color for the text. +void CGUIEditBox::setOverrideColor(video::SColor color) +{ + OverrideColor = color; + OverrideColorEnabled = true; +} + + +//! Turns the border on or off +void CGUIEditBox::setDrawBorder(bool border) +{ + Border = border; +} + + +//! Sets if the text should use the overide color or the color in the gui skin. +void CGUIEditBox::enableOverrideColor(bool enable) +{ + OverrideColorEnabled = enable; +} + + +//! Enables or disables word wrap +void CGUIEditBox::setWordWrap(bool enable) +{ + WordWrap = enable; + breakText(); +} + + +void CGUIEditBox::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + breakText(); +} + + +//! Checks if word wrap is enabled +bool CGUIEditBox::isWordWrapEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return WordWrap; +} + + +//! Enables or disables newlines. +void CGUIEditBox::setMultiLine(bool enable) +{ + MultiLine = enable; +} + + +//! Checks if multi line editing is enabled +bool CGUIEditBox::isMultiLineEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return MultiLine; +} + + +void CGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar) +{ + PasswordBox = passwordBox; + if (PasswordBox) + { + PasswordChar = passwordChar; + setMultiLine(false); + setWordWrap(false); + BrokenText.clear(); + } +} + + +bool CGUIEditBox::isPasswordBox() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return PasswordBox; +} + + +//! Sets text justification +void CGUIEditBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; +} + + +//! called if an event happened. +bool CGUIEditBox::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + { + MouseMarking = false; + MarkBegin = 0; + MarkEnd = 0; + } + } + break; + case EET_KEY_INPUT_EVENT: + if (processKey(event)) + return true; + break; + case EET_MOUSE_INPUT_EVENT: + if (processMouse(event)) + return true; + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +bool CGUIEditBox::processKey(const SEvent& event) +{ + if (!event.KeyInput.PressedDown) + return false; + + bool textChanged = false; + + // control shortcut handling + + if (event.KeyInput.Control) + { + switch(event.KeyInput.Key) + { + case KEY_KEY_A: + // select all + MarkBegin = 0; + MarkEnd = Text.size(); + break; + case KEY_KEY_C: + // copy to clipboard + if (!PasswordBox && Operator && MarkBegin != MarkEnd) + { + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + core::stringc s; + s = Text.subString(realmbgn, realmend - realmbgn).c_str(); + Operator->copyToClipboard(s.c_str()); + } + break; + case KEY_KEY_X: + // cut to the clipboard + if (!PasswordBox && Operator && MarkBegin != MarkEnd) + { + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + // copy + core::stringc sc; + sc = Text.subString(realmbgn, realmend - realmbgn).c_str(); + Operator->copyToClipboard(sc.c_str()); + + if (IsEnabled) + { + // delete + core::stringw s; + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + MarkBegin = 0; + MarkEnd = 0; + textChanged = true; + } + } + break; + case KEY_KEY_V: + if ( !IsEnabled ) + break; + + // paste from the clipboard + if (Operator) + { + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + // add new character + const c8* p = Operator->getTextFromClipboard(); + if (p) + { + if (MarkBegin == MarkEnd) + { + // insert text + core::stringw s = Text.subString(0, CursorPos); + s.append(p); + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + + if (!Max || s.size()<=Max) // thx to Fish FH for fix + { + Text = s; + s = p; + CursorPos += s.size(); + } + } + else + { + // replace text + + core::stringw s = Text.subString(0, realmbgn); + s.append(p); + s.append( Text.subString(realmend, Text.size()-realmend) ); + + if (!Max || s.size()<=Max) // thx to Fish FH for fix + { + Text = s; + s = p; + CursorPos = realmbgn + s.size(); + } + } + } + + MarkBegin = 0; + MarkEnd = 0; + textChanged = true; + } + break; + case KEY_HOME: + // move/highlight to start of text + if (event.KeyInput.Shift) + { + MarkEnd = CursorPos; + MarkBegin = 0; + CursorPos = 0; + } + else + { + CursorPos = 0; + MarkBegin = 0; + MarkEnd = 0; + } + break; + case KEY_END: + // move/highlight to end of text + if (event.KeyInput.Shift) + { + MarkBegin = CursorPos; + MarkEnd = Text.size(); + CursorPos = 0; + } + else + { + CursorPos = Text.size(); + MarkBegin = 0; + MarkEnd = 0; + } + break; + default: + return false; + } + } + + // default keyboard handling + + if (!event.KeyInput.Control) + switch(event.KeyInput.Key) + { + case KEY_END: + { + s32 p = Text.size(); + if (WordWrap || MultiLine) + { + p = getLineFromPos(CursorPos); + p = BrokenTextPositions[p] + (s32)BrokenText[p].size(); + if (p > 0 && (Text[p-1] == L'\r' || Text[p-1] == L'\n' )) + p-=1; + } + + if (event.KeyInput.Shift) + { + if (MarkBegin == MarkEnd) + MarkBegin = CursorPos; + + MarkEnd = p; + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + CursorPos = p; + BlinkStartTime = os::Timer::getTime(); + } + break; + case KEY_HOME: + { + + s32 p = 0; + if (WordWrap || MultiLine) + { + p = getLineFromPos(CursorPos); + p = BrokenTextPositions[p]; + } + + if (event.KeyInput.Shift) + { + if (MarkBegin == MarkEnd) + MarkBegin = CursorPos; + MarkEnd = p; + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + CursorPos = p; + BlinkStartTime = os::Timer::getTime(); + } + break; + case KEY_RETURN: + if (MultiLine) + { + inputChar(L'\n'); + } + else + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_EDITBOX_ENTER; + Parent->OnEvent(e); + } + break; + case KEY_LEFT: + + if (event.KeyInput.Shift) + { + if (CursorPos > 0) + { + if (MarkBegin == MarkEnd) + MarkBegin = CursorPos; + + MarkEnd = CursorPos-1; + } + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + + if (CursorPos > 0) CursorPos--; + BlinkStartTime = os::Timer::getTime(); + break; + + case KEY_RIGHT: + if (event.KeyInput.Shift) + { + if (Text.size() > (u32)CursorPos) + { + if (MarkBegin == MarkEnd) + MarkBegin = CursorPos; + + MarkEnd = CursorPos+1; + } + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + + if (Text.size() > (u32)CursorPos) CursorPos++; + BlinkStartTime = os::Timer::getTime(); + break; + case KEY_UP: + if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + { + s32 lineNo = getLineFromPos(CursorPos); + s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd); + if (lineNo > 0) + { + s32 cp = CursorPos - BrokenTextPositions[lineNo]; + if ((s32)BrokenText[lineNo-1].size() < cp) + CursorPos = BrokenTextPositions[lineNo-1] + (s32)BrokenText[lineNo-1].size()-1; + else + CursorPos = BrokenTextPositions[lineNo-1] + cp; + } + + if (event.KeyInput.Shift) + { + MarkBegin = mb; + MarkEnd = CursorPos; + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + + } + else + { + return false; + } + break; + case KEY_DOWN: + if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + { + s32 lineNo = getLineFromPos(CursorPos); + s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd); + if (lineNo < (s32)BrokenText.size()-1) + { + s32 cp = CursorPos - BrokenTextPositions[lineNo]; + if ((s32)BrokenText[lineNo+1].size() < cp) + CursorPos = BrokenTextPositions[lineNo+1] + BrokenText[lineNo+1].size()-1; + else + CursorPos = BrokenTextPositions[lineNo+1] + cp; + } + + if (event.KeyInput.Shift) + { + MarkBegin = mb; + MarkEnd = CursorPos; + } + else + { + MarkBegin = 0; + MarkEnd = 0; + } + + } + else + { + return false; + } + break; + + case KEY_BACK: + if ( !this->IsEnabled ) + break; + + if (Text.size()) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // delete marked text + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + } + else + { + // delete text behind cursor + if (CursorPos>0) + s = Text.subString(0, CursorPos-1); + else + s = L""; + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + Text = s; + --CursorPos; + } + + if (CursorPos < 0) + CursorPos = 0; + BlinkStartTime = os::Timer::getTime(); + MarkBegin = 0; + MarkEnd = 0; + textChanged = true; + } + break; + case KEY_DELETE: + if ( !this->IsEnabled ) + break; + + if (Text.size() != 0) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // delete marked text + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + } + else + { + // delete text before cursor + s = Text.subString(0, CursorPos); + s.append( Text.subString(CursorPos+1, Text.size()-CursorPos-1) ); + Text = s; + } + + if (CursorPos > (s32)Text.size()) + CursorPos = (s32)Text.size(); + + BlinkStartTime = os::Timer::getTime(); + MarkBegin = 0; + MarkEnd = 0; + textChanged = true; + } + break; + + case KEY_ESCAPE: + case KEY_TAB: + case KEY_SHIFT: + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + case KEY_F11: + case KEY_F12: + case KEY_F13: + case KEY_F14: + case KEY_F15: + case KEY_F16: + case KEY_F17: + case KEY_F18: + case KEY_F19: + case KEY_F20: + case KEY_F21: + case KEY_F22: + case KEY_F23: + case KEY_F24: + // ignore these keys + return false; + + default: + inputChar(event.KeyInput.Char); + break; + } + + // break the text if it has changed + if (textChanged) + breakText(); + + calculateScrollPos(); + + return true; +} + +//! draws the element and its children +void CGUIEditBox::draw() +{ + if (!IsVisible) + return; + + bool focus = Environment->hasFocus(this); + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + frameRect = AbsoluteRect; + + // draw the border + + if (Border) + { + skin->draw3DSunkenPane(this, skin->getColor(EGDC_WINDOW), + false, true, frameRect, &AbsoluteClippingRect); + + frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1; + frameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; + frameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1; + frameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; + } + core::rect localClipRect = frameRect; + localClipRect.clipAgainst(AbsoluteClippingRect); + + // draw the text + + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(); + + s32 cursorLine = 0; + s32 charcursorpos = 0; + + if (font) + { + if (LastBreakFont != font) + breakText(); + + // calculate cursor pos + + core::stringw *txtLine = &Text; + s32 startPos = 0; + + core::stringw s, s2; + + // get mark position + bool ml = (!PasswordBox && (WordWrap || MultiLine)); + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0; + s32 hlineCount = ml ? getLineFromPos(realmend) - hlineStart + 1 : 1; + s32 lineCount = ml ? BrokenText.size() : 1; + + // Save the override color information. + // Then, alter it if the edit box is disabled. + bool prevOver = OverrideColorEnabled; + video::SColor prevColor = OverrideColor; + + if (Text.size()) + { + if (!IsEnabled && !OverrideColorEnabled) + { + OverrideColorEnabled = true; + OverrideColor = skin->getColor(EGDC_GRAY_TEXT); + } + + for (s32 i=0; i < lineCount; ++i) + { + setTextRect(i); + + // clipping test - don't draw anything outside the visible area + core::rect c = localClipRect; + c.clipAgainst(CurrentTextRect); + if (!c.isValid()) + continue; + + // get current line + if (PasswordBox) + { + if (BrokenText.size() != 1) + { + BrokenText.clear(); + BrokenText.push_back(core::stringw()); + } + if (BrokenText[0].size() != Text.size()) + { + BrokenText[0] = Text; + for (u32 q = 0; q < Text.size(); ++q) + { + BrokenText[0] [q] = PasswordChar; + } + } + txtLine = &BrokenText[0]; + startPos = 0; + } + else + { + txtLine = ml ? &BrokenText[i] : &Text; + startPos = ml ? BrokenTextPositions[i] : 0; + } + + + // draw normal text + font->draw(txtLine->c_str(), CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &localClipRect); + + // draw mark and marked text + if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount) + { + + s32 mbegin = 0, mend = 0; + s32 lineStartPos = 0, lineEndPos = txtLine->size(); + + if (i == hlineStart) + { + // highlight start is on this line + s = txtLine->subString(0, realmbgn - startPos); + mbegin = font->getDimension(s.c_str()).Width; + lineStartPos = realmbgn - startPos; + } + if (i == hlineStart + hlineCount - 1) + { + // highlight end is on this line + s2 = txtLine->subString(0, realmend - startPos); + mend = font->getDimension(s2.c_str()).Width; + lineEndPos = (s32)s2.size(); + } + else + mend = font->getDimension(txtLine->c_str()).Width; + + CurrentTextRect.UpperLeftCorner.X += mbegin; + CurrentTextRect.LowerRightCorner.X = CurrentTextRect.UpperLeftCorner.X + mend - mbegin; + + // draw mark + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect); + + // draw marked text + s = txtLine->subString(lineStartPos, lineEndPos - lineStartPos); + + if (s.size()) + font->draw(s.c_str(), CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT), + false, true, &localClipRect); + + } + } + + // Return the override color information to its previous settings. + OverrideColorEnabled = prevOver; + OverrideColor = prevColor; + } + + // draw cursor + + if (WordWrap || MultiLine) + { + cursorLine = getLineFromPos(CursorPos); + txtLine = &BrokenText[cursorLine]; + startPos = BrokenTextPositions[cursorLine]; + } + s = txtLine->subString(0,CursorPos-startPos); + charcursorpos = font->getDimension(s.c_str()).Width; + + if (focus && (os::Timer::getTime() - BlinkStartTime) % 700 < 350) + { + setTextRect(cursorLine); + CurrentTextRect.UpperLeftCorner.X += charcursorpos; + + font->draw(L"_", CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &localClipRect); + } + } +} + + +//! Sets the new caption of this element. +void CGUIEditBox::setText(const wchar_t* text) +{ + Text = text; + CursorPos = 0; + HScrollPos = 0; + MarkBegin = 0; + MarkEnd = 0; + breakText(); +} + + +//! Enables or disables automatic scrolling with cursor position +//! \param enable: If set to true, the text will move around with the cursor position +void CGUIEditBox::setAutoScroll(bool enable) +{ + AutoScroll = enable; +} + + +//! Checks to see if automatic scrolling is enabled +//! \return true if automatic scrolling is enabled, false if not +bool CGUIEditBox::isAutoScrollEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return AutoScroll; +} + +//! Gets the area of the text in the edit box +//! \return Returns the size in pixels of the text +core::dimension2di CGUIEditBox::getTextDimension() +{ + core::rect ret; + + setTextRect(0); + ret = CurrentTextRect; + + for (u32 i=1; i < BrokenText.size(); ++i) + { + setTextRect(i); + ret.addInternalPoint(CurrentTextRect.UpperLeftCorner); + ret.addInternalPoint(CurrentTextRect.LowerRightCorner); + } + + return ret.getSize(); +} + + +//! Sets the maximum amount of characters which may be entered in the box. +//! \param max: Maximum amount of characters. If 0, the character amount is +//! infinity. +void CGUIEditBox::setMax(u32 max) +{ + Max = max; + + if (Text.size() > Max && Max != 0) + Text = Text.subString(0, Max); +} + + +//! Returns maximum amount of characters, previously set by setMax(); +u32 CGUIEditBox::getMax() const +{ + return Max; +} + + +bool CGUIEditBox::processMouse(const SEvent& event) +{ + switch(event.MouseInput.Event) + { + case irr::EMIE_LMOUSE_LEFT_UP: + if (Environment->hasFocus(this)) + { + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + if (MouseMarking) + MarkEnd = CursorPos; + MouseMarking = false; + calculateScrollPos(); + return true; + } + break; + case irr::EMIE_MOUSE_MOVED: + { + if (MouseMarking) + { + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + MarkEnd = CursorPos; + calculateScrollPos(); + return true; + } + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: + if (!Environment->hasFocus(this)) + { + // get focus + BlinkStartTime = os::Timer::getTime(); + Environment->setFocus(this); + MouseMarking = true; + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + MarkBegin = CursorPos; + MarkEnd = CursorPos; + calculateScrollPos(); + return true; + } + else + { + if (!AbsoluteClippingRect.isPointInside( + core::position2d(event.MouseInput.X, event.MouseInput.Y))) + { + return false; + } + else + { + // move cursor + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + + if (!MouseMarking) + MarkBegin = CursorPos; + + MouseMarking = true; + MarkEnd = CursorPos; + calculateScrollPos(); + return true; + } + } + default: + break; + } + + return false; +} + + +s32 CGUIEditBox::getCursorPos(s32 x, s32 y) +{ + IGUIFont* font = OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (!OverrideFont) + font = skin->getFont(); + + u32 lineCount = 1; + + if (WordWrap || MultiLine) + lineCount = BrokenText.size(); + + core::stringw *txtLine=0; + s32 startPos=0; + x+=3; + + for (u32 i=0; i < lineCount; ++i) + { + setTextRect(i); + if (i == 0 && y < CurrentTextRect.UpperLeftCorner.Y) + y = CurrentTextRect.UpperLeftCorner.Y; + if (i == lineCount - 1 && y > CurrentTextRect.LowerRightCorner.Y ) + y = CurrentTextRect.LowerRightCorner.Y; + + // is it inside this region? + if (y >= CurrentTextRect.UpperLeftCorner.Y && y <= CurrentTextRect.LowerRightCorner.Y) + { + // we've found the clicked line + txtLine = (WordWrap || MultiLine) ? &BrokenText[i] : &Text; + startPos = (WordWrap || MultiLine) ? BrokenTextPositions[i] : 0; + break; + } + } + + if (x < CurrentTextRect.UpperLeftCorner.X) + x = CurrentTextRect.UpperLeftCorner.X; + + s32 idx = font->getCharacterFromPos(Text.c_str(), x - CurrentTextRect.UpperLeftCorner.X); + + // click was on or left of the line + if (idx != -1) + return idx + startPos; + + // click was off the right edge of the line, go to end. + return txtLine->size() + startPos; +} + + +//! Breaks the single text line. +void CGUIEditBox::breakText() +{ + IGUISkin* skin = Environment->getSkin(); + + if ((!WordWrap && !MultiLine) || !skin) + return; + + BrokenText.clear(); // need to reallocate :/ + BrokenTextPositions.set_used(0); + + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(); + + if (!font) + return; + + LastBreakFont = font; + + core::stringw line; + core::stringw word; + core::stringw whitespace; + s32 lastLineStart = 0; + s32 size = Text.size(); + s32 length = 0; + s32 elWidth = RelativeRect.getWidth() - 6; + wchar_t c; + + for (s32 i=0; igetDimension(whitespace.c_str()).Width; + s32 worldlgth = font->getDimension(word.c_str()).Width; + + if (WordWrap && length + worldlgth + whitelgth > elWidth) + { + // break to next line + length = worldlgth; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); + lastLineStart = i - (s32)word.size(); + line = word; + } + else + { + // add word to line + line += whitespace; + line += word; + length += whitelgth + worldlgth; + } + + word = L""; + whitespace = L""; + } + + whitespace += c; + + // compute line break + if (lineBreak) + { + line += whitespace; + line += word; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); + lastLineStart = i+1; + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } + else + { + // yippee this is a word.. + word += c; + } + } + + line += whitespace; + line += word; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); +} + + +void CGUIEditBox::setTextRect(s32 line) +{ + core::dimension2di d; + s32 lineCount = 1; + + IGUIFont* font = OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (!OverrideFont) + font = skin->getFont(); + + // get text dimension + if (WordWrap || MultiLine) + { + lineCount = BrokenText.size(); + d = font->getDimension(BrokenText[line].c_str()); + } + else + { + d = font->getDimension(Text.c_str()); + d.Height = AbsoluteRect.getHeight(); + } + d.Height += font->getKerningHeight(); + + // justification + switch (HAlign) + { + case EGUIA_CENTER: + // align to h centre + CurrentTextRect.UpperLeftCorner.X = (frameRect.getWidth()/2) - (d.Width/2); + CurrentTextRect.LowerRightCorner.X = (frameRect.getWidth()/2) + (d.Width/2); + break; + case EGUIA_LOWERRIGHT: + // align to right edge + CurrentTextRect.UpperLeftCorner.X = frameRect.getWidth() - d.Width; + CurrentTextRect.LowerRightCorner.X = frameRect.getWidth(); + break; + default: + // align to left edge + CurrentTextRect.UpperLeftCorner.X = 0; + CurrentTextRect.LowerRightCorner.X = d.Width; + + } + + switch (VAlign) + { + case EGUIA_CENTER: + // align to v centre + CurrentTextRect.UpperLeftCorner.Y = + (frameRect.getHeight()/2) - (lineCount*d.Height)/2 + d.Height*line; + break; + case EGUIA_LOWERRIGHT: + // align to bottom edge + CurrentTextRect.UpperLeftCorner.Y = + frameRect.getHeight() - lineCount*d.Height + d.Height*line; + break; + default: + // align to top edge + CurrentTextRect.UpperLeftCorner.Y = d.Height*line; + break; + } + + CurrentTextRect.UpperLeftCorner.X -= HScrollPos; + CurrentTextRect.LowerRightCorner.X -= HScrollPos; + CurrentTextRect.UpperLeftCorner.Y -= VScrollPos; + CurrentTextRect.LowerRightCorner.Y = CurrentTextRect.UpperLeftCorner.Y + d.Height; + + CurrentTextRect += frameRect.UpperLeftCorner; + +} + + +s32 CGUIEditBox::getLineFromPos(s32 pos) +{ + if (!WordWrap && !MultiLine) + return 0; + + s32 i=0; + while (i < (s32)BrokenTextPositions.size()) + { + if (BrokenTextPositions[i] > pos) + return i-1; + ++i; + } + return (s32)BrokenTextPositions.size() - 1; +} + + +void CGUIEditBox::inputChar(wchar_t c) +{ + if (!IsEnabled) + return; + + if (c != 0) + { + if (Text.size() < Max || Max == 0) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // replace marked text + s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append(c); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + CursorPos = realmbgn+1; + } + else + { + // add new character + s = Text.subString(0, CursorPos); + s.append(c); + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + Text = s; + ++CursorPos; + } + + BlinkStartTime = os::Timer::getTime(); + MarkBegin = 0; + MarkEnd = 0; + } + } + breakText(); +} + + +void CGUIEditBox::calculateScrollPos() +{ + + if (!AutoScroll) + return; + + // calculate horizontal scroll position + s32 cursLine = getLineFromPos(CursorPos); + setTextRect(cursLine); + + // don't do horizontal scrolling when wordwrap is enabled. + if (!WordWrap) + { + // get cursor position + IGUIFont* font = OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (!OverrideFont) + font = skin->getFont(); + + core::stringw *txtLine = MultiLine ? &BrokenText[cursLine] : &Text; + s32 cPos = MultiLine ? CursorPos - BrokenTextPositions[cursLine] : CursorPos; + + s32 cStart = CurrentTextRect.UpperLeftCorner.X + HScrollPos + + font->getDimension(txtLine->subString(0, cPos).c_str()).Width; + + s32 cEnd = cStart + font->getDimension(L"_ ").Width; + + if (frameRect.LowerRightCorner.X < cEnd) + HScrollPos = cEnd - frameRect.LowerRightCorner.X; + else if (frameRect.UpperLeftCorner.X > cStart) + HScrollPos = cStart - frameRect.UpperLeftCorner.X; + else + HScrollPos = 0; + + // todo: adjust scrollbar + + } + + // vertical scroll position + if (frameRect.LowerRightCorner.Y < CurrentTextRect.LowerRightCorner.Y + VScrollPos) + VScrollPos = CurrentTextRect.LowerRightCorner.Y - frameRect.LowerRightCorner.Y + VScrollPos; + + else if (frameRect.UpperLeftCorner.Y > CurrentTextRect.UpperLeftCorner.Y + VScrollPos) + VScrollPos = CurrentTextRect.UpperLeftCorner.Y - frameRect.UpperLeftCorner.Y + VScrollPos; + else + VScrollPos = 0; + + // todo: adjust scrollbar +} + + +//! Writes attributes of the element. +void CGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + // IGUIEditBox::serializeAttributes(out,options); + + out->addBool ("OverrideColorEnabled",OverrideColorEnabled ); + out->addColor ("OverrideColor", OverrideColor); + // out->addFont("OverrideFont",OverrideFont); + out->addInt ("MaxChars", Max); + out->addBool ("WordWrap", WordWrap); + out->addBool ("MultiLine", MultiLine); + out->addBool ("AutoScroll", AutoScroll); + out->addBool ("PasswordBox", PasswordBox); + core::stringw ch = L" "; + ch[0] = PasswordChar; + out->addString("PasswordChar", ch.c_str()); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + + IGUIEditBox::serializeAttributes(out,options); +} + + +//! Reads attributes of the element +void CGUIEditBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIEditBox::deserializeAttributes(in,options); + + setOverrideColor(in->getAttributeAsColor("OverrideColor")); + enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled")); + setMax(in->getAttributeAsInt("MaxChars")); + setWordWrap(in->getAttributeAsBool("WordWrap")); + setMultiLine(in->getAttributeAsBool("MultiLine")); + setAutoScroll(in->getAttributeAsBool("AutoScroll")); + core::stringw ch = in->getAttributeAsStringW("PasswordChar"); + + if (!ch.size()) + setPasswordBox(in->getAttributeAsBool("PasswordBox")); + else + setPasswordBox(in->getAttributeAsBool("PasswordBox"), ch[0]); + + setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); + + // setOverrideFont(in->getAttributeAsFont("OverrideFont")); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIEditBox.h b/src/dep/src/irrlicht/CGUIEditBox.h new file mode 100644 index 0000000..d5135b0 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIEditBox.h @@ -0,0 +1,156 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_EDIT_BOX_H_INCLUDED__ +#define __C_GUI_EDIT_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEditBox.h" +#include "irrArray.h" +#include "IOSOperator.h" + +namespace irr +{ +namespace gui +{ + class CGUIEditBox : public IGUIEditBox + { + public: + + //! constructor + CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle); + + //! destructor + virtual ~CGUIEditBox(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Sets if the text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Turns the border on or off + virtual void setDrawBorder(bool border); + + //! Enables or disables word wrap for using the edit box as multiline text editor. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled() const; + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable); + + //! Checks if multi line editing is enabled + //! \return true if mult-line is enabled, false otherwise + virtual bool isMultiLineEnabled() const; + + //! Enables or disables automatic scrolling with cursor position + //! \param enable: If set to true, the text will move around with the cursor position + virtual void setAutoScroll(bool enable); + + //! Checks to see if automatic scrolling is enabled + //! \return true if automatic scrolling is enabled, false if not + virtual bool isAutoScrollEnabled() const; + + //! Gets the size area of the text in the edit box + //! \return Returns the size in pixels of the text + virtual core::dimension2di getTextDimension(); + + //! Sets text justification + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text); + + //! Sets the maximum amount of characters which may be entered in the box. + //! \param max: Maximum amount of characters. If 0, the character amount is + //! infinity. + virtual void setMax(u32 max); + + //! Returns maximum amount of characters, previously set by setMax(); + virtual u32 getMax() const; + + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*'); + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() const; + + //! Updates the absolute position, splits text if required + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + //! Breaks the single text line. + void breakText(); + //! sets the area of the given line + void setTextRect(s32 line); + //! returns the line number that the cursor is on + s32 getLineFromPos(s32 pos); + //! adds a letter to the edit box + void inputChar(wchar_t c); + //! calculates the current scroll position + void calculateScrollPos(); + + bool processKey(const SEvent& event); + bool processMouse(const SEvent& event); + s32 getCursorPos(s32 x, s32 y); + + bool MouseMarking; + bool Border; + bool OverrideColorEnabled; + s32 MarkBegin; + s32 MarkEnd; + + video::SColor OverrideColor; + gui::IGUIFont *OverrideFont, *LastBreakFont; + IOSOperator* Operator; + + u32 BlinkStartTime; + s32 CursorPos; + s32 HScrollPos, VScrollPos; // scroll position in characters + u32 Max; + + bool WordWrap, MultiLine, AutoScroll, PasswordBox; + wchar_t PasswordChar; + EGUI_ALIGNMENT HAlign, VAlign; + + core::array< core::stringw > BrokenText; + core::array< s32 > BrokenTextPositions; + + core::rect CurrentTextRect, frameRect; // temporary values + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ +#endif // __C_GUI_EDIT_BOX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIEnvironment.cpp b/src/dep/src/irrlicht/CGUIEnvironment.cpp new file mode 100644 index 0000000..7fa6287 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIEnvironment.cpp @@ -0,0 +1,1497 @@ + +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIEnvironment.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IVideoDriver.h" + +#include "CGUISkin.h" +#include "CGUIButton.h" +#include "CGUIWindow.h" +#include "CGUIScrollBar.h" +#include "CGUIFont.h" +#include "CGUISpriteBank.h" +#include "CGUIImage.h" +#include "CGUIMeshViewer.h" +#include "CGUICheckBox.h" +#include "CGUIListBox.h" +#include "CGUIFileOpenDialog.h" +#include "CGUIColorSelectDialog.h" +#include "CGUIStaticText.h" +#include "CGUIEditBox.h" +#include "CGUISpinBox.h" +#include "CGUIInOutFader.h" +#include "CGUIMessageBox.h" +#include "CGUIModalScreen.h" +#include "CGUITabControl.h" +#include "CGUIContextMenu.h" +#include "CGUIComboBox.h" +#include "CGUIMenu.h" +#include "CGUIToolBar.h" + +#include "CDefaultGUIElementFactory.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" + +#include "BuiltInFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +const wchar_t* IRR_XML_FORMAT_GUI_ENV = L"irr_gui"; +const wchar_t* IRR_XML_FORMAT_GUI_ELEMENT = L"element"; +const wchar_t* IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE = L"type"; + +//! constructor +CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op) +: IGUIElement(EGUIET_ELEMENT, 0, 0, 0, core::rect(core::position2d(0,0), driver ? driver->getScreenSize() : core::dimension2d(0,0))), + Driver(driver), Hovered(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0), + FileSystem(fs), UserReceiver(0), Operator(op) +{ + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + if (Operator) + Operator->grab(); + + #ifdef _DEBUG + IGUIEnvironment::setDebugName("CGUIEnvironment"); + #endif + + // gui factory + IGUIElementFactory* factory = new CDefaultGUIElementFactory(this); + registerGUIElementFactory(factory); + factory->drop(); + + loadBuiltInFont(); + + IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC ); + setSkin(skin); + skin->drop(); + + //set tooltip default + ToolTip.LastTime = 0; + ToolTip.LaunchTime = 1000; + ToolTip.Element = 0; + + // environment is root tab group + Environment = this; + setTabGroup(true); +} + + +//! destructor +CGUIEnvironment::~CGUIEnvironment() +{ + if (Hovered && Hovered != this) + { + Hovered->drop(); + Hovered = 0; + } + + if (Driver) + { + Driver->drop(); + Driver = 0; + } + + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + if (ToolTip.Element) + { + ToolTip.Element->drop(); + ToolTip.Element = 0; + } + + if (FileSystem) + { + FileSystem->drop(); + FileSystem = 0; + } + + if (Operator) + { + Operator->drop(); + Operator = 0; + } + + // drop skin + if (CurrentSkin) + { + CurrentSkin->drop(); + CurrentSkin = 0; + } + + // delete all fonts + u32 i; + + for (i=0; idrop(); + + // remove all factories + for (i=0; idrop(); +} + + +void CGUIEnvironment::loadBuiltInFont() +{ + const c8* filename = "#DefaultFont"; + io::IReadFile* file = io::createMemoryReadFile(BuiltInFontData, BuiltInFontDataSize, filename, false); + + CGUIFont* font = new CGUIFont(this, "#DefaultFont"); + if (!font->load(file)) + { + os::Printer::log("Error: Could not load built-in Font.", ELL_ERROR); + font->drop(); + file->drop(); + return; + } + + SFont f; + f.Filename = filename; + f.Font = font; + Fonts.push_back(f); + + file->drop(); +} + + +//! draws all gui elements +void CGUIEnvironment::drawAll() +{ + if (Driver) + { + core::dimension2d dim = Driver->getScreenSize(); + if (AbsoluteRect.LowerRightCorner.X != dim.Width || + AbsoluteRect.LowerRightCorner.Y != dim.Height) + { + // resize gui environment + DesiredRect.LowerRightCorner.X = Driver->getScreenSize().Width; + DesiredRect.LowerRightCorner.Y = Driver->getScreenSize().Height; + AbsoluteClippingRect = DesiredRect; + AbsoluteRect = DesiredRect; + updateAbsolutePosition(); + } + } + + // make sure tooltip is always on top + if (ToolTip.Element) + bringToFront(ToolTip.Element); + + draw(); + OnPostRender ( os::Timer::getTime () ); +} + + +//! sets the focus to an element +bool CGUIEnvironment::setFocus(IGUIElement* element) +{ + if (Focus == element) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // GUI Environment should not get the focus + if (element == this) + element = 0; + + // stop element from being deleted + if (element) + element->grab(); + + // focus may change or be removed in this call + IGUIElement *currentFocus = 0; + if (Focus) + { + currentFocus = Focus; + currentFocus->grab(); + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = Focus; + e.GUIEvent.Element = element; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST; + if (Focus->OnEvent(e)) + { + if (element) + element->drop(); + currentFocus->drop(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + currentFocus->drop(); + currentFocus = 0; + } + + if (element) + { + currentFocus = Focus; + if (currentFocus) + currentFocus->grab(); + + // send focused event + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = element; + e.GUIEvent.Element = Focus; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUSED; + if (element->OnEvent(e)) + { + if (element) + element->drop(); + if (currentFocus) + currentFocus->drop(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + } + + if (currentFocus) + currentFocus->drop(); + + if (Focus) + Focus->drop(); + + // element is the new focus so it doesn't have to be dropped + Focus = element; + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; +} + + +//! returns the element with the focus +IGUIElement* CGUIEnvironment::getFocus() const +{ + return Focus; +} + + +//! removes the focus from an element +bool CGUIEnvironment::removeFocus(IGUIElement* element) +{ + if (Focus && Focus==element) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = Focus; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST; + if (Focus->OnEvent(e)) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + } + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; +} + + +//! Returns if the element has focus +bool CGUIEnvironment::hasFocus(IGUIElement* element) const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (element == Focus); +} + + +//! returns the current video driver +video::IVideoDriver* CGUIEnvironment::getVideoDriver() const +{ + return Driver; +} + +//! returns the current file system +io::IFileSystem* CGUIEnvironment::getFileSystem() const +{ + return FileSystem; +} + +//! returns the current file system +IOSOperator* CGUIEnvironment::getOSOperator() const +{ + return Operator; +} + +//! clear all GUI elements +void CGUIEnvironment::clear() +{ + // Remove the focus + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + if (Hovered && Hovered != this) + { + Hovered->drop(); + Hovered = 0; + } + + // get the root's children in case the root changes in future + const core::list& children = getRootGUIElement()->getChildren(); + + while (!children.empty()) + (*children.getLast())->remove(); +} + + +//! called by ui if an event happened. +bool CGUIEnvironment::OnEvent(const SEvent& event) +{ + if (UserReceiver && (event.EventType != EET_MOUSE_INPUT_EVENT) && + (event.EventType != EET_GUI_EVENT || event.GUIEvent.Caller != this)) + { + return UserReceiver->OnEvent(event); + } + + return false; +} + + +// +void CGUIEnvironment::OnPostRender( u32 time ) +{ + // check tooltip + + // launch tooltip + if ( time - ToolTip.LastTime >= ToolTip.LaunchTime && + Hovered && Hovered != this && + ToolTip.Element == 0 && + Hovered != ToolTip.Element && + Hovered->getToolTipText().size() && + getSkin() && + getSkin()->getFont(EGDF_TOOLTIP) + ) + { + core::rect pos; + + pos.UpperLeftCorner = LastHoveredMousePos; + core::dimension2di dim = getSkin()->getFont(EGDF_TOOLTIP)->getDimension(Hovered->getToolTipText().c_str()); + dim.Width += getSkin()->getSize(EGDS_TEXT_DISTANCE_X)*2; + dim.Height += getSkin()->getSize(EGDS_TEXT_DISTANCE_Y)*2; + + pos.UpperLeftCorner.Y -= dim.Height+1; + pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + dim.Height-1; + pos.LowerRightCorner.X = pos.UpperLeftCorner.X + dim.Width; + + pos.constrainTo(getAbsolutePosition()); + + ToolTip.Element = addStaticText(Hovered->getToolTipText().c_str(), pos, true, true, this, -1, true); + ToolTip.Element->setOverrideColor(getSkin()->getColor(EGDC_TOOLTIP)); + ToolTip.Element->setBackgroundColor(getSkin()->getColor(EGDC_TOOLTIP_BACKGROUND)); + ToolTip.Element->setOverrideFont(getSkin()->getFont(EGDF_TOOLTIP)); + ToolTip.Element->setSubElement(true); + ToolTip.Element->grab(); + + s32 textHeight = ToolTip.Element->getTextHeight(); + pos = ToolTip.Element->getRelativePosition(); + pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + textHeight; + ToolTip.Element->setRelativePosition(pos); + + } + + IGUIElement::OnPostRender ( time ); +} + + +// +void CGUIEnvironment::updateHoveredElement(core::position2d mousePos) +{ + IGUIElement* lastHovered = Hovered; + LastHoveredMousePos = mousePos; + + Hovered = getElementFromPoint(mousePos); + + if (Hovered) + { + u32 now = os::Timer::getTime (); + + if (Hovered != this) + Hovered->grab(); + + if (Hovered != lastHovered) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + + if (lastHovered) + { + event.GUIEvent.Caller = lastHovered; + event.GUIEvent.EventType = EGET_ELEMENT_LEFT; + lastHovered->OnEvent(event); + } + + if ( ToolTip.Element ) + { + ToolTip.Element->remove(); + ToolTip.Element->drop(); + ToolTip.Element = 0; + ToolTip.LastTime += 500; + } + else + { + // boost tooltip generation for relaunch + if ( now - ToolTip.LastTime < ToolTip.LastTime ) + { + ToolTip.LastTime += 500; + } + else + { + ToolTip.LastTime = now; + } + } + + + event.GUIEvent.Caller = Hovered; + event.GUIEvent.EventType = EGET_ELEMENT_HOVERED; + Hovered->OnEvent(event); + } + } + + if (lastHovered && lastHovered != this) + lastHovered->drop(); +} + + +//! This sets a new event receiver for gui events. Usually you do not have to +//! use this method, it is used by the internal engine. +void CGUIEnvironment::setUserEventReceiver(IEventReceiver* evr) +{ + UserReceiver = evr; +} + + +//! posts an input event to the environment +bool CGUIEnvironment::postEventFromUser(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + // hey, why is the user sending gui events..? + break; + case EET_MOUSE_INPUT_EVENT: + + updateHoveredElement(core::position2d(event.MouseInput.X, event.MouseInput.Y)); + + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + if ( (Hovered && Hovered != Focus) || !Focus ) + { + setFocus(Hovered); + } + + // sending input to focus + if (Focus && Focus->OnEvent(event)) + return true; + + // focus could have died in last call + if (!Focus && Hovered) + return Hovered->OnEvent(event); + + break; + case EET_KEY_INPUT_EVENT: + { + // send focus changing event + if (event.EventType == EET_KEY_INPUT_EVENT && + event.KeyInput.PressedDown && + event.KeyInput.Key == KEY_TAB) + { + IGUIElement *next = getNextElement(event.KeyInput.Shift, event.KeyInput.Control); + if (next && next != Focus) + { + if (setFocus(next)) + return true; + } + } + if (Focus) + return Focus->OnEvent(event); + } + break; + default: + break; + } // end switch + + return false; +} + + +//! returns the current gui skin +IGUISkin* CGUIEnvironment::getSkin() const +{ + return CurrentSkin; +} + + +//! Sets a new GUI Skin +void CGUIEnvironment::setSkin(IGUISkin* skin) +{ + if (CurrentSkin) + CurrentSkin->drop(); + + CurrentSkin = skin; + + if (CurrentSkin) + CurrentSkin->grab(); +} + + +//! Creates a new GUI Skin based on a template. +/** \return Returns a pointer to the created skin. +If you no longer need the skin, you should call IGUISkin::drop(). +See IReferenceCounted::drop() for more information. */ +IGUISkin* CGUIEnvironment::createSkin(EGUI_SKIN_TYPE type) +{ + IGUISkin* skin = new CGUISkin(type, Driver); + + IGUIFont* builtinfont = getBuiltInFont(); + IGUIFontBitmap* bitfont = 0; + if (builtinfont && builtinfont->getType() == EGFT_BITMAP) + bitfont = (IGUIFontBitmap*)builtinfont; + + IGUISpriteBank* bank = 0; + skin->setFont(builtinfont); + + if (bitfont) + bank = bitfont->getSpriteBank(); + + skin->setSpriteBank(bank); + + return skin; +} + + +//! Returns the default element factory which can create all built in elements +IGUIElementFactory* CGUIEnvironment::getDefaultGUIElementFactory() const +{ + return getGUIElementFactory(0); +} + + +//! Adds an element factory to the gui environment. +/** Use this to extend the gui environment with new element types which it should be +able to create automaticly, for example when loading data from xml files. */ +void CGUIEnvironment::registerGUIElementFactory(IGUIElementFactory* factoryToAdd) +{ + if (factoryToAdd) + { + factoryToAdd->grab(); + GUIElementFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node factories. +u32 CGUIEnvironment::getRegisteredGUIElementFactoryCount() const +{ + return GUIElementFactoryList.size(); +} + + +//! Returns a scene node factory by index +IGUIElementFactory* CGUIEnvironment::getGUIElementFactory(u32 index) const +{ + if (index < GUIElementFactoryList.size()) + return GUIElementFactoryList[index]; + else + return 0; +} + + +//! adds a GUI Element using its name +IGUIElement* CGUIEnvironment::addGUIElement(const c8* elementName, IGUIElement* parent) +{ + IGUIElement* node=0; + + if (!parent) + parent = this; + + for (u32 i=0; iaddGUIElement(elementName, parent); + + return node; +} + + +//! Saves the current gui into a file. +//! \param filename: Name of the file . +bool CGUIEnvironment::saveGUI(const c8* filename, IGUIElement* start) +{ + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if (!file) + return false; + + bool ret = saveGUI(file, start); + file->drop(); + return ret; +} + + +//! Saves the current gui into a file. +bool CGUIEnvironment::saveGUI(io::IWriteFile* file, IGUIElement* start) +{ + if (!file) + return false; + + io::IXMLWriter* writer = FileSystem->createXMLWriter(file); + if (!writer) + return false; + + writer->writeXMLHeader(); + writeGUIElement(writer, start ? start : this); + writer->drop(); + + return true; +} + + +//! Loads the gui. Note that the current gui is not cleared before. +//! \param filename: Name of the file. +bool CGUIEnvironment::loadGUI(const c8* filename, IGUIElement* parent) +{ + io::IReadFile* read = FileSystem->createAndOpenFile(filename); + if (!read) + { + os::Printer::log("Unable to open gui file", filename, ELL_ERROR); + return false; + } + + bool ret = loadGUI(read, parent); + read->drop(); + + return ret; +} + + +//! Loads the gui. Note that the current gui is not cleared before. +bool CGUIEnvironment::loadGUI(io::IReadFile* file, IGUIElement* parent) +{ + if (!file) + { + os::Printer::log("Unable to open GUI file", ELL_ERROR); + return false; + } + + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + { + os::Printer::log("GUI is not a valid XML file", file->getFileName(), ELL_ERROR); + return false; + } + + // read file + while(reader->read()) + { + readGUIElement(reader, parent); + } + + // finish up + + reader->drop(); + return true; +} + + +//! reads an element +void CGUIEnvironment::readGUIElement(io::IXMLReader* reader, IGUIElement* parent) +{ + if (!reader) + return; + + gui::IGUIElement* node = 0; + + io::EXML_NODE nodeType = reader->getNodeType(); + + if (nodeType == io::EXN_NONE || nodeType == io::EXN_UNKNOWN || nodeType == io::EXN_ELEMENT_END) + return; + + if (!parent && !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + node = this; // root + } + else if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName())) + { + // find node type and create it + core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE); + + node = addGUIElement(attrName.c_str(), parent); + + if (!node) + os::Printer::log("Could not create GUI element of unknown type", attrName.c_str()); + } + + // read attributes + + while(reader->read()) + { + bool endreached = false; + + switch (reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + endreached = true; + } + break; + case io::EXN_ELEMENT: + if (!wcscmp(L"attributes", reader->getNodeName())) + { + // read attributes + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader, true); + + if (node) + node->deserializeAttributes(attr); + + attr->drop(); + } + else + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + readGUIElement(reader, node); + } + else + { + os::Printer::log("Found unknown element in irrlicht GUI file", + core::stringc(reader->getNodeName()).c_str()); + } + + break; + default: + break; + } + + if (endreached) + break; + } +} + + +//! writes an element +void CGUIEnvironment::writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) +{ + if (!writer || !node ) + return; + + const wchar_t* name = 0; + + // write properties + + io::IAttributes* attr = FileSystem->createEmptyAttributes(); + node->serializeAttributes(attr); + + // all gui elements must have at least one attribute + // if they have nothing then we ignore them. + if (attr->getAttributeCount() != 0) + { + if (node == this) + { + name = IRR_XML_FORMAT_GUI_ENV; + writer->writeElement(name, false); + } + else + { + name = IRR_XML_FORMAT_GUI_ELEMENT; + writer->writeElement(name, false, IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE, + core::stringw(node->getTypeName()).c_str()); + } + + writer->writeLineBreak(); + writer->writeLineBreak(); + + attr->write(writer); + writer->writeLineBreak(); + } + + // write children + + core::list::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); ++it) + { + if (!(*it)->isSubElement()) + writeGUIElement(writer, (*it)); + } + + // write closing brace if required + if (attr->getAttributeCount() != 0) + { + writer->writeClosingTag(name); + writer->writeLineBreak(); + writer->writeLineBreak(); + } + + attr->drop(); +} + + +//! Writes attributes of the environment +void CGUIEnvironment::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUISkin* skin = getSkin(); + + if (skin) + { + out->addEnum("Skin", getSkin()->getType(), GUISkinTypeNames); + skin->serializeAttributes(out, options); + } +} + + +//! Reads attributes of the environment +void CGUIEnvironment::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + if (in->existsAttribute("Skin")) + { + IGUISkin *skin = getSkin(); + + EGUI_SKIN_TYPE t = (EGUI_SKIN_TYPE) in->getAttributeAsEnumeration("Skin",GUISkinTypeNames); + if ( !skin || t != skin->getType()) + { + skin = createSkin(t); + setSkin(skin); + skin->drop(); + } + + skin = getSkin(); + + if (skin) + { + skin->deserializeAttributes(in, options); + } + + } + + RelativeRect = AbsoluteRect = + core::rect(core::position2d(0,0), + Driver ? Driver->getScreenSize() : core::dimension2d(0,0)); +} + + +//! adds a button. The returned pointer must not be dropped. +IGUIButton* CGUIEnvironment::addButton(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text, const wchar_t *tooltiptext) +{ + IGUIButton* button = new CGUIButton(this, parent ? parent : this, id, rectangle); + if (text) + button->setText(text); + + if ( tooltiptext ) + button->setToolTipText ( tooltiptext ); + + button->drop(); + return button; +} + + +//! adds a window. The returned pointer must not be dropped. +IGUIWindow* CGUIEnvironment::addWindow(const core::rect& rectangle, bool modal, + const wchar_t* text, IGUIElement* parent, s32 id) +{ + parent = parent ? parent : this; + + if (modal) + { + parent = new CGUIModalScreen(this, parent, -1); + parent->drop(); + } + + IGUIWindow* win = new CGUIWindow(this, parent, id, rectangle); + if (text) + win->setText(text); + win->drop(); + + return win; +} + + +//! adds a modal screen. The returned pointer must not be dropped. +IGUIElement* CGUIEnvironment::addModalScreen(IGUIElement* parent) +{ + parent = parent ? parent : this; + + IGUIElement *win = new CGUIModalScreen(this, parent, -1); + win->drop(); + + return win; +} + + +//! Adds a message box. +IGUIWindow* CGUIEnvironment::addMessageBox(const wchar_t* caption, const wchar_t* text, + bool modal, s32 flag, IGUIElement* parent, s32 id) +{ + if (!CurrentSkin) + return 0; + + parent = parent ? parent : this; + + core::rect rect; + core::dimension2d screenDim, msgBoxDim; + + screenDim.Width = parent->getAbsolutePosition().getWidth(); + screenDim.Height = parent->getAbsolutePosition().getHeight(); + msgBoxDim.Width = CurrentSkin->getSize(gui::EGDS_MESSAGE_BOX_WIDTH); + msgBoxDim.Height = CurrentSkin->getSize(gui::EGDS_MESSAGE_BOX_HEIGHT); + + rect.UpperLeftCorner.X = (screenDim.Width - msgBoxDim.Width) / 2; + rect.UpperLeftCorner.Y = (screenDim.Height - msgBoxDim.Height) / 2; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + msgBoxDim.Width; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + msgBoxDim.Height; + + if (modal) + { + parent = new CGUIModalScreen(this, parent, -1); + parent->drop(); + } + + IGUIWindow* win = new CGUIMessageBox(this, caption, text, flag, + parent, id, rect); + + win->drop(); + return win; +} + + +//! adds a scrollbar. The returned pointer must not be dropped. +IGUIScrollBar* CGUIEnvironment::addScrollBar(bool horizontal, const core::rect& rectangle, IGUIElement* parent, s32 id) +{ + IGUIScrollBar* bar = new CGUIScrollBar(horizontal, this, parent ? parent : this, id, rectangle); + bar->drop(); + return bar; +} + + +//! Adds an image element. +IGUIImage* CGUIEnvironment::addImage(video::ITexture* image, core::position2d pos, + bool useAlphaChannel, IGUIElement* parent, s32 id, const wchar_t* text) +{ + core::dimension2d sz(0,0); + if (image) + sz = image->getOriginalSize(); + + IGUIImage* img = new CGUIImage(this, parent ? parent : this, + id, core::rect(pos, sz)); + + if (text) + img->setText(text); + + if (useAlphaChannel) + img->setUseAlphaChannel(true); + + if (image) + img->setImage(image); + + img->drop(); + return img; +} + + +//! adds an image. The returned pointer must not be dropped. +IGUIImage* CGUIEnvironment::addImage(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text) +{ + IGUIImage* img = new CGUIImage(this, parent ? parent : this, + id, rectangle); + + if (text) + img->setText(text); + + img->drop(); + return img; +} + + +//! adds an mesh viewer. The returned pointer must not be dropped. +IGUIMeshViewer* CGUIEnvironment::addMeshViewer(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text) +{ + IGUIMeshViewer* v = new CGUIMeshViewer(this, parent ? parent : this, + id, rectangle); + + if (text) + v->setText(text); + + v->drop(); + return v; +} + + +//! adds a checkbox +IGUICheckBox* CGUIEnvironment::addCheckBox(bool checked, const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text) +{ + IGUICheckBox* b = new CGUICheckBox(checked, this, + parent ? parent : this , id , rectangle); + + if (text) + b->setText(text); + + b->drop(); + return b; +} + + +//! adds a list box +IGUIListBox* CGUIEnvironment::addListBox(const core::rect& rectangle, + IGUIElement* parent, s32 id, + bool drawBackground) +{ + IGUIListBox* b = new CGUIListBox(this, parent ? parent : this, id, rectangle, + true, drawBackground, false); + + if (CurrentSkin && CurrentSkin->getSpriteBank()) + { + b->setSpriteBank(CurrentSkin->getSpriteBank()); + } + else if (getBuiltInFont() && getBuiltInFont()->getType() == EGFT_BITMAP) + { + b->setSpriteBank( ((IGUIFontBitmap*)getBuiltInFont())->getSpriteBank()); + } + + b->drop(); + return b; +} + + +//! adds a file open dialog. The returned pointer must not be dropped. +IGUIFileOpenDialog* CGUIEnvironment::addFileOpenDialog(const wchar_t* title, + bool modal, + IGUIElement* parent, s32 id) +{ + parent = parent ? parent : this; + + if (modal) + { + parent = new CGUIModalScreen(this, parent, -1); + parent->drop(); + } + + IGUIFileOpenDialog* d = new CGUIFileOpenDialog(title, this, parent, id); + + d->drop(); + return d; +} + + +//! adds a color select dialog. The returned pointer must not be dropped. +IGUIColorSelectDialog* CGUIEnvironment::addColorSelectDialog(const wchar_t* title, + bool modal, + IGUIElement* parent, s32 id) +{ + parent = parent ? parent : this; + + if (modal) + { + parent = new CGUIModalScreen(this, parent, -1); + parent->drop(); + } + + IGUIColorSelectDialog* d = new CGUIColorSelectDialog( title, + this, parent, id); + + d->drop(); + return d; +} + + +//! adds a static text. The returned pointer must not be dropped. +IGUIStaticText* CGUIEnvironment::addStaticText(const wchar_t* text, + const core::rect& rectangle, + bool border, bool wordWrap, + IGUIElement* parent, s32 id, + bool background) +{ + IGUIStaticText* d = new CGUIStaticText(text, border, this, + parent ? parent : this, id, rectangle, background); + + d->setWordWrap(wordWrap); + d->drop(); + + return d; +} + + +//! Adds an edit box. The returned pointer must not be dropped. +IGUIEditBox* CGUIEnvironment::addEditBox(const wchar_t* text, + const core::rect& rectangle, + bool border, IGUIElement* parent, + s32 id) +{ + IGUIEditBox* d = new CGUIEditBox(text, border, this, + parent ? parent : this, id, rectangle); + + d->drop(); + return d; +} + + +//! Adds a spin box to the environment +IGUISpinBox* CGUIEnvironment::addSpinBox(const wchar_t* text, + const core::rect &rectangle, + IGUIElement* parent, s32 id) +{ + IGUISpinBox* d = new CGUISpinBox(text, this, parent ? parent : this, id, rectangle); + + d->drop(); + return d; +} + + +//! Adds a tab control to the environment. +IGUITabControl* CGUIEnvironment::addTabControl(const core::rect& rectangle, + IGUIElement* parent, bool fillbackground, bool border, s32 id) +{ + IGUITabControl* t = new CGUITabControl(this, parent ? parent : this, + rectangle, fillbackground, border, id); + t->drop(); + return t; +} + + +//! Adds tab to the environment. +IGUITab* CGUIEnvironment::addTab(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUITab* t = new CGUITab(-1, this, parent ? parent : this, + rectangle, id); + t->drop(); + return t; +} + + +//! Adds a context menu to the environment. +IGUIContextMenu* CGUIEnvironment::addContextMenu(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUIContextMenu* c = new CGUIContextMenu(this, + parent ? parent : this, id, rectangle, true); + c->drop(); + return c; +} + + +//! Adds a menu to the environment. +IGUIContextMenu* CGUIEnvironment::addMenu(IGUIElement* parent, s32 id) +{ + if (!parent) + parent = this; + + IGUIContextMenu* c = new CGUIMenu(this, + parent, id, core::rect(0,0, + parent->getAbsolutePosition().getWidth(), + parent->getAbsolutePosition().getHeight())); + + c->drop(); + return c; +} + + +//! Adds a toolbar to the environment. It is like a menu is always placed on top +//! in its parent, and contains buttons. +IGUIToolBar* CGUIEnvironment::addToolBar(IGUIElement* parent, s32 id) +{ + if (!parent) + parent = this; + + IGUIToolBar* b = new CGUIToolBar(this, parent, id, core::rect(0,0,10,10)); + b->drop(); + return b; +} + + +//! Adds an element for fading in or out. +IGUIInOutFader* CGUIEnvironment::addInOutFader(const core::rect* rectangle, IGUIElement* parent, s32 id) +{ + core::rect rect; + + if (rectangle) + rect = *rectangle; + else + if (Driver) + rect = core::rect(core::position2d(0,0), Driver->getScreenSize()); + + if (!parent) + parent = this; + + IGUIInOutFader* fader = new CGUIInOutFader(this, parent, id, rect); + fader->drop(); + return fader; +} + + +//! Adds a combo box to the environment. +IGUIComboBox* CGUIEnvironment::addComboBox(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUIComboBox* t = new CGUIComboBox(this, parent ? parent : this, + id, rectangle); + t->drop(); + return t; +} + + +//! returns the font +IGUIFont* CGUIEnvironment::getFont(const c8* filename) +{ + // search existing font + + SFont f; + IGUIFont* ifont=0; + if (!filename) + f.Filename = ""; + else + f.Filename = filename; + + f.Filename.make_lower(); + + s32 index = Fonts.binary_search(f); + if (index != -1) + return Fonts[index].Font; + + // font doesn't exist, attempt to load it + + // does the file exist? + + if (!FileSystem->existFile(filename)) + { + os::Printer::log("Could not load font because the file does not exist", f.Filename.c_str(), ELL_ERROR); + return 0; + } + + io::IXMLReader *xml = FileSystem->createXMLReader(filename); + if (xml) + { + // this is an XML font, but we need to know what type + EGUI_FONT_TYPE t = EGFT_CUSTOM; + + bool found=false; + while(xml->read() && !found) + { + if (xml->getNodeType() == io::EXN_ELEMENT) + { + if (core::stringw(L"font") == xml->getNodeName()) + { + if (core::stringw(L"vector") == xml->getAttributeValue(L"type")) + { + t = EGFT_VECTOR; + found=true; + } + else if (core::stringw(L"bitmap") == xml->getAttributeValue(L"type")) + { + t = EGFT_BITMAP; + found=true; + } + else found=true; + } + } + } + + if (t==EGFT_BITMAP) + { + CGUIFont* font = new CGUIFont(this, filename); + ifont = (IGUIFont*)font; + // change working directory, for loading textures + core::stringc workingDir = FileSystem->getWorkingDirectory(); + FileSystem->changeWorkingDirectoryTo(FileSystem->getFileDir(f.Filename).c_str()); + + // load the font + if (!font->load(xml)) + { + font->drop(); + font = 0; + ifont = 0; + } + // change working dir back again + FileSystem->changeWorkingDirectoryTo( workingDir.c_str()); + } + else if (t==EGFT_VECTOR) + { + // todo: vector fonts + os::Printer::log("Unable to load font, XML vector fonts are not supported yet", f.Filename.c_str(), ELL_ERROR); + + //CGUIFontVector* font = new CGUIFontVector(Driver); + //ifont = (IGUIFont*)font; + //if (!font->load(xml)) + } + xml->drop(); + } + + + if (!ifont) + { + + CGUIFont* font = new CGUIFont(this, f.Filename.c_str()); + ifont = (IGUIFont*)font; + if (!font->load(f.Filename.c_str())) + { + font->drop(); + return 0; + } + } + + // add to fonts. + + f.Font = ifont; + Fonts.push_back(f); + + return ifont; +} + + +IGUISpriteBank* CGUIEnvironment::getSpriteBank(const c8* filename) +{ + // search for the file name + + SSpriteBank b; + if (!filename) + b.Filename = ""; + else + b.Filename = filename; + + b.Filename.make_lower(); + + s32 index = Banks.binary_search(b); + if (index != -1) + return Banks[index].Bank; + + // we don't have this sprite bank, we should load it + + if (!FileSystem->existFile(b.Filename.c_str())) + { + os::Printer::log("Could not load sprite bank because the file does not exist", filename, ELL_ERROR); + return 0; + } + + // todo: load it! + + return 0; +} + + +IGUISpriteBank* CGUIEnvironment::addEmptySpriteBank(const c8 *name) +{ + // no duplicate names allowed + + SSpriteBank b; + if (!name) + b.Filename = ""; + else + b.Filename = name; + + s32 index = Banks.binary_search(b); + if (index != -1) + return 0; + + + // create a new sprite bank + + b.Bank = new CGUISpriteBank(this); + + Banks.push_back(b); + + return b.Bank; +} + + +//! returns default font +IGUIFont* CGUIEnvironment::getBuiltInFont() const +{ + if (Fonts.empty()) + return 0; + + return Fonts[0].Font; +} + + + +//! Returns the root gui element. +IGUIElement* CGUIEnvironment::getRootGUIElement() +{ + return this; +} + + +//! Returns the next element in the tab group starting at the focused element +IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group) +{ + // start the search at the root of the current tab group + IGUIElement *startPos = Focus ? Focus->getTabGroup() : 0; + s32 startOrder = -1; + + // if we're searching for a group + if (group && startPos) + { + startOrder = startPos->getTabOrder(); + } + else + if (!group && Focus && !Focus->isTabGroup()) + { + startOrder = Focus->getTabOrder(); + if (startOrder == -1) + { + // this element is not part of the tab cycle, + // but its parent might be... + IGUIElement *el = Focus; + while (el && el->getParent() && startOrder == -1) + { + el = el->getParent(); + startOrder = el->getTabOrder(); + } + + } + } + + if (group || !startPos) + startPos = this; // start at the root + + // find the element + IGUIElement *closest = 0; + IGUIElement *first = 0; + startPos->getNextElement(startOrder, reverse, group, first, closest); + + if (closest) + return closest; // we found an element + else if (first) + return first; // go to the end or the start + else if (group) + return this; // no group found? root group + else + return 0; +} + + +//! creates an GUI Environment +IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs, + video::IVideoDriver* Driver, + IOSOperator* op) +{ + return new CGUIEnvironment(fs, Driver, op); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIEnvironment.h b/src/dep/src/irrlicht/CGUIEnvironment.h new file mode 100644 index 0000000..aa43a07 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIEnvironment.h @@ -0,0 +1,294 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_ENVIRNMENT_H_INCLUDED__ +#define __C_GUI_ENVIRNMENT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IGUIElement.h" +#include "irrArray.h" +#include "IFileSystem.h" +#include "IOSOperator.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; +} +namespace gui +{ + +class CGUIEnvironment : public IGUIEnvironment, public IGUIElement +{ +public: + + //! constructor + CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op); + + //! destructor + virtual ~CGUIEnvironment(); + + //! draws all gui elements + virtual void drawAll(); + + //! returns the current video driver + virtual video::IVideoDriver* getVideoDriver() const; + + //! returns pointer to the filesystem + virtual io::IFileSystem* getFileSystem() const; + + //! returns a pointer to the OS operator + virtual IOSOperator* getOSOperator() const; + + //! posts an input event to the environment + virtual bool postEventFromUser(const SEvent& event); + + //! This sets a new event receiver for gui events. Usually you do not have to + //! use this method, it is used by the internal engine. + virtual void setUserEventReceiver(IEventReceiver* evr); + + //! removes all elements from the environment + virtual void clear(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! returns the current gui skin + virtual IGUISkin* getSkin() const; + + //! Sets a new GUI Skin + virtual void setSkin(IGUISkin* skin); + + //! Creates a new GUI Skin based on a template. + /** \return Returns a pointer to the created skin. + If you no longer need the skin, you should call IGUISkin::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IGUISkin* createSkin(EGUI_SKIN_TYPE type); + + //! returns the font + virtual IGUIFont* getFont(const c8* filename); + + //! returns the sprite bank + virtual IGUISpriteBank* getSpriteBank(const c8* filename); + + //! returns the sprite bank + virtual IGUISpriteBank* addEmptySpriteBank(const c8* name); + + //! adds an button. The returned pointer must not be dropped. + virtual IGUIButton* addButton(const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext = 0); + + //! adds a window. The returned pointer must not be dropped. + virtual IGUIWindow* addWindow(const core::rect& rectangle, bool modal = false, + const wchar_t* text=0, IGUIElement* parent=0, s32 id=-1); + + //! adds a modal screen. The returned pointer must not be dropped. + virtual IGUIElement* addModalScreen(IGUIElement* parent); + + //! Adds a message box. + virtual IGUIWindow* addMessageBox(const wchar_t* caption, const wchar_t* text=0, + bool modal = true, s32 flag = EMBF_OK, IGUIElement* parent=0, s32 id=-1); + + //! adds a scrollbar. The returned pointer must not be dropped. + virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1); + + //! Adds an image element. + virtual IGUIImage* addImage(video::ITexture* image, core::position2d pos, + bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! adds an image. The returned pointer must not be dropped. + virtual IGUIImage* addImage(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! adds a checkbox + virtual IGUICheckBox* addCheckBox(bool checked, const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! adds a list box + virtual IGUIListBox* addListBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false); + + //! adds an mesh viewer. The returned pointer must not be dropped. + virtual IGUIMeshViewer* addMeshViewer(const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! Adds a file open dialog. + virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title = 0, bool modal=true, IGUIElement* parent=0, s32 id=-1); + + //! Adds a color select dialog. + virtual IGUIColorSelectDialog* addColorSelectDialog(const wchar_t* title = 0, bool modal=true, IGUIElement* parent=0, s32 id=-1); + + //! adds a static text. The returned pointer must not be dropped. + virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect& rectangle, + bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, bool drawBackground = false); + + //! Adds an edit box. The returned pointer must not be dropped. + virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect& rectangle, + bool border=false, IGUIElement* parent=0, s32 id=-1); + + //! Adds a spin box to the environment + virtual IGUISpinBox* addSpinBox(const wchar_t* text, const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a tab control to the environment. + virtual IGUITabControl* addTabControl(const core::rect& rectangle, + IGUIElement* parent=0, bool fillbackground=false, bool border=true, s32 id=-1); + + //! Adds tab to the environment. + virtual IGUITab* addTab(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a context menu to the environment. + virtual IGUIContextMenu* addContextMenu(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a menu to the environment. + virtual IGUIContextMenu* addMenu(IGUIElement* parent=0, s32 id=-1); + + //! Adds a toolbar to the environment. It is like a menu is always placed on top + //! in its parent, and contains buttons. + virtual IGUIToolBar* addToolBar(IGUIElement* parent=0, s32 id=-1); + + //! Adds a combo box to the environment. + virtual IGUIComboBox* addComboBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! sets the focus to an element + virtual bool setFocus(IGUIElement* element); + + //! removes the focus from an element + virtual bool removeFocus(IGUIElement* element); + + //! Returns if the element has focus + virtual bool hasFocus(IGUIElement* element) const; + + //! Returns the element with the focus + virtual IGUIElement* getFocus() const; + + //! returns default font + virtual IGUIFont* getBuiltInFont() const; + + //! Adds an element for fading in or out. + virtual IGUIInOutFader* addInOutFader(const core::rect* rectangle=0, IGUIElement* parent=0, s32 id=-1); + + //! Returns the root gui element. + virtual IGUIElement* getRootGUIElement(); + + virtual void OnPostRender( u32 time ); + + //! Returns the default element factory which can create all built in elements + virtual IGUIElementFactory* getDefaultGUIElementFactory() const; + + //! Adds an element factory to the gui environment. + /** Use this to extend the gui environment with new element types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerGUIElementFactory(IGUIElementFactory* factoryToAdd); + + //! Returns amount of registered scene node factories. + virtual u32 getRegisteredGUIElementFactoryCount() const; + + //! Returns a scene node factory by index + virtual IGUIElementFactory* getGUIElementFactory(u32 index) const; + + //! Adds a GUI Element by its name + virtual IGUIElement* addGUIElement(const c8* elementName, IGUIElement* parent=0); + + //! Saves the current gui into a file. + /** \param filename: Name of the file. + \param start: The element to start saving from. + if not specified, the root element will be used */ + virtual bool saveGUI(const c8* filename, IGUIElement* start=0); + + //! Saves the current gui into a file. + /** \param file: The file to save the GUI to. + \param start: The element to start saving from. + if not specified, the root element will be used */ + virtual bool saveGUI(io::IWriteFile* file, IGUIElement* start=0); + + //! Loads the gui. Note that the current gui is not cleared before. + /** \param filename: Name of the file. + \param parent: The parent of all loaded GUI elements, + if not specified, the root element will be used */ + virtual bool loadGUI(const c8* filename, IGUIElement* parent=0); + + //! Loads the gui. Note that the current gui is not cleared before. + /** \param file: IReadFile to load the GUI from + \param parent: The parent of all loaded GUI elements, + if not specified, the root element will be used */ + virtual bool loadGUI(io::IReadFile* file, IGUIElement* parent=0); + + //! Writes attributes of the environment + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the environment. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! writes an element + virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node); + + //! reads an element + virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* parent); + + +private: + + IGUIElement* getNextElement(bool reverse=false, bool group=false); + + void updateHoveredElement(core::position2d mousePos); + + void loadBuiltInFont(); + + struct SFont + { + core::stringc Filename; + IGUIFont* Font; + + bool operator < (const SFont& other) const + { + return (Filename < other.Filename); + } + }; + + struct SSpriteBank + { + core::stringc Filename; + IGUISpriteBank* Bank; + + bool operator < (const SSpriteBank& other) const + { + return (Filename < other.Filename); + } + }; + + struct SToolTip + { + u32 LastTime; + u32 LaunchTime; + IGUIStaticText* Element; + }; + + SToolTip ToolTip; + + core::array GUIElementFactoryList; + + core::array Fonts; + core::array Banks; + video::IVideoDriver* Driver; + IGUIElement* Hovered; + IGUIElement* Focus; + core::position2d LastHoveredMousePos; + IGUISkin* CurrentSkin; + io::IFileSystem* FileSystem; + IEventReceiver* UserReceiver; + IOSOperator* Operator; +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_ENVIRNMENT_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIFileOpenDialog.cpp b/src/dep/src/irrlicht/CGUIFileOpenDialog.cpp new file mode 100644 index 0000000..d7dd05a --- /dev/null +++ b/src/dep/src/irrlicht/CGUIFileOpenDialog.cpp @@ -0,0 +1,329 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIFileOpenDialog.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIStaticText.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "IFileList.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +const s32 FOD_WIDTH = 350; +const s32 FOD_HEIGHT = 250; + + +//! constructor +CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title, + IGUIEnvironment* environment, IGUIElement* parent, s32 id) +: IGUIFileOpenDialog(environment, parent, id, + core::rect((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2, + (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2, + (parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH, + (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)), + Dragging(false), FileNameText(0), FileList(0) +{ + #ifdef _DEBUG + IGUIElement::setDebugName("CGUIFileOpenDialog"); + #endif + + Text = title; + + IGUISkin* skin = Environment->getSkin(); + IGUISpriteBank* sprites = 0; + video::SColor color(255,255,255,255); + if (skin) + { + sprites = skin->getSpriteBank(); + color = skin->getColor(EGDC_WINDOW_SYMBOL); + } + + s32 buttonw = environment->getSkin()->getSize(EGDS_WINDOW_BUTTON_WIDTH); + s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close"); + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + if (sprites) + { + CloseButton->setSpriteBank(sprites); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color); + } + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CloseButton->grab(); + + OKButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK"); + OKButton->setSubElement(true); + OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + OKButton->grab(); + + CancelButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel"); + CancelButton->setSubElement(true); + CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CancelButton->grab(); + + FileBox = Environment->addListBox(core::rect(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true); + FileBox->setSubElement(true); + FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + FileBox->grab(); + + FileNameText = Environment->addStaticText(0, core::rect(10, 30, RelativeRect.getWidth()-90, 50), true, false, this); + FileNameText->setSubElement(true); + FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + FileNameText->grab(); + + FileSystem = Environment->getFileSystem(); + + if (FileSystem) + FileSystem->grab(); + + setTabGroup(true); + + fillListBox(); +} + + +//! destructor +CGUIFileOpenDialog::~CGUIFileOpenDialog() +{ + if (CloseButton) + CloseButton->drop(); + + if (OKButton) + OKButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + if (FileBox) + FileBox->drop(); + + if (FileNameText) + FileNameText->drop(); + + if (FileSystem) + FileSystem->drop(); + + if (FileList) + FileList->drop(); +} + + +//! returns the filename of the selected file. Returns NULL, if no file was selected. +const wchar_t* CGUIFileOpenDialog::getFileName() const +{ + return FileName.c_str(); +} + + +//! called if an event happened. +bool CGUIFileOpenDialog::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + Dragging = false; + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == CloseButton || + event.GUIEvent.Caller == CancelButton) + { + sendCancelEvent(); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == OKButton && FileName != L"") + { + sendSelectedEvent(); + remove(); + return true; + } + break; + + case EGET_LISTBOX_CHANGED: + { + s32 selected = FileBox->getSelected(); + if (FileList && FileSystem) + { + if (FileList->isDirectory(selected)) + FileName = L""; + else + FileName = FileList->getFullFileName(selected); + } + } + break; + + case EGET_LISTBOX_SELECTED_AGAIN: + { + const s32 selected = FileBox->getSelected(); + if (FileList && FileSystem) + { + if (FileList->isDirectory(selected)) + { + FileSystem->changeWorkingDirectoryTo(FileList->getFileName(selected)); + fillListBox(); + FileName = L""; + } + else + { + FileName = FileList->getFullFileName(selected); + return true; + } + } + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + return FileBox->OnEvent(event); + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = true; + Environment->setFocus(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + return true; + case EMIE_MOUSE_MOVED: + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent) + if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) + + return true; + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + break; + default: + break; + } + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void CGUIFileOpenDialog::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + core::rect rect = AbsoluteRect; + + rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), + rect, &AbsoluteClippingRect); + + if (Text.size()) + { + rect.UpperLeftCorner.X += 2; + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + font->draw(Text.c_str(), rect, + skin->getColor(EGDC_ACTIVE_CAPTION), + false, true, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! fills the listbox with files. +void CGUIFileOpenDialog::fillListBox() +{ + IGUISkin *skin = Environment->getSkin(); + + if (!FileSystem || !FileBox || !skin) + return; + + if (FileList) + FileList->drop(); + + FileBox->clear(); + + FileList = FileSystem->createFileList(); + core::stringw s; + + for (u32 i=0; igetFileCount(); ++i) + { + s = FileList->getFileName(i); + FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE)); + } + + if (FileNameText) + { + s = FileSystem->getWorkingDirectory(); + FileNameText->setText(s.c_str()); + } +} + + +//! sends the event that the file has been selected. +void CGUIFileOpenDialog::sendSelectedEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_SELECTED; + Parent->OnEvent(event); +} + + +//! sends the event that the file choose process has been canceld +void CGUIFileOpenDialog::sendCancelEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED; + Parent->OnEvent(event); +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIFileOpenDialog.h b/src/dep/src/irrlicht/CGUIFileOpenDialog.h new file mode 100644 index 0000000..c33f3dc --- /dev/null +++ b/src/dep/src/irrlicht/CGUIFileOpenDialog.h @@ -0,0 +1,72 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ +#define __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFileOpenDialog.h" +#include "IGUIButton.h" +#include "IGUIListBox.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace gui +{ + + class CGUIFileOpenDialog : public IGUIFileOpenDialog + { + public: + + //! constructor + CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* environment, IGUIElement* parent, s32 id); + + //! destructor + virtual ~CGUIFileOpenDialog(); + + //! returns the filename of the selected file. Returns NULL, if no file was selected. + virtual const wchar_t* getFileName() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + protected: + + //! fills the listbox with files. + void fillListBox(); + + //! sends the event that the file has been selected. + void sendSelectedEvent(); + + //! sends the event that the file choose process has been canceld + void sendCancelEvent(); + + core::position2d DragStart; + core::stringw FileName; + bool Dragging; + IGUIButton* CloseButton; + IGUIButton* OKButton; + IGUIButton* CancelButton; + IGUIListBox* FileBox; + IGUIElement* FileNameText; + IGUIElement* EventParent; + io::IFileSystem* FileSystem; + + io::IFileList* FileList; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIFont.cpp b/src/dep/src/irrlicht/CGUIFont.cpp new file mode 100644 index 0000000..c1f481e --- /dev/null +++ b/src/dep/src/irrlicht/CGUIFont.cpp @@ -0,0 +1,648 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIFont.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "os.h" +#include "IGUIEnvironment.h" +#include "IXMLReader.h" +#include "IReadFile.h" +#include "IVideoDriver.h" +#include "IGUISpriteBank.h" +#include "CImage.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIFont::CGUIFont(IGUIEnvironment *env, const c8* filename) +: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0), + MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0) +{ + #ifdef _DEBUG + setDebugName("CGUIFont"); + #endif + + if (Environment) + { + // don't grab environment, to avoid circular references + Driver = Environment->getVideoDriver(); + + SpriteBank = Environment->addEmptySpriteBank(filename); + } + + if (Driver) + Driver->grab(); +} + + +//! destructor +CGUIFont::~CGUIFont() +{ + if (Driver) + Driver->drop(); + + if (SpriteBank) + SpriteBank->drop(); + +} + + +//! loads a font file from xml +bool CGUIFont::load(io::IXMLReader* xml) +{ + if (!SpriteBank) + return false; + + while (xml->read()) + { + if (io::EXN_ELEMENT == xml->getNodeType()) + { + if (core::stringw(L"Texture") == xml->getNodeName()) + { + // add a texture + core::stringc fn = xml->getAttributeValue(L"filename"); + u32 i = (u32)xml->getAttributeValueAsInt(L"index"); + core::stringw alpha = xml->getAttributeValue(L"hasAlpha"); + + while (i+1 > SpriteBank->getTextureCount()) + SpriteBank->addTexture(0); + + // disable mipmaps+filtering + bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + // load texture + SpriteBank->setTexture(i, Driver->getTexture(fn.c_str())); + + // set previous mip-map+filter state + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap); + + // couldn't load texture, abort. + if (!SpriteBank->getTexture(i)) + { + os::Printer::log("Unable to load all textures in the font, aborting", ELL_ERROR); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + else + { + // colorkey texture rather than alpha channel? + if (alpha == core::stringw("false")) + Driver->makeColorKeyTexture(SpriteBank->getTexture(i), core::position2di(0,0)); + } + } + else if (core::stringw(L"c") == xml->getNodeName()) + { + // adding a character to this font + SFontArea a; + SGUISpriteFrame f; + SGUISprite s; + core::rect rectangle; + + a.underhang = xml->getAttributeValueAsInt(L"u"); + a.overhang = xml->getAttributeValueAsInt(L"o"); + a.spriteno = SpriteBank->getSprites().size(); + s32 texno = xml->getAttributeValueAsInt(L"i"); + + // parse rectangle + core::stringc rectstr = xml->getAttributeValue(L"r"); + wchar_t ch = xml->getAttributeValue(L"c")[0]; + + const c8 *c = rectstr.c_str(); + s32 val; + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.UpperLeftCorner.X = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.UpperLeftCorner.Y = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.LowerRightCorner.X = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.LowerRightCorner.Y = val; + + CharacterMap.insert(ch,Areas.size()); + + // make frame + f.rectNumber = SpriteBank->getPositions().size(); + f.textureNumber = texno; + + // add frame to sprite + s.Frames.push_back(f); + s.frameTime = 0; + + // add rectangle to sprite bank + SpriteBank->getPositions().push_back(rectangle); + a.width = rectangle.getWidth(); + + // add sprite to sprite bank + SpriteBank->getSprites().push_back(s); + + // add character to font + Areas.push_back(a); + } + } + } + + // set bad character + WrongCharacter = getAreaFromCharacter(L' '); + + setMaxHeight(); + + return true; +} + + +void CGUIFont::setMaxHeight() +{ + MaxHeight = 0; + s32 t; + + core::array< core::rect >& p = SpriteBank->getPositions(); + + for (u32 i=0; iMaxHeight) + MaxHeight = t; + } + +} + + +//! loads a font file, native file needed, for texture parsing +bool CGUIFont::load(io::IReadFile* file) +{ + if (!Driver) + return false; + + return loadTexture(Driver->createImageFromFile(file), + file->getFileName()); +} + + +//! loads a font file, native file needed, for texture parsing +bool CGUIFont::load(const c8* filename) +{ + if (!Driver) + return false; + return loadTexture(Driver->createImageFromFile( filename ), + filename); +} + + +//! load & prepare font from ITexture +bool CGUIFont::loadTexture(video::IImage* image, const c8* name) +{ + if (!image) + return false; + + s32 lowerRightPositions = 0; + + video::IImage* tmpImage=image; + bool deleteTmpImage=false; + switch(image->getColorFormat()) + { + case video::ECF_R5G6B5: + tmpImage = new video::CImage(video::ECF_A1R5G5B5,image); + deleteTmpImage=true; + case video::ECF_A1R5G5B5: + readPositions16bit(tmpImage, lowerRightPositions); + break; + case video::ECF_R8G8B8: + tmpImage = new video::CImage(video::ECF_A8R8G8B8,image); + deleteTmpImage=true; + case video::ECF_A8R8G8B8: + readPositions32bit (tmpImage, lowerRightPositions); + break; + } + + WrongCharacter = getAreaFromCharacter(L' '); + + // output warnings + if (!lowerRightPositions || !SpriteBank->getSprites().size()) + os::Printer::log("The amount of upper corner pixels or lower corner pixels is == 0, font file may be corrupted.", ELL_ERROR); + else + if (lowerRightPositions != (s32)SpriteBank->getPositions().size()) + os::Printer::log("The amount of upper corner pixels and the lower corner pixels is not equal, font file may be corrupted.", ELL_ERROR); + + bool ret = ( !SpriteBank->getSprites().empty() && lowerRightPositions ); + + + if ( ret ) + { + SpriteBank->addTexture(Driver->addTexture(name, tmpImage)); + } + if (deleteTmpImage) + tmpImage->drop(); + image->drop(); + + setMaxHeight(); + + return ret; +} + + +void CGUIFont::readPositions32bit(video::IImage* image, s32& lowerRightPositions) +{ + const core::dimension2d& size = image->getDimension(); + + s32* p = (s32*)image->lock(); + if (!p) + { + os::Printer::log("Could not lock texture while preparing texture for a font.", ELL_ERROR); + return; + } + + // fix half alpha of top left pixel in some font textures + p[0] |= 0xFF000000; + + s32 colorTopLeft = p[0]; + s32 colorLowerRight = *(p+1); + s32 colorBackGround = *(p+2); + s32 colorBackGroundTransparent = 0; // 0x00FFFFFF & colorBackGround; + + *(p+1) = colorBackGround; + + // start parsing + + core::position2d pos(0,0); + for (pos.Y=0; pos.YgetPositions().push_back(core::rect(pos, pos)); + } + else + if (*p == colorLowerRight) + { + if (SpriteBank->getPositions().size()<=(u32)lowerRightPositions) + { + image->unlock(); + lowerRightPositions = 0; + return; + } + + *p = colorBackGroundTransparent; + SpriteBank->getPositions()[lowerRightPositions].LowerRightCorner = pos; + // add frame to sprite bank + SGUISpriteFrame f; + f.rectNumber = lowerRightPositions; + f.textureNumber = 0; + SGUISprite s; + s.Frames.push_back(f); + s.frameTime = 0; + SpriteBank->getSprites().push_back(s); + // add character to font + SFontArea a; + a.overhang = 0; + a.underhang = 0; + a.spriteno = lowerRightPositions; + a.width = SpriteBank->getPositions()[lowerRightPositions].getWidth(); + Areas.push_back(a); + // map letter to character + wchar_t ch = (wchar_t)(lowerRightPositions + 32); + CharacterMap.set(ch, lowerRightPositions); + + ++lowerRightPositions; + } + else + if (*p == colorBackGround) + { + *p = colorBackGroundTransparent; + } + ++p; + } + } + + // Positions parsed. + + image->unlock(); +} + + +void CGUIFont::readPositions16bit(video::IImage* image, s32& lowerRightPositions) +{ + core::dimension2d size = image->getDimension(); + + s16* p = (s16*)image->lock(); + if (!p) + { + os::Printer::log("Could not lock texture while preparing texture for a font.", ELL_ERROR); + return; + } + + // fix half alpha of top left pixel in some font textures + p[0] |= 0x8000; + + s16 colorTopLeft = p[0]; + s16 colorLowerRight = *(p+1); + s16 colorBackGround = *(p+2); + s16 colorBackGroundTransparent = 0; // 0x7FFF & colorBackGround; + + *(p+1) = colorBackGround; + + // start parsing + + core::position2d pos(0,0); + for (pos.Y=0; pos.YgetPositions().push_back(core::rect(pos, pos)); + } + else + if (*p == colorLowerRight) + { + // too many lower right points + if (SpriteBank->getPositions().size()<=(u32)lowerRightPositions) + { + image->unlock(); + lowerRightPositions = 0; + return; + } + + *p = colorBackGroundTransparent; + SpriteBank->getPositions()[lowerRightPositions].LowerRightCorner = pos; + // add frame to sprite bank + SGUISpriteFrame f; + f.rectNumber = lowerRightPositions; + f.textureNumber = 0; + SGUISprite s; + s.Frames.push_back(f); + s.frameTime = 0; + SpriteBank->getSprites().push_back(s); + // add character to font + SFontArea a; + a.overhang = 0; + a.underhang = 0; + a.spriteno = lowerRightPositions; + a.width = SpriteBank->getPositions()[lowerRightPositions].getWidth(); + Areas.push_back(a); + // map letter to character + wchar_t ch = (wchar_t)(lowerRightPositions + 32); + CharacterMap.set(ch, lowerRightPositions); + + ++lowerRightPositions; + } + else + if (*p == colorBackGround) + *p = colorBackGroundTransparent; + ++p; + } + } + + // Positions parsed. + + image->unlock(); +} + + +//! returns the dimension of text +core::dimension2d CGUIFont::getDimension(const wchar_t* text) const +{ + core::dimension2d dim(0, 0); + core::dimension2d thisLine(0, MaxHeight); + + for (const wchar_t* p = text; *p; ++p) + { + bool lineBreak=false; + if (*p == L'\r') // Mac or Windows breaks + { + lineBreak = true; + if (p[1] == L'\n') // Windows breaks + ++p; + } + else if (*p == L'\n') // Unix breaks + { + lineBreak = true; + } + if (lineBreak) + { + dim.Height += thisLine.Height; + if (dim.Width < thisLine.Width) + dim.Width = thisLine.Width; + thisLine.Width = 0; + continue; + } + + const SFontArea &area = Areas[getAreaFromCharacter(*p)]; + + thisLine.Width += area.underhang; + thisLine.Width += area.width + area.overhang + GlobalKerningWidth; + } + + dim.Height += thisLine.Height; + if (dim.Width < thisLine.Width) + dim.Width = thisLine.Width; + + return dim; +} + + +//! set an Pixel Offset on Drawing ( scale position on width ) +void CGUIFont::setKerningWidth ( s32 kerning ) +{ + GlobalKerningWidth = kerning; +} + + +//! set an Pixel Offset on Drawing ( scale position on width ) +s32 CGUIFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previousLetter) const +{ + s32 ret = GlobalKerningWidth; + + if (thisLetter) + { + ret += Areas[getAreaFromCharacter(*thisLetter)].overhang; + + if (previousLetter) + { + ret += Areas[getAreaFromCharacter(*previousLetter)].underhang; + } + } + + return ret; +} + + +//! set an Pixel Offset on Drawing ( scale position on height ) +void CGUIFont::setKerningHeight ( s32 kerning ) +{ + GlobalKerningHeight = kerning; +} + + +//! set an Pixel Offset on Drawing ( scale position on height ) +s32 CGUIFont::getKerningHeight () const +{ + return GlobalKerningHeight; +} + + +//! returns the sprite number from a given character +u32 CGUIFont::getSpriteNoFromChar(const wchar_t *c) const +{ + return Areas[getAreaFromCharacter(*c)].spriteno; +} + + +s32 CGUIFont::getAreaFromCharacter(const wchar_t c) const +{ + core::map::Node* n = CharacterMap.find(c); + if (n) + return n->getValue(); + else + return WrongCharacter; +} + + +/* +//! draws an text and clips it to the specified rectangle if wanted +void CGUIFont::draw(const wchar_t* text, const core::rect& position, video::SColor color, bool hcenter, bool vcenter, const core::rect* clip) +{ + if (!Driver) + return; + + core::dimension2d textDimension; + core::position2d offset = position.UpperLeftCorner; + + if (hcenter || vcenter) + { + textDimension = getDimension(text); + + if (hcenter) + offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; + + if (vcenter) + offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; + } + + core::array indices; + indices.reallocate(core::stringw(text).size()); + u32 n; + while(*text) + { + n = (*text) - 32; + if ( n > Positions.size()) + n = WrongCharacter; + indices.push_back(n); + ++text; + } + Driver->draw2DImage(Texture, offset, Positions, indices, GlobalKerningWidth, clip, color, true); +} +*/ + + +//! draws some text and clips it to the specified rectangle if wanted +void CGUIFont::draw(const wchar_t* text, const core::rect& position, video::SColor color, bool hcenter, bool vcenter, const core::rect* clip) +{ + if (!Driver) + return; + + core::dimension2d textDimension; + core::position2d offset = position.UpperLeftCorner; + core::rect pos; + + if (hcenter || vcenter || clip) + textDimension = getDimension(text); + + if (hcenter) + offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; + + if (vcenter) + offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; + + if (clip) + { + core::rect clippedRect(offset, textDimension); + clippedRect.clipAgainst(*clip); + if (!clippedRect.isValid()) + return; + } + + while(*text) + { + SFontArea& area = Areas[getAreaFromCharacter(*text)]; + + offset.X += area.underhang; + + SpriteBank->draw2DSprite(area.spriteno, offset, clip, color); + + offset.X += area.width + area.overhang + GlobalKerningWidth; + + ++text; + } +} + + +//! Calculates the index of the character in the text which is on a specific position. +s32 CGUIFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const +{ + s32 x = 0; + s32 idx = 0; + + while (text[idx]) + { + const SFontArea& a = Areas[getAreaFromCharacter(text[idx])]; + + x += a.width + a.overhang + a.underhang; + + if (x >= pixel_x) + return idx; + + ++idx; + } + + return -1; +} + + +IGUISpriteBank* CGUIFont::getSpriteBank() const +{ + return SpriteBank; +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIFont.h b/src/dep/src/irrlicht/CGUIFont.h new file mode 100644 index 0000000..aba88ef --- /dev/null +++ b/src/dep/src/irrlicht/CGUIFont.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_FONT_H_INCLUDED__ +#define __C_GUI_FONT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFontBitmap.h" +#include "irrString.h" +#include "irrMap.h" +#include "IXMLReader.h" +#include "IReadFile.h" +#include "irrArray.h" + +namespace irr +{ + +namespace video +{ + class IVideoDriver; + class IImage; +} + +namespace gui +{ + + class IGUIEnvironment; + +class CGUIFont : public IGUIFontBitmap +{ +public: + + //! constructor + CGUIFont(IGUIEnvironment* env, const c8* filename); + + //! destructor + virtual ~CGUIFont(); + + //! loads a font from a texture file + bool load(const c8* filename); + + //! loads a font from a texture file + bool load(io::IReadFile* file); + + //! loads a font from an XML file + bool load(io::IXMLReader* xml); + + //! draws an text and clips it to the specified rectangle if wanted + virtual void draw(const wchar_t* text, const core::rect& position, video::SColor color, bool hcenter=false, bool vcenter=false, const core::rect* clip=0); + + //! returns the dimension of a text + virtual core::dimension2d getDimension(const wchar_t* text) const; + + //! Calculates the index of the character in the text which is on a specific position. + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const; + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; } + + //! set an Pixel Offset on Drawing ( scale position on width ) + virtual void setKerningWidth (s32 kerning); + virtual void setKerningHeight (s32 kerning); + + //! set an Pixel Offset on Drawing ( scale position on width ) + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const; + virtual s32 getKerningHeight() const; + + //! gets the sprite bank + virtual IGUISpriteBank* getSpriteBank() const; + + //! returns the sprite number from a given character + virtual u32 getSpriteNoFromChar(const wchar_t *c) const; + +private: + + struct SFontArea + { + SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {} + s32 underhang; + s32 overhang; + s32 width; + u32 spriteno; + }; + + //! load & prepare font from ITexture + bool loadTexture(video::IImage * image, const c8* name); + + void readPositions16bit(video::IImage* texture, s32& lowerRightPositions); + void readPositions32bit(video::IImage* texture, s32& lowerRightPositions); + + s32 getAreaFromCharacter (const wchar_t c) const; + void setMaxHeight(); + + core::array Areas; + core::map CharacterMap; + video::IVideoDriver* Driver; + IGUISpriteBank* SpriteBank; + IGUIEnvironment* Environment; + u32 WrongCharacter; + s32 MaxHeight; + s32 GlobalKerningWidth, GlobalKerningHeight; +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_FONT_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIImage.cpp b/src/dep/src/irrlicht/CGUIImage.cpp new file mode 100644 index 0000000..ddb6add --- /dev/null +++ b/src/dep/src/irrlicht/CGUIImage.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIImage.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace gui +{ + + + +//! constructor +CGUIImage::CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIImage(environment, parent, id, rectangle), Color(255,255,255,255), + Texture(0), UseAlphaChannel(false), ScaleImage(false) +{ + #ifdef _DEBUG + setDebugName("CGUIImage"); + #endif +} + + + +//! destructor +CGUIImage::~CGUIImage() +{ + if (Texture) + Texture->drop(); +} + + + +//! sets an image +void CGUIImage::setImage(video::ITexture* image) +{ + if (Texture) + Texture->drop(); + + Texture = image; + + if (Texture) + Texture->grab(); +} + + +//! sets the color of the image +void CGUIImage::setColor(video::SColor color) +{ + Color = color; +} + + +//! draws the element and its children +void CGUIImage::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect rect = AbsoluteRect; + + if (Texture) + { + if (ScaleImage) + { + video::SColor Colors[4]; + Colors[0] = Color; + Colors[1] = Color; + Colors[2] = Color; + Colors[3] = Color; + + driver->draw2DImage(Texture, AbsoluteRect, + core::rect(core::position2d(0,0), Texture->getOriginalSize()), + &AbsoluteClippingRect, Colors, UseAlphaChannel); + } + else + { + driver->draw2DImage(Texture, AbsoluteRect.UpperLeftCorner, + core::rect(core::position2d(0,0), Texture->getOriginalSize()), + &AbsoluteClippingRect, Color, UseAlphaChannel); + } + } + else + { + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! sets if the image should use its alpha channel to draw itself +void CGUIImage::setUseAlphaChannel(bool use) +{ + UseAlphaChannel = use; +} + +//! sets if the image should use its alpha channel to draw itself +void CGUIImage::setScaleImage(bool scale) +{ + ScaleImage = scale; +} + +//! Returns true if the image is scaled to fit, false if not +bool CGUIImage::isImageScaled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ScaleImage; +} + +//! Returns true if the image is using the alpha channel, false if not +bool CGUIImage::isAlphaChannelUsed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return UseAlphaChannel; +} + + +//! Writes attributes of the element. +void CGUIImage::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIImage::serializeAttributes(out,options); + + out->addTexture ("Texture", Texture); + out->addBool ("UseAlphaChannel", UseAlphaChannel); + out->addColor ("Color", Color); + out->addBool ("ScaleImage", ScaleImage); + +} + +//! Reads attributes of the element +void CGUIImage::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIImage::deserializeAttributes(in,options); + + setImage(in->getAttributeAsTexture("Texture")); + setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel")); + setColor(in->getAttributeAsColor("Color")); + setScaleImage(in->getAttributeAsBool("ScaleImage")); +} + + + + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIImage.h b/src/dep/src/irrlicht/CGUIImage.h new file mode 100644 index 0000000..d5b4bd3 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIImage.h @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_IMAGE_H_INCLUDED__ +#define __C_GUI_IMAGE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIImage.h" + +namespace irr +{ +namespace gui +{ + + class CGUIImage : public IGUIImage + { + public: + + //! constructor + CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIImage(); + + //! sets an image + virtual void setImage(video::ITexture* image); + + //! sets the color of the image + virtual void setColor(video::SColor color); + + //! sets if the image should scale to fit the element + virtual void setScaleImage(bool scale); + + //! draws the element and its children + virtual void draw(); + + //! sets if the image should use its alpha channel to draw itself + virtual void setUseAlphaChannel(bool use); + + //! Returns true if the image is scaled to fit, false if not + virtual bool isImageScaled() const; + + //! Returns true if the image is using the alpha channel, false if not + virtual bool isAlphaChannelUsed() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + + private: + video::SColor Color; + video::ITexture* Texture; + bool UseAlphaChannel; + bool ScaleImage; + + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_IMAGE_H_INCLUDED__ diff --git a/src/dep/src/irrlicht/CGUIInOutFader.cpp b/src/dep/src/irrlicht/CGUIInOutFader.cpp new file mode 100644 index 0000000..ced2b9d --- /dev/null +++ b/src/dep/src/irrlicht/CGUIInOutFader.cpp @@ -0,0 +1,180 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIInOutFader.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIInOutFader::CGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIInOutFader(environment, parent, id, rectangle) +{ + #ifdef _DEBUG + setDebugName("CGUIInOutFader"); + #endif + + Action = EFA_NOTHING; + StartTime = 0; + EndTime = 0; + + setColor(video::SColor(0,0,0,0)); +} + + +//! draws the element and its children +void CGUIInOutFader::draw() +{ + if (!IsVisible || !Action) + return; + + u32 now = os::Timer::getTime(); + if (now > EndTime && Action == EFA_FADE_IN) + { + Action = EFA_NOTHING; + return; + } + + video::IVideoDriver* driver = Environment->getVideoDriver(); + + if (driver) + { + f32 d; + + if (now > EndTime) + d = 0.0f; + else + d = (EndTime - now) / (f32)(EndTime - StartTime); + + video::SColor newCol = FullColor.getInterpolated(TransColor, d); + driver->draw2DRectangle(newCol, AbsoluteRect, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + + +//! Gets the color to fade out to or to fade in from. +video::SColor CGUIInOutFader::getColor() const +{ + return Color[1]; +} + + + +//! Sets the color to fade out to or to fade in from. +void CGUIInOutFader::setColor(video::SColor color) +{ + video::SColor s = color; + video::SColor d = color; + + s.setAlpha ( 255 ); + d.setAlpha ( 0 ); + setColor ( s,d ); + +/* + Color[0] = color; + + FullColor = Color[0]; + TransColor = Color[0]; + + if (Action == EFA_FADE_OUT) + { + FullColor.setAlpha(0); + TransColor.setAlpha(255); + } + else + if (Action == EFA_FADE_IN) + { + FullColor.setAlpha(255); + TransColor.setAlpha(0); + } +*/ +} + +void CGUIInOutFader::setColor(video::SColor source, video::SColor dest) +{ + Color[0] = source; + Color[1] = dest; + + if (Action == EFA_FADE_OUT) + { + FullColor = Color[1]; + TransColor = Color[0]; + } + else + if (Action == EFA_FADE_IN) + { + FullColor = Color[0]; + TransColor = Color[1]; + } + +} + + +//! Returns if the fade in or out process is done. +bool CGUIInOutFader::isReady() const +{ + u32 now = os::Timer::getTime(); + bool ret = (now > EndTime); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + + +//! Starts the fade in process. +void CGUIInOutFader::fadeIn(u32 time) +{ + StartTime = os::Timer::getTime(); + EndTime = StartTime + time; + Action = EFA_FADE_IN; + setColor(Color[0],Color[1]); +} + + +//! Starts the fade out process. +void CGUIInOutFader::fadeOut(u32 time) +{ + StartTime = os::Timer::getTime(); + EndTime = StartTime + time; + Action = EFA_FADE_OUT; + setColor(Color[0],Color[1]); +} + +//! Writes attributes of the element. +void CGUIInOutFader::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIInOutFader::serializeAttributes(out,options); + + out->addColor ("FullColor", FullColor); + out->addColor ("TransColor", TransColor); + +} + +//! Reads attributes of the element +void CGUIInOutFader::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIInOutFader::deserializeAttributes(in,options); + + FullColor = in->getAttributeAsColor("FullColor"); + TransColor = in->getAttributeAsColor("TransColor"); +} + + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIInOutFader.h b/src/dep/src/irrlicht/CGUIInOutFader.h new file mode 100644 index 0000000..5297a5e --- /dev/null +++ b/src/dep/src/irrlicht/CGUIInOutFader.h @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_IN_OUT_FADER_H_INCLUDED__ +#define __C_GUI_IN_OUT_FADER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIInOutFader.h" + +namespace irr +{ +namespace gui +{ + + class CGUIInOutFader : public IGUIInOutFader + { + public: + + //! constructor + CGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle); + + //! draws the element and its children + virtual void draw(); + + //! Gets the color to fade out to or to fade in from. + virtual video::SColor getColor() const; + + //! Sets the color to fade out to or to fade in from. + virtual void setColor(video::SColor color ); + virtual void setColor(video::SColor source, video::SColor dest); + + //! Starts the fade in process. + virtual void fadeIn(u32 time); + + //! Starts the fade out process. + virtual void fadeOut(u32 time); + + //! Returns if the fade in or out process is done. + virtual bool isReady() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + enum EFadeAction + { + EFA_NOTHING = 0, + EFA_FADE_IN, + EFA_FADE_OUT + }; + + u32 StartTime; + u32 EndTime; + EFadeAction Action; + + video::SColor Color[2]; + video::SColor FullColor; + video::SColor TransColor; + + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_IN_OUT_FADER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIListBox.cpp b/src/dep/src/irrlicht/CGUIListBox.cpp new file mode 100644 index 0000000..e4ac6f4 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIListBox.cpp @@ -0,0 +1,857 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIListBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIListBox.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "CGUIScrollBar.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip, + bool drawBack, bool moveOverSelect) +: IGUIListBox(environment, parent, id, rectangle), Selected(-1), ItemHeight(0), + TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), + ScrollBar(0), Selecting(false), DrawBack(drawBack), + MoveOverSelect(moveOverSelect), selectTime(0), AutoScroll(true), + KeyBuffer(), LastKeyTime(0), HighlightWhenNotFocused(true) +{ + #ifdef _DEBUG + setDebugName("CGUIListBox"); + #endif + + IGUISkin* skin = Environment->getSkin(); + const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE); + + ScrollBar = new CGUIScrollBar(false, Environment, this, 0, + core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), + !clip); + ScrollBar->setSubElement(true); + ScrollBar->setTabStop(false); + ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + ScrollBar->setVisible(false); + ScrollBar->drop(); + + ScrollBar->setPos(0); + ScrollBar->grab(); + + setNotClipped(!clip); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + updateAbsolutePosition(); +} + + +//! destructor +CGUIListBox::~CGUIListBox() +{ + if (ScrollBar) + ScrollBar->drop(); + + if (Font) + Font->drop(); + + if (IconBank) + IconBank->drop(); +} + + +//! returns amount of list items +u32 CGUIListBox::getItemCount() const +{ + return Items.size(); +} + + +//! returns string of a list item. the may be a value from 0 to itemCount-1 +const wchar_t* CGUIListBox::getListItem(u32 id) const +{ + if (id>=Items.size()) + return 0; + + return Items[id].text.c_str(); +} + + +//! Returns the icon of an item +s32 CGUIListBox::getIcon(u32 id) const +{ + if (id>=Items.size()) + return -1; + + return Items[id].icon; +} + + +//! adds a list item, returns id of item +u32 CGUIListBox::addItem(const wchar_t* text) +{ + return addItem(text, -1); +} + + +//! adds a list item, returns id of item +void CGUIListBox::removeItem(u32 id) +{ + if (id >= Items.size()) + return; + + if ((u32)Selected==id) + { + Selected = -1; + } + else if ((u32)Selected > id) + { + Selected -= 1; + selectTime = os::Timer::getTime(); + } + + Items.erase(id); + + recalculateItemHeight(); +} + + +//! clears the list +void CGUIListBox::clear() +{ + Items.clear(); + ItemsIconWidth = 0; + Selected = -1; + + if (ScrollBar) + ScrollBar->setPos(0); + + recalculateItemHeight(); +} + + +void CGUIListBox::recalculateItemHeight() +{ + IGUISkin* skin = Environment->getSkin(); + + if (Font != skin->getFont()) + { + if (Font) + Font->drop(); + + Font = skin->getFont(); + ItemHeight = 0; + + if (Font) + { + ItemHeight = Font->getDimension(L"A").Height + 4; + Font->grab(); + } + } + + TotalItemHeight = ItemHeight * Items.size(); + ScrollBar->setMax(TotalItemHeight - AbsoluteRect.getHeight()); + + if ( TotalItemHeight <= AbsoluteRect.getHeight() ) + ScrollBar->setVisible(false); + else + ScrollBar->setVisible(true); +} + + +//! returns id of selected item. returns -1 if no item is selected. +s32 CGUIListBox::getSelected() const +{ + return Selected; +} + + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUIListBox::setSelected(s32 id) +{ + if ((u32)id>=Items.size()) + Selected = -1; + else + Selected = id; + + selectTime = os::Timer::getTime(); + + recalculateScrollPos(); +} + + +//! called if an event happened. +bool CGUIListBox::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_DOWN || + event.KeyInput.Key == KEY_UP || + event.KeyInput.Key == KEY_HOME || + event.KeyInput.Key == KEY_END || + event.KeyInput.Key == KEY_NEXT || + event.KeyInput.Key == KEY_PRIOR ) ) + { + s32 oldSelected = Selected; + switch (event.KeyInput.Key) + { + case KEY_DOWN: + Selected += 1; + break; + case KEY_UP: + Selected -= 1; + break; + case KEY_HOME: + Selected = 0; + break; + case KEY_END: + Selected = (s32)Items.size()-1; + break; + case KEY_NEXT: + Selected += AbsoluteRect.getHeight() / ItemHeight; + break; + case KEY_PRIOR: + Selected -= AbsoluteRect.getHeight() / ItemHeight; + break; + default: + break; + } + if (Selected >= (s32)Items.size()) + Selected = Items.size() - 1; + else + if (Selected<0) + Selected = 0; + + recalculateScrollPos(); + + // post the news + + if (oldSelected != Selected && Parent && !Selecting && !MoveOverSelect) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + + return true; + } + else + if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) ) + { + if (Parent) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN; + Parent->OnEvent(e); + } + return true; + } + else if (event.KeyInput.PressedDown && event.KeyInput.Char) + { + // change selection based on text as it is typed. + u32 now = os::Timer::getTime(); + + if (now - LastKeyTime < 500) + { + // add to key buffer if it isn't a key repeat + if (!(KeyBuffer.size() == 1 && KeyBuffer[0] == event.KeyInput.Char)) + { + KeyBuffer += L" "; + KeyBuffer[KeyBuffer.size()-1] = event.KeyInput.Char; + } + } + else + { + KeyBuffer = L" "; + KeyBuffer[0] = event.KeyInput.Char; + } + LastKeyTime = now; + + // find the selected item, starting at the current selection + s32 start = Selected; + // dont change selection if the key buffer matches the current item + if (Selected > -1 && KeyBuffer.size() > 1) + { + if (Items[Selected].text.size() >= KeyBuffer.size() && + KeyBuffer.equals_ignore_case(Items[Selected].text.subString(0,KeyBuffer.size()))) + return true; + } + + s32 current; + for (current = start+1; current < (s32)Items.size(); ++current) + { + if (Items[current].text.size() >= KeyBuffer.size()) + { + if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) + { + if (Parent && Selected != current && !Selecting && !MoveOverSelect) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + setSelected(current); + return true; + } + } + } + for (current = 0; current <= start; ++current) + { + if (Items[current].text.size() >= KeyBuffer.size()) + { + if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) + { + if (Parent && Selected != current && !Selecting && !MoveOverSelect) + { + Selected = current; + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + setSelected(current); + return true; + } + } + } + + return true; + } + break; + + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_SCROLL_BAR_CHANGED: + if (event.GUIEvent.Caller == ScrollBar) + return true; + break; + case gui::EGET_ELEMENT_FOCUS_LOST: + { + if (event.GUIEvent.Caller == this) + Selecting = false; + } + default: + break; + } + break; + + case EET_MOUSE_INPUT_EVENT: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + ScrollBar->setPos(ScrollBar->getPos() + (s32)event.MouseInput.Wheel*-10); + return true; + + case EMIE_LMOUSE_PRESSED_DOWN: + { + Selecting = true; + return true; + } + + case EMIE_LMOUSE_LEFT_UP: + { + Selecting = false; + + if (isPointInside(p)) + selectNew(event.MouseInput.Y); + + return true; + } + + case EMIE_MOUSE_MOVED: + if (Selecting || MoveOverSelect) + { + if (isPointInside(p)) + { + selectNew(event.MouseInput.Y, true); + return true; + } + } + default: + break; + } + } + break; + case EET_LOG_TEXT_EVENT: + case EET_USER_EVENT: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +void CGUIListBox::selectNew(s32 ypos, bool onlyHover) +{ + u32 now = os::Timer::getTime(); + s32 oldSelected = Selected; + + // find new selected item. + if (ItemHeight!=0) + Selected = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; + + if (Selected<0) + Selected = 0; + else + if ((u32)Selected >= Items.size()) + Selected = Items.size() - 1; + + recalculateScrollPos(); + + // post the news + if (Parent && !onlyHover) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; + Parent->OnEvent(event); + } + selectTime = now; +} + + +//! Update the position and size of the listbox, and update the scrollbar +void CGUIListBox::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + + recalculateItemHeight(); +} + + +//! draws the element and its children +void CGUIListBox::draw() +{ + if (!IsVisible) + return; + + recalculateItemHeight(); // if the font changed + + IGUISkin* skin = Environment->getSkin(); + + core::rect* clipRect = 0; + + // draw background + core::rect frameRect(AbsoluteRect); + + // draw items + + core::rect clientClip(AbsoluteRect); + clientClip.UpperLeftCorner.Y += 1; + clientClip.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + clientClip.LowerRightCorner.Y -= 1; + clientClip.clipAgainst(AbsoluteClippingRect); + + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, + DrawBack, frameRect, &clientClip); + + if (clipRect) + clientClip.clipAgainst(*clipRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + + frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; + + frameRect.UpperLeftCorner.Y -= ScrollBar->getPos(); + frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); + + bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && + frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) + { + if (i == Selected && hl) + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); + + core::rect textRect = frameRect; + textRect.UpperLeftCorner.X += 3; + + if (Font) + { + if (IconBank && (Items[i].icon > -1)) + { + core::position2di iconPos = textRect.UpperLeftCorner; + iconPos.Y += textRect.getHeight() / 2; + iconPos.X += ItemsIconWidth/2; + + if ( i==Selected && hl ) + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), + selectTime, os::Timer::getTime(), false, true); + } + else + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), + 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); + } + } + + textRect.UpperLeftCorner.X += ItemsIconWidth+3; + + if ( i==Selected && hl ) + { + Font->draw(Items[i].text.c_str(), textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT), + false, true, &clientClip); + } + else + { + Font->draw(Items[i].text.c_str(), textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT), + false, true, &clientClip); + } + + textRect.UpperLeftCorner.X -= ItemsIconWidth+3; + } + } + + frameRect.UpperLeftCorner.Y += ItemHeight; + frameRect.LowerRightCorner.Y += ItemHeight; + } + + IGUIElement::draw(); +} + + +//! adds an list item with an icon +u32 CGUIListBox::addItem(const wchar_t* text, s32 icon) +{ + ListItem i; + i.text = text; + i.icon = icon; + + Items.push_back(i); + recalculateItemHeight(); + recalculateItemWidth(icon); + + return Items.size() - 1; +} + + +void CGUIListBox::setSpriteBank(IGUISpriteBank* bank) +{ + if (IconBank) + IconBank->drop(); + + IconBank = bank; + if (IconBank) + IconBank->grab(); +} + + +void CGUIListBox::recalculateScrollPos() +{ + if (!AutoScroll) + return; + + const s32 selPos = (Selected == -1 ? TotalItemHeight : Selected * ItemHeight) - ScrollBar->getPos(); + + if (selPos < 0) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos); + } + else + if (selPos > AbsoluteRect.getHeight() - ItemHeight) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight); + } +} + + +void CGUIListBox::setAutoScrollEnabled(bool scroll) +{ + AutoScroll = scroll; +} + + +bool CGUIListBox::isAutoScrollEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return AutoScroll; +} + + +bool CGUIListBox::getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const +{ + switch ( colorType ) + { + case EGUI_LBC_TEXT: + useColorLabel = "UseColText"; + colorLabel = "ColText"; + break; + case EGUI_LBC_TEXT_HIGHLIGHT: + useColorLabel = "UseColTextHl"; + colorLabel = "ColTextHl"; + break; + case EGUI_LBC_ICON: + useColorLabel = "UseColIcon"; + colorLabel = "ColIcon"; + break; + case EGUI_LBC_ICON_HIGHLIGHT: + useColorLabel = "UseColIconHl"; + colorLabel = "ColIconHl"; + break; + default: + return false; + } + return true; +} + + +//! Writes attributes of the element. +void CGUIListBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIListBox::serializeAttributes(out,options); + + // todo: out->addString ("IconBank", IconBank->getName?); + out->addBool ("DrawBack", DrawBack); + out->addBool ("MoveOverSelect", MoveOverSelect); + out->addBool ("AutoScroll", AutoScroll); + + out->addInt("ItemCount", Items.size()); + for (u32 i=0;iaddString(label.c_str(), Items[i].text.c_str() ); + + for ( s32 c=0; c < (s32)EGUI_LBC_COUNT; ++c ) + { + core::stringc useColorLabel, colorLabel; + if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) + return; + label = useColorLabel; label += i; + if ( Items[i].OverrideColors[c].Use ) + { + out->addBool(label.c_str(), true ); + label = colorLabel; label += i; + out->addColor(label.c_str(), Items[i].OverrideColors[c].Color); + } + else + { + out->addBool(label.c_str(), false ); + } + } + } +} + + +//! Reads attributes of the element +void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + clear(); + + DrawBack = in->getAttributeAsBool("DrawBack"); + MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); + AutoScroll = in->getAttributeAsBool("AutoScroll"); + + IGUIListBox::deserializeAttributes(in,options); + + const s32 count = in->getAttributeAsInt("ItemCount"); + for (s32 i=0; igetAttributeAsStringW(label.c_str()); + + addItem(item.text.c_str(), item.icon); + + for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) + { + core::stringc useColorLabel, colorLabel; + if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) + return; + label = useColorLabel; label += i; + Items[i].OverrideColors[c].Use = in->getAttributeAsBool(label.c_str()); + if ( Items[i].OverrideColors[c].Use ) + { + label = colorLabel; label += i; + Items[i].OverrideColors[c].Color = in->getAttributeAsColor(label.c_str()); + } + } + } +} + + +void CGUIListBox::recalculateItemWidth(s32 icon) +{ + if (IconBank && icon > -1 && + IconBank->getSprites().size() > (u32)icon && + IconBank->getSprites()[(u32)icon].Frames.size()) + { + u32 rno = IconBank->getSprites()[(u32)icon].Frames[0].rectNumber; + if (IconBank->getPositions().size() > rno) + { + const s32 w = IconBank->getPositions()[rno].getWidth(); + if (w > ItemsIconWidth) + ItemsIconWidth = w; + } + } +} + + +void CGUIListBox::setItem(u32 index, const wchar_t* text, s32 icon) +{ + if ( index >= Items.size() ) + return; + + Items[index].text = text; + Items[index].icon = icon; + + recalculateItemHeight(); + recalculateItemWidth(icon); +} + + +//! Insert the item at the given index +//! Return the index on success or -1 on failure. +s32 CGUIListBox::insertItem(u32 index, const wchar_t* text, s32 icon) +{ + ListItem i; + i.text = text; + i.icon = icon; + + Items.insert(i, index); + recalculateItemHeight(); + recalculateItemWidth(icon); + + return index; +} + + +void CGUIListBox::swapItems(u32 index1, u32 index2) +{ + if ( index1 >= Items.size() || index2 >= Items.size() ) + return; + + ListItem dummmy = Items[index1]; + Items[index1] = Items[index2]; + Items[index2] = dummmy; +} + + +void CGUIListBox::setItemOverrideColor(u32 index, const video::SColor &color) +{ + for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = true; + Items[index].OverrideColors[c].Color = color; + } +} + + +void CGUIListBox::setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, const video::SColor &color) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = true; + Items[index].OverrideColors[colorType].Color = color; +} + + +void CGUIListBox::clearItemOverrideColor(u32 index) +{ + for (u32 c=0; c < (u32)EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = false; + } +} + + +void CGUIListBox::clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = false; +} + + +bool CGUIListBox::hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return false; + + return Items[index].OverrideColors[colorType].Use; +} + + +video::SColor CGUIListBox::getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( (u32)index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return video::SColor(); + + return Items[index].OverrideColors[colorType].Color; +} + + +video::SColor CGUIListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const +{ + IGUISkin* skin = Environment->getSkin(); + if ( !skin ) + return video::SColor(); + + switch ( colorType ) + { + case EGUI_LBC_TEXT: + return skin->getColor(EGDC_BUTTON_TEXT); + case EGUI_LBC_TEXT_HIGHLIGHT: + return skin->getColor(EGDC_HIGH_LIGHT_TEXT); + case EGUI_LBC_ICON: + return skin->getColor(EGDC_ICON); + case EGUI_LBC_ICON_HIGHLIGHT: + return skin->getColor(EGDC_ICON_HIGH_LIGHT); + default: + return video::SColor(); + } +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIListBox.h b/src/dep/src/irrlicht/CGUIListBox.h new file mode 100644 index 0000000..3929655 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIListBox.h @@ -0,0 +1,176 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_LIST_BOX_H_INCLUDED__ +#define __C_GUI_LIST_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIListBox.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + + class IGUIFont; + class IGUIScrollBar; + + class CGUIListBox : public IGUIListBox + { + public: + //! constructor + CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip=true, + bool drawBack=false, bool moveOverSelect=false); + + //! destructor + virtual ~CGUIListBox(); + + //! returns amount of list items + virtual u32 getItemCount() const; + + //! returns string of a list item. the id may be a value from 0 to itemCount-1 + virtual const wchar_t* getListItem(u32 id) const; + + //! adds an list item, returns id of item + virtual u32 addItem(const wchar_t* text); + + //! clears the list + virtual void clear(); + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 id); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! adds an list item with an icon + //! \param text Text of list entry + //! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon + //! \return + //! returns the id of the new created item + virtual u32 addItem(const wchar_t* text, s32 icon); + + //! Returns the icon of an item + virtual s32 getIcon(u32 id) const; + + //! removes an item from the list + virtual void removeItem(u32 id); + + //! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of + //! the built-in-font by default. A sprite can be displayed in front of every list item. + //! An icon is an index within the icon sprite bank. Several default icons are available in the + //! skin through getIcon + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! sets if automatic scrolling is enabled or not. Default is true. + virtual void setAutoScrollEnabled(bool scroll); + + //! returns true if automatic scrolling is enabled, false if not. + virtual bool isAutoScrollEnabled() const; + + //! Update the position and size of the listbox, and update the scrollbar + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + //! set all item colors at given index to color + virtual void setItemOverrideColor(u32 index, const video::SColor &color); + + //! set all item colors of specified type at given index to color + virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, const video::SColor &color); + + //! clear all item colors at index + virtual void clearItemOverrideColor(u32 index); + + //! clear item color at index for given colortype + virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType); + + //! has the item at index it's color overwritten? + virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the overwrite color at given item index. + virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the default color which is used for the given colorType + virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const; + + //! set the item at the given index + virtual void setItem(u32 index, const wchar_t* text, s32 icon); + + //! Insert the item at the given index + //! Return the index on success or -1 on failure. + virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon); + + //! Swap the items at the given indices + virtual void swapItems(u32 index1, u32 index2); + + private: + + struct ListItem + { + ListItem() : icon(-1) + {} + + core::stringw text; + s32 icon; + + // A multicolor extension + struct ListItemOverrideColor + { + ListItemOverrideColor() : Use(false) {} + bool Use; + video::SColor Color; + }; + ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]; + }; + + void recalculateItemHeight(); + void selectNew(s32 ypos, bool onlyHover=false); + void recalculateScrollPos(); + + // extracted that function to avoid copy&paste code + void recalculateItemWidth(s32 icon); + + // get labels used for serialization + bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const; + + core::array< ListItem > Items; + s32 Selected; + s32 ItemHeight; + s32 TotalItemHeight; + s32 ItemsIconWidth; + gui::IGUIFont* Font; + gui::IGUISpriteBank* IconBank; + gui::IGUIScrollBar* ScrollBar; + bool Selecting; + bool DrawBack; + bool MoveOverSelect; + u32 selectTime; + bool AutoScroll; + core::stringw KeyBuffer; + u32 LastKeyTime; + bool HighlightWhenNotFocused; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/dep/src/irrlicht/CGUIMenu.cpp b/src/dep/src/irrlicht/CGUIMenu.cpp new file mode 100644 index 0000000..c42a4e5 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMenu.cpp @@ -0,0 +1,260 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMenu.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" + +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIMenu::CGUIMenu(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : CGUIContextMenu(environment, parent, id, rectangle, false, true) +{ + #ifdef _DEBUG + setDebugName("CGUIMenu"); + #endif + + Type = EGUIET_MENU; + + recalculateSize(); +} + + +//! draws the element and its children +void CGUIMenu::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(EGDF_MENU); + + if (font != LastFont) + { + if (LastFont) + LastFont->drop(); + LastFont = font; + if (LastFont) + LastFont->grab(); + + recalculateSize(); + } + + core::rect rect = AbsoluteRect; + + // draw frame + + skin->draw3DToolBar(this, rect, &AbsoluteClippingRect); + + // loop through all menu items + + rect = AbsoluteRect; + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (!Items[i].IsSeparator) + { + rect = getRect(Items[i], AbsoluteRect); + + // draw highlighted + if (i == HighLighted && Items[i].Enabled) + { + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_DARK_SHADOW), + true, true, rect, &AbsoluteClippingRect); + } + // draw text + + EGUI_DEFAULT_COLOR c = EGDC_BUTTON_TEXT; + + if (i == HighLighted) + c = EGDC_HIGH_LIGHT_TEXT; + + if (!Items[i].Enabled) + c = EGDC_GRAY_TEXT; + + if (font) + font->draw(Items[i].Text.c_str(), rect, + skin->getColor(c), true, true, &AbsoluteClippingRect); + } + } + + IGUIElement::draw(); +} + + +//! called if an event happened. +bool CGUIMenu::OnEvent(const SEvent& event) +{ + if (!IsEnabled) + return Parent ? Parent->OnEvent(event) : false; + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_ELEMENT_FOCUS_LOST: + if (event.GUIEvent.Caller == this && !isMyChild(event.GUIEvent.Element)) + { + closeAllSubMenus(); + HighLighted = -1; + } + break; + case gui::EGET_ELEMENT_FOCUSED: + if (event.GUIEvent.Caller == this && Parent) + { + Parent->bringToFront(this); + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + { + if (!Environment->hasFocus(this)) + { + Environment->setFocus(this); + } + + if (Parent) + Parent->bringToFront(this); + + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + bool shouldCloseSubMenu = hasOpenSubMenu(); + if (!AbsoluteClippingRect.isPointInside(p)) + { + shouldCloseSubMenu = false; + s32 t = sendClick(p); + if ((t==0 || t==1) && Environment->hasFocus(this)) + Environment->removeFocus(this); + } + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), true); + if ( shouldCloseSubMenu ) + closeAllSubMenus(); + + return true; + } + case EMIE_MOUSE_MOVED: + if (Environment->hasFocus(this)) + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), hasOpenSubMenu()); + return true; + default: + break; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +void CGUIMenu::recalculateSize() +{ + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(EGDF_MENU); + + if (!font) + { + if (Parent && skin) + RelativeRect = core::rect(0,0, + Parent->getAbsolutePosition().LowerRightCorner.X, + skin->getSize(EGDS_MENU_HEIGHT)); + return; + } + + core::rect rect; + rect.UpperLeftCorner.X = 0; + rect.UpperLeftCorner.Y = 0; + s32 height = font->getDimension(L"A").Height + 5; + //if (skin && height < skin->getSize ( EGDS_MENU_HEIGHT )) + // height = skin->getSize(EGDS_MENU_HEIGHT); + s32 width = 0; + s32 i; + + for (i=0; i<(s32)Items.size(); ++i) + { + if (Items[i].IsSeparator) + { + Items[i].Dim.Width = 0; + Items[i].Dim.Height = height; + } + else + { + Items[i].Dim = font->getDimension(Items[i].Text.c_str()); + Items[i].Dim.Width += 20; + } + + Items[i].PosY = width; + width += Items[i].Dim.Width; + } + + if (Parent) + width = Parent->getAbsolutePosition().getWidth(); + + rect.LowerRightCorner.X = width; + rect.LowerRightCorner.Y = height; + + setRelativePosition(rect); + + // recalculate submenus + for (i=0; i<(s32)Items.size(); ++i) + if (Items[i].SubMenu) + { + // move submenu + s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); + s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); + + Items[i].SubMenu->setRelativePosition( + core::rect(Items[i].PosY, height , + Items[i].PosY+w-5, height+h)); + } +} + + +//! returns the item highlight-area +core::rect CGUIMenu::getHRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.X += i.PosY; + r.LowerRightCorner.X = r.UpperLeftCorner.X + i.Dim.Width; + return r; +} + +//! Gets drawing rect of Item +core::rect CGUIMenu::getRect(const SItem& i, const core::rect& absolute) const +{ + return getHRect(i, absolute); +} + +void CGUIMenu::updateAbsolutePosition() +{ + if (Parent) + DesiredRect.LowerRightCorner.X = Parent->getAbsolutePosition().getWidth(); + + IGUIElement::updateAbsolutePosition(); +} + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIMenu.h b/src/dep/src/irrlicht/CGUIMenu.h new file mode 100644 index 0000000..844922c --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMenu.h @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MENU_H_INCLUDED__ +#define __C_GUI_MENU_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIContextMenu.h" + +namespace irr +{ +namespace gui +{ + + //! GUI menu interface. + class CGUIMenu : public CGUIContextMenu + { + public: + + //! constructor + CGUIMenu(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! draws the element and its children + virtual void draw(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + protected: + + virtual void recalculateSize(); + + //! returns the item highlight-area + virtual core::rect getHRect(const SItem& i, const core::rect& absolute) const; + + //! Gets drawing rect of Item + virtual core::rect getRect(const SItem& i, const core::rect& absolute) const; + }; + +} // end namespace gui +} // end namespace irr + + +#endif // __C_GUI_MENU_H_INCLUDED__ +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIMeshViewer.cpp b/src/dep/src/irrlicht/CGUIMeshViewer.cpp new file mode 100644 index 0000000..0bc3599 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMeshViewer.cpp @@ -0,0 +1,171 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMeshViewer.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IAnimatedMesh.h" +#include "IMesh.h" +#include "irrMath.h" +#include "os.h" +#include "IGUISkin.h" + +namespace irr +{ + +namespace gui +{ + + +//! constructor +CGUIMeshViewer::CGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIMeshViewer(environment, parent, id, rectangle), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CGUIMeshViewer"); + #endif +} + + +//! destructor +CGUIMeshViewer::~CGUIMeshViewer() +{ + if (Mesh) + Mesh->drop(); +} + + +//! sets the mesh to be shown +void CGUIMeshViewer::setMesh(scene::IAnimatedMesh* mesh) +{ + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + if (!Mesh) + return; + + core::vector3df center(0.0f,0.0f,0.0f); + core::aabbox3d box; + + if (mesh->getFrameCount()) + { + box = mesh->getMesh(0)->getBoundingBox(); + center = (box.MaxEdge + box.MinEdge) / 2; + } + + if (Mesh) + Mesh->grab(); +} + + +//! Gets the displayed mesh +scene::IAnimatedMesh* CGUIMeshViewer::getMesh() const +{ + return Mesh; +} + + +//! sets the material +void CGUIMeshViewer::setMaterial(const video::SMaterial& material) +{ + Material = material; +} + + +//! gets the material +const video::SMaterial& CGUIMeshViewer::getMaterial() const +{ + return Material; +} + + +//! called if an event happened. +bool CGUIMeshViewer::OnEvent(const SEvent& event) +{ + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void CGUIMeshViewer::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + core::rect viewPort = AbsoluteRect; + viewPort.LowerRightCorner.X -= 1; + viewPort.LowerRightCorner.Y -= 1; + viewPort.UpperLeftCorner.X += 1; + viewPort.UpperLeftCorner.Y += 1; + + viewPort.clipAgainst(AbsoluteClippingRect); + + // draw the frame + + core::rect frameRect(AbsoluteRect); + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); + + frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1; + frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + // draw the mesh + + if (Mesh) + { + //TODO: if outside of screen, dont draw. + // - why is the absolute clipping rect not already the screen? + + core::rect oldViewPort = driver->getViewPort(); + + driver->setViewPort(viewPort); + + core::matrix4 mat; + + //CameraControl->calculateProjectionMatrix(mat); + //driver->setTransform(video::TS_PROJECTION, mat); + + mat.makeIdentity(); + mat.setTranslation(core::vector3df(0,0,0)); + driver->setTransform(video::ETS_WORLD, mat); + + //CameraControl->calculateViewMatrix(mat); + //driver->setTransform(video::TS_VIEW, mat); + + driver->setMaterial(Material); + + scene::IMesh* m = Mesh->getMesh(os::Timer::getTime()/20); + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + driver->drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/ 3, mb->getVertexType(), scene::EPT_TRIANGLES); + } + + driver->setViewPort(oldViewPort); + } + + IGUIElement::draw(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIMeshViewer.h b/src/dep/src/irrlicht/CGUIMeshViewer.h new file mode 100644 index 0000000..a8e595c --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMeshViewer.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MESH_VIEWER_H_INCLUDED__ +#define __C_GUI_MESH_VIEWER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIMeshViewer.h" +#include "SMaterial.h" +#include "vector3d.h" + +namespace irr +{ + +namespace gui +{ + + class CGUIMeshViewer : public IGUIMeshViewer + { + public: + + //! constructor + CGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIMeshViewer(); + + //! sets the mesh to be shown + virtual void setMesh(scene::IAnimatedMesh* mesh); + + //! Gets the displayed mesh + virtual scene::IAnimatedMesh* getMesh() const; + + //! sets the material + virtual void setMaterial(const video::SMaterial& material); + + //! gets the material + virtual const video::SMaterial& getMaterial() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + private: + + video::SMaterial Material; + scene::IAnimatedMesh* Mesh; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_MESH_VIEWER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUIMessageBox.cpp b/src/dep/src/irrlicht/CGUIMessageBox.cpp new file mode 100644 index 0000000..0e4bb94 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMessageBox.cpp @@ -0,0 +1,433 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMessageBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIButton.h" +#include "IGUIFont.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, + const wchar_t* text, s32 flags, + IGUIElement* parent, s32 id, core::rect rectangle) +: CGUIWindow(environment, parent, id, rectangle), + OkButton(0), CancelButton(0), YesButton(0), NoButton(0), StaticText(0), + Flags(flags), MessageText(text), Pressed(false) +{ + #ifdef _DEBUG + setDebugName("CGUIMessageBox"); + #endif + + // set element type + Type = EGUIET_MESSAGE_BOX; + + // remove focus + Environment->setFocus(0); + + // remove buttons + + getMaximizeButton()->remove(); + getMinimizeButton()->remove(); + + if (caption) + setText(caption); + + Environment->setFocus(this); + + refreshControls(); +} + + +//! destructor +CGUIMessageBox::~CGUIMessageBox() +{ + if (StaticText) + StaticText->drop(); + + if (OkButton) + OkButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + if (YesButton) + YesButton->drop(); + + if (NoButton) + NoButton->drop(); +} + + +void CGUIMessageBox::refreshControls() +{ + const IGUISkin* skin = Environment->getSkin(); + IGUIElement* focusMe = 0; + + const s32 buttonHeight = skin->getSize(EGDS_BUTTON_HEIGHT); + const s32 buttonWidth = skin->getSize(EGDS_BUTTON_WIDTH); + const s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2; + const s32 buttonDistance = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + + // add static multiline text + + core::dimension2d dim(AbsoluteClippingRect.getWidth() - buttonWidth, + AbsoluteClippingRect.getHeight() - (buttonHeight * 3)); + const core::position2d pos((AbsoluteClippingRect.getWidth() - dim.Width) / 2, + buttonHeight / 2 + titleHeight); + + if (!StaticText) + { + StaticText = Environment->addStaticText(MessageText.c_str(), + core::rect(pos, dim), false, false, this); + StaticText->setWordWrap(true); + StaticText->setSubElement(true); + StaticText->grab(); + } + else + { + StaticText->setRelativePosition(core::rect(pos, dim)); + StaticText->setText(MessageText.c_str()); + } + + // adjust static text height + + const s32 textHeight = StaticText->getTextHeight(); + core::rect tmp = StaticText->getRelativePosition(); + tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + textHeight; + StaticText->setRelativePosition(tmp); + dim.Height = textHeight; + + // adjust message box height + + tmp = getRelativePosition(); + s32 msgBoxHeight = textHeight + core::floor32(2.5f * buttonHeight) + titleHeight; + + // adjust message box position + + tmp.UpperLeftCorner.Y = (Parent->getAbsolutePosition().getHeight() - msgBoxHeight) / 2; + tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + msgBoxHeight; + setRelativePosition(tmp); + + // add buttons + + s32 countButtons = 0; + if (Flags & EMBF_OK) + ++countButtons; + if (Flags & EMBF_CANCEL) + ++countButtons; + if (Flags & EMBF_YES) + ++countButtons; + if (Flags & EMBF_NO) + ++countButtons; + + core::rect btnRect; + btnRect.UpperLeftCorner.Y = pos.Y + dim.Height + buttonHeight / 2; + btnRect.LowerRightCorner.Y = btnRect.UpperLeftCorner.Y + buttonHeight; + btnRect.UpperLeftCorner.X = (AbsoluteClippingRect.getWidth() - + ((buttonWidth + buttonDistance)*countButtons)) / 2; + btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + buttonWidth; + + // add/remove ok button + if (Flags & EMBF_OK) + { + if (!OkButton) + { + OkButton = Environment->addButton(btnRect, this); + OkButton->setSubElement(true); + OkButton->grab(); + } + else + OkButton->setRelativePosition(btnRect); + + OkButton->setText(skin->getDefaultText(EGDT_MSG_BOX_OK)); + + btnRect.LowerRightCorner.X += buttonWidth + buttonDistance; + btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance; + + focusMe = OkButton; + } + else if (OkButton) + { + OkButton->drop(); + OkButton->remove(); + OkButton = 0; + } + + // add cancel button + if (Flags & EMBF_CANCEL) + { + if (!CancelButton) + { + CancelButton = Environment->addButton(btnRect, this); + CancelButton->setSubElement(true); + CancelButton->grab(); + } + else + CancelButton->setRelativePosition(btnRect); + + CancelButton->setText(skin->getDefaultText(EGDT_MSG_BOX_CANCEL)); + + btnRect.LowerRightCorner.X += buttonWidth + buttonDistance; + btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance; + + if (!focusMe) + focusMe = CancelButton; + + } + else if (CancelButton) + { + CancelButton->drop(); + CancelButton->remove(); + CancelButton = 0; + } + + + // add/remove yes button + if (Flags & EMBF_YES) + { + if (!YesButton) + { + YesButton = Environment->addButton(btnRect, this); + YesButton->setSubElement(true); + YesButton->grab(); + } + else + YesButton->setRelativePosition(btnRect); + + YesButton->setText(skin->getDefaultText(EGDT_MSG_BOX_YES)); + + btnRect.LowerRightCorner.X += buttonWidth + buttonDistance; + btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance; + + if (!focusMe) + focusMe = YesButton; + } + else if (YesButton) + { + YesButton->drop(); + YesButton->remove(); + YesButton = 0; + } + + // add no button + if (Flags & EMBF_NO) + { + if (!NoButton) + { + NoButton = Environment->addButton(btnRect, this); + NoButton->setSubElement(true); + NoButton->grab(); + } + else + NoButton->setRelativePosition(btnRect); + + NoButton->setText(skin->getDefaultText(EGDT_MSG_BOX_NO)); + + btnRect.LowerRightCorner.X += buttonWidth + buttonDistance; + btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance; + + if (!focusMe) + focusMe = NoButton; + + } + else if (NoButton) + { + NoButton->drop(); + NoButton->remove(); + NoButton = 0; + } + + if (Environment->hasFocus(this) && focusMe) + Environment->setFocus(focusMe); +} + + +//! called if an event happened. +bool CGUIMessageBox::OnEvent(const SEvent& event) +{ + SEvent outevent; + outevent.EventType = EET_GUI_EVENT; + outevent.GUIEvent.Caller = this; + outevent.GUIEvent.Element = 0; + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + + if (event.KeyInput.PressedDown) + { + switch (event.KeyInput.Key) + { + case KEY_RETURN: + if (OkButton) + { + OkButton->setPressed(true); + Pressed = true; + } + break; + case KEY_KEY_Y: + if (YesButton) + { + YesButton->setPressed(true); + Pressed = true; + } + break; + case KEY_KEY_N: + if (NoButton) + { + NoButton->setPressed(true); + Pressed = true; + } + break; + case KEY_ESCAPE: + if (Pressed) + { + // cancel press + if (OkButton) OkButton->setPressed(false); + if (YesButton) OkButton->setPressed(false); + if (NoButton) OkButton->setPressed(false); + Pressed = false; + } + else + if (CancelButton) + { + CancelButton->setPressed(true); + Pressed = true; + } + else + if (CloseButton && CloseButton->isVisible()) + { + CloseButton->setPressed(true); + Pressed = true; + } + break; + default: // no other key is handled here + break; + } + } + else + if (Pressed) + { + if (OkButton && event.KeyInput.Key == KEY_RETURN) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if ((CancelButton || CloseButton) && event.KeyInput.Key == KEY_ESCAPE) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (YesButton && event.KeyInput.Key == KEY_KEY_Y) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (NoButton && event.KeyInput.Key == KEY_KEY_N) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO; + Parent->OnEvent(outevent); + remove(); + return true; + } + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == OkButton) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == CancelButton || + event.GUIEvent.Caller == CloseButton) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == YesButton) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == NoButton) + { + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO; + Parent->OnEvent(outevent); + remove(); + return true; + } + } + break; + default: + break; + } + + return CGUIWindow::OnEvent(event); +} + +//! Writes attributes of the element. +void CGUIMessageBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + CGUIWindow::serializeAttributes(out,options); + + out->addBool ("OkayButton", (Flags & EMBF_OK) != 0 ); + out->addBool ("CancelButton", (Flags & EMBF_CANCEL) != 0 ); + out->addBool ("YesButton", (Flags & EMBF_YES) != 0 ); + out->addBool ("NoButton", (Flags & EMBF_NO) != 0 ); + + out->addString ("MessageText", MessageText.c_str()); +} + +//! Reads attributes of the element +void CGUIMessageBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Flags = 0; + + Flags = in->getAttributeAsBool("OkayButton") ? EMBF_OK : 0; + Flags |= in->getAttributeAsBool("CancelButton")? EMBF_CANCEL : 0; + Flags |= in->getAttributeAsBool("YesButton") ? EMBF_YES : 0; + Flags |= in->getAttributeAsBool("NoButton") ? EMBF_NO : 0; + + MessageText = in->getAttributeAsStringW("MessageText").c_str(); + + CGUIWindow::deserializeAttributes(in,options); + + refreshControls(); +} + + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIMessageBox.h b/src/dep/src/irrlicht/CGUIMessageBox.h new file mode 100644 index 0000000..99154e8 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIMessageBox.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MESSAGE_BOX_H_INCLUDED__ +#define __C_GUI_MESSAGE_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIWindow.h" +#include "IGUIStaticText.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class CGUIMessageBox : public CGUIWindow + { + public: + + //! constructor + CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, + const wchar_t* text, s32 flag, + IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIMessageBox(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void refreshControls(); + + IGUIButton* OkButton; + IGUIButton* CancelButton; + IGUIButton* YesButton; + IGUIButton* NoButton; + IGUIStaticText* StaticText; + + s32 Flags; + core::stringw MessageText; + bool Pressed; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/dep/src/irrlicht/CGUIModalScreen.cpp b/src/dep/src/irrlicht/CGUIModalScreen.cpp new file mode 100644 index 0000000..cb64baa --- /dev/null +++ b/src/dep/src/irrlicht/CGUIModalScreen.cpp @@ -0,0 +1,160 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIModalScreen.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "os.h" +#include "IVideoDriver.h" +#include "IGUISkin.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIModalScreen::CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* parent, s32 id) +: IGUIElement(EGUIET_MODAL_SCREEN, environment, parent, id, parent->getAbsolutePosition()), + MouseDownTime(0) +{ + #ifdef _DEBUG + setDebugName("CGUIModalScreen"); + #endif + setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + + // this element is a tab group + setTabGroup(true); +} + + +//! called if an event happened. +bool CGUIModalScreen::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUSED: + // only children are allowed the focus + if (event.GUIEvent.Caller != this && !isMyChild(event.GUIEvent.Caller)) + Environment->setFocus(this); + return false; + case EGET_ELEMENT_FOCUS_LOST: + // only children are allowed the focus + if (!(isMyChild(event.GUIEvent.Element) || event.GUIEvent.Element == this)) + { + MouseDownTime = os::Timer::getTime(); + return true; + } + else + { + return IGUIElement::OnEvent(event); + } + case EGET_ELEMENT_CLOSED: + // do not interfere with children being removed + return IGUIElement::OnEvent(event); + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + MouseDownTime = os::Timer::getTime(); + } + default: + break; + } + + IGUIElement::OnEvent(event); + + return true; // absorb everything else +} + + +//! draws the element and its children +void CGUIModalScreen::draw() +{ + IGUISkin *skin = Environment->getSkin(); + + if (!skin) + return; + + u32 now = os::Timer::getTime(); + if (now - MouseDownTime < 300 && (now / 70)%2) + { + core::list::Iterator it = Children.begin(); + core::rect r; + video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT); + + for (; it != Children.end(); ++it) + { + r = (*it)->getAbsolutePosition(); + r.LowerRightCorner.X += 1; + r.LowerRightCorner.Y += 1; + r.UpperLeftCorner.X -= 1; + r.UpperLeftCorner.Y -= 1; + + skin->draw2DRectangle(this, c, r, &AbsoluteClippingRect); + } + } + + IGUIElement::draw(); +} + + + +//! Removes a child. +void CGUIModalScreen::removeChild(IGUIElement* child) +{ + IGUIElement::removeChild(child); + + if (Children.empty()) + remove(); +} + +//! adds a child +void CGUIModalScreen::addChild(IGUIElement* child) +{ + IGUIElement::addChild(child); + Environment->setFocus(child); +} + + +void CGUIModalScreen::updateAbsolutePosition() +{ + core::rect parentRect(0,0,0,0); + + if (Parent) + { + parentRect = Parent->getAbsolutePosition(); + RelativeRect.UpperLeftCorner.X = 0; + RelativeRect.UpperLeftCorner.Y = 0; + RelativeRect.LowerRightCorner.X = parentRect.getWidth(); + RelativeRect.LowerRightCorner.Y = parentRect.getHeight(); + } + + IGUIElement::updateAbsolutePosition(); +} + +//! Writes attributes of the element. +void CGUIModalScreen::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + // these don't get serialized, their status is added to their children. +} + +//! Reads attributes of the element +void CGUIModalScreen::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + // these don't get deserialized. children create them if required +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/dep/src/irrlicht/CGUIModalScreen.h b/src/dep/src/irrlicht/CGUIModalScreen.h new file mode 100644 index 0000000..3ef7df6 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIModalScreen.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MODAL_SCREEN_H_INCLUDED__ +#define __C_GUI_MODAL_SCREEN_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + class CGUIModalScreen : public IGUIElement + { + public: + + //! constructor + CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* parent, s32 id); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Removes a child. + virtual void removeChild(IGUIElement* child); + + //! Adds a child + virtual void addChild(IGUIElement* child); + + + //! draws the element and its children + virtual void draw(); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + u32 MouseDownTime; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/dep/src/irrlicht/CGUIScrollBar.cpp b/src/dep/src/irrlicht/CGUIScrollBar.cpp new file mode 100644 index 0000000..7017701 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIScrollBar.cpp @@ -0,0 +1,528 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIScrollBar.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "CGUIButton.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, + core::rect rectangle, bool noclip) + : IGUIScrollBar(environment, parent, id, rectangle), UpButton(0), + DownButton(0), Dragging(false), Horizontal(horizontal), + DraggedBySlider(false), TrayClick(false), Pos(0), DrawPos(0), + DrawHeight(0), Max(100), SmallStep(10), LargeStep(50), DesiredPos(0), + LastChange(0) +{ + #ifdef _DEBUG + setDebugName("CGUIScrollBar"); + #endif + + refreshControls(); + + setNotClipped(noclip); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + setPos(0); +} + + +//! destructor +CGUIScrollBar::~CGUIScrollBar() +{ + if (UpButton) + UpButton->drop(); + + if (DownButton) + DownButton->drop(); +} + + +//! called if an event happened. +bool CGUIScrollBar::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown) + { + const s32 oldPos = Pos; + bool absorb = true; + switch (event.KeyInput.Key) + { + case KEY_LEFT: + case KEY_UP: + setPos(Pos-SmallStep); + break; + case KEY_RIGHT: + case KEY_DOWN: + setPos(Pos+SmallStep); + break; + case KEY_HOME: + setPos(0); + break; + case KEY_PRIOR: + setPos(Pos-LargeStep); + break; + case KEY_END: + setPos(Max); + break; + case KEY_NEXT: + setPos(Pos+LargeStep); + break; + default: + absorb = false; + } + + if (Pos != oldPos) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + if (absorb) + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == UpButton) + setPos(Pos-SmallStep); + else + if (event.GUIEvent.Caller == DownButton) + setPos(Pos+SmallStep); + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + + return true; + } + else + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + Dragging = false; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + if (Environment->hasFocus(this)) + { // thanks to a bug report by REAPER + setPos(getPos() + (s32)event.MouseInput.Wheel* -SmallStep); + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + return true; + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: + { + if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y))) + { + Dragging = true; + DraggedBySlider = SliderRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y)); + TrayClick = !DraggedBySlider; + DesiredPos = getPosFromMousePos(event.MouseInput.X, event.MouseInput.Y); + return true; + } + break; + } + case EMIE_LMOUSE_LEFT_UP: + case EMIE_MOUSE_MOVED: + if (Dragging) + { + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + Dragging = false; + + const s32 newPos = getPosFromMousePos(event.MouseInput.X, event.MouseInput.Y); + const s32 oldPos = Pos; + + if (!DraggedBySlider) + { + if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y))) + { + DraggedBySlider = SliderRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y)); + TrayClick = !DraggedBySlider; + } + else + { + TrayClick = false; + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + return true; + } + } + + if (DraggedBySlider) + { + setPos(newPos); + } + else + { + DesiredPos = newPos; + } + + if (Pos != oldPos && Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + default: + break; + } + break; + default: + break; + } + + return IGUIElement::OnEvent(event); +} + +//! draws the element and its children +void CGUIScrollBar::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + u32 now = os::Timer::getRealTime(); + + if (Dragging && !DraggedBySlider && TrayClick && now > LastChange + 200) + { + LastChange = now; + + const s32 oldPos = Pos; + + if (DesiredPos >= Pos + LargeStep) + setPos(Pos + LargeStep); + else + if (DesiredPos <= Pos - LargeStep) + setPos(Pos - LargeStep); + else + if (DesiredPos >= Pos - LargeStep && DesiredPos <= Pos + LargeStep) + setPos(DesiredPos); + + if (Pos != oldPos && Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + } + + SliderRect = AbsoluteRect; + + // draws the background + skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), SliderRect, &AbsoluteClippingRect); + + if (Max!=0) + { + // recalculate slider rectangle + if (Horizontal) + { + SliderRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + DrawPos + RelativeRect.getHeight() - DrawHeight/2; + SliderRect.LowerRightCorner.X = SliderRect.UpperLeftCorner.X + DrawHeight; + } + else + { + SliderRect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + DrawPos + RelativeRect.getWidth() - DrawHeight/2; + SliderRect.LowerRightCorner.Y = SliderRect.UpperLeftCorner.Y + DrawHeight; + } + + skin->draw3DButtonPaneStandard(this, SliderRect, &AbsoluteClippingRect); + } + + // draw buttons + IGUIElement::draw(); +} + +void CGUIScrollBar::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + // todo: properly resize + refreshControls(); + + if (Horizontal) + { + const f32 f = (RelativeRect.getWidth() - ((f32)RelativeRect.getHeight()*3.0f)) / (f32)Max; + DrawPos = (s32)((Pos * f) + ((f32)RelativeRect.getHeight() * 0.5f)); + DrawHeight = RelativeRect.getHeight(); + } + else + { + f32 f = 0.0f; + if (Max != 0) + f = (RelativeRect.getHeight() - ((f32)RelativeRect.getWidth()*3.0f)) / (f32)Max; + + DrawPos = (s32)((Pos * f) + ((f32)RelativeRect.getWidth() * 0.5f)); + DrawHeight = RelativeRect.getWidth(); + } +} + +s32 CGUIScrollBar::getPosFromMousePos(s32 x, s32 y) const +{ + if (Horizontal) + { + const f32 w = RelativeRect.getWidth() - f32(RelativeRect.getHeight())*3.0f; + const f32 p = x - AbsoluteRect.UpperLeftCorner.X - RelativeRect.getHeight()*1.5f; + return s32( p/w * f32(Max) ); + } + else + { + const f32 h = RelativeRect.getHeight() - f32(RelativeRect.getWidth())*3.0f; + const f32 p = y - AbsoluteRect.UpperLeftCorner.Y - RelativeRect.getWidth()*1.5f; + return s32( p/h * f32(Max) ); + } +} + + + +//! sets the position of the scrollbar +void CGUIScrollBar::setPos(s32 pos) +{ + if (pos < 0) + Pos = 0; + else if (pos > Max) + Pos = Max; + else + Pos = pos; + + if (Horizontal) + { + const f32 f = (RelativeRect.getWidth() - ((f32)RelativeRect.getHeight()*3.0f)) / (f32)Max; + DrawPos = (s32)((Pos * f) + ((f32)RelativeRect.getHeight() * 0.5f)); + DrawHeight = RelativeRect.getHeight(); + } + else + { + f32 f = 0.0f; + if (Max != 0) + f = (RelativeRect.getHeight() - ((f32)RelativeRect.getWidth()*3.0f)) / (f32)Max; + + DrawPos = (s32)((Pos * f) + ((f32)RelativeRect.getWidth() * 0.5f)); + DrawHeight = RelativeRect.getWidth(); + } +} + + +//! gets the small step value +s32 CGUIScrollBar::getSmallStep() const +{ + return SmallStep; +} + + +//! sets the small step value +void CGUIScrollBar::setSmallStep(s32 step) +{ + if (step > 0) + SmallStep = step; + else + SmallStep = 10; +} + +//! gets the small step value +s32 CGUIScrollBar::getLargeStep() const +{ + return LargeStep; +} + + +//! sets the small step value +void CGUIScrollBar::setLargeStep(s32 step) +{ + if (step > 0) + LargeStep = step; + else + LargeStep = 50; +} + + + +//! gets the maximum value of the scrollbar. +s32 CGUIScrollBar::getMax() const +{ + return Max; +} + + +//! sets the maximum value of the scrollbar. +void CGUIScrollBar::setMax(s32 max) +{ + if (max > 0) + Max = max; + else + Max = 0; + + bool enable = (Max != 0); + UpButton->setEnabled(enable); + DownButton->setEnabled(enable); + setPos(Pos); +} + + +//! gets the current position of the scrollbar +s32 CGUIScrollBar::getPos() const +{ + return Pos; +} + + +//! refreshes the position and text on child buttons +void CGUIScrollBar::refreshControls() +{ + video::SColor color(255,255,255,255); + + IGUISkin* skin = Environment->getSkin(); + IGUISpriteBank* sprites = 0; + + if (skin) + { + sprites = skin->getSpriteBank(); + color = skin->getColor(EGDC_WINDOW_SYMBOL); + } + + if (Horizontal) + { + s32 h = RelativeRect.getHeight(); + if (!UpButton) + { + UpButton = new CGUIButton(Environment, this, -1, core::rect(0,0, h, h), NoClip); + UpButton->setSubElement(true); + UpButton->setTabStop(false); + } + if (sprites) + { + UpButton->setSpriteBank(sprites); + UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), color); + UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), color); + } + UpButton->setRelativePosition(core::rect(0,0, h, h)); + UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + if (!DownButton) + { + DownButton = new CGUIButton(Environment, this, -1, core::rect(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip); + DownButton->setSubElement(true); + DownButton->setTabStop(false); + } + if (sprites) + { + DownButton->setSpriteBank(sprites); + DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), color); + DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), color); + } + DownButton->setRelativePosition(core::rect(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h)); + DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + } + else + { + s32 w = RelativeRect.getWidth(); + if (!UpButton) + { + UpButton = new CGUIButton(Environment, this, -1, core::rect(0,0, w, w), NoClip); + UpButton->setSubElement(true); + UpButton->setTabStop(false); + } + if (sprites) + { + UpButton->setSpriteBank(sprites); + UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_UP), color); + UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_UP), color); + } + UpButton->setRelativePosition(core::rect(0,0, w, w)); + UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (!DownButton) + { + DownButton = new CGUIButton(Environment, this, -1, core::rect(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip); + DownButton->setSubElement(true); + DownButton->setTabStop(false); + } + if (sprites) + { + DownButton->setSpriteBank(sprites); + DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), color); + DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), color); + } + DownButton->setRelativePosition(core::rect(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight())); + DownButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + } +} + + +//! Writes attributes of the element. +void CGUIScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIScrollBar::serializeAttributes(out,options); + + out->addBool("Horizontal", Horizontal); + out->addInt ("Value", Pos); + out->addInt ("Max", Max); + out->addInt ("SmallStep", SmallStep); + out->addInt ("LargeStep", LargeStep); +} + + +//! Reads attributes of the element +void CGUIScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIScrollBar::deserializeAttributes(in,options); + + Horizontal = in->getAttributeAsBool("Horizontal"); + setMax(in->getAttributeAsInt("Max")); + setPos(in->getAttributeAsInt("Value")); + setSmallStep(in->getAttributeAsInt("SmallStep")); + setLargeStep(in->getAttributeAsInt("LargeStep")); + NoClip = in->getAttributeAsBool("NoClip"); + + refreshControls(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIScrollBar.h b/src/dep/src/irrlicht/CGUIScrollBar.h new file mode 100644 index 0000000..6ec7baf --- /dev/null +++ b/src/dep/src/irrlicht/CGUIScrollBar.h @@ -0,0 +1,100 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SCROLL_BAR_H_INCLUDED__ +#define __C_GUI_SCROLL_BAR_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIScrollBar.h" +#include "IGUIButton.h" + +namespace irr +{ +namespace gui +{ + + class CGUIScrollBar : public IGUIScrollBar + { + public: + + //! constructor + CGUIScrollBar(bool horizontal, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, core::rect rectangle, + bool noclip=false); + + //! destructor + virtual ~CGUIScrollBar(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! gets the maximum value of the scrollbar. + virtual s32 getMax() const; + + //! sets the maximum value of the scrollbar. + virtual void setMax(s32 max); + + //! gets the small step value + virtual s32 getSmallStep() const; + + //! sets the small step value + virtual void setSmallStep(s32 step); + + //! gets the large step value + virtual s32 getLargeStep() const; + + //! sets the large step value + virtual void setLargeStep(s32 step); + + //! gets the current position of the scrollbar + virtual s32 getPos() const; + + //! sets the position of the scrollbar + virtual void setPos(s32 pos); + + //! updates the rectangle + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void refreshControls(); + s32 getPosFromMousePos(s32 x, s32 y) const; + + IGUIButton* UpButton; + IGUIButton* DownButton; + + core::rect SliderRect; + + bool Dragging; + bool Horizontal; + bool DraggedBySlider; + bool TrayClick; + s32 Pos; + s32 DrawPos; + s32 DrawHeight; + s32 Max; + s32 SmallStep; + s32 LargeStep; + s32 DesiredPos; + u32 LastChange; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGUISkin.cpp b/src/dep/src/irrlicht/CGUISkin.cpp new file mode 100644 index 0000000..f69f664 --- /dev/null +++ b/src/dep/src/irrlicht/CGUISkin.cpp @@ -0,0 +1,858 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUISkin.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "IVideoDriver.h" +#include "IAttributes.h" +#include "SoftwareDriver2_helper.h" + +namespace irr +{ +namespace gui +{ + +CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver) +: SpriteBank(0), Driver(driver), Type(type) +{ + #ifdef _DEBUG + setDebugName("CGUISkin"); + #endif + + if ( (Type == EGST_WINDOWS_CLASSIC) | + (Type == EGST_WINDOWS_METALLIC) + ) + { + Colors[EGDC_3D_DARK_SHADOW] = video::SColor(101,50,50,50); + Colors[EGDC_3D_SHADOW] = video::SColor(101,130,130,130); + Colors[EGDC_3D_FACE] = video::SColor(101,210,210,210); + Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255); + Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210); + Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115); + Colors[EGDC_ACTIVE_CAPTION] = video::SColor(200,255,255,255); + Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100); + Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10); + Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130); + Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107); + Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255); + Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165); + Colors[EGDC_INACTIVE_CAPTION] = video::SColor(101,210,210,210); + Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0); + Colors[EGDC_TOOLTIP_BACKGROUND]= video::SColor(200,255,255,225); + Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230); + Colors[EGDC_WINDOW] = video::SColor(101,255,255,255); + Colors[EGDC_WINDOW_SYMBOL] = video::SColor(200,10,10,10); + Colors[EGDC_ICON] = video::SColor(200,255,255,255); + Colors[EGDC_ICON_HIGH_LIGHT] = video::SColor(200,8,36,107); + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 30; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 2; + Sizes[EGDS_TEXT_DISTANCE_Y] = 0; + } + else + { + //0x80a6a8af + Colors[EGDC_3D_DARK_SHADOW] = 0x60767982; + //Colors[EGDC_3D_FACE] = 0xc0c9ccd4; // tab background + Colors[EGDC_3D_FACE] = 0xc0cbd2d9; // tab background + Colors[EGDC_3D_SHADOW] = 0x50e4e8f1; // tab background, and left-top highlight + Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc; + Colors[EGDC_3D_LIGHT] = 0x802e313a; + Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title + Colors[EGDC_ACTIVE_CAPTION] = 0xf0d0d0d0; + Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused + Colors[EGDC_BUTTON_TEXT] = 0xd0161616; + Colors[EGDC_GRAY_TEXT] = 0x3c141414; + Colors[EGDC_HIGH_LIGHT] = 0x6c606060; + Colors[EGDC_HIGH_LIGHT_TEXT]= 0xd0e0e0e0; + Colors[EGDC_INACTIVE_BORDER]= 0xf0a5a5a5; + Colors[EGDC_INACTIVE_CAPTION]= 0xf0d2d2d2; + Colors[EGDC_TOOLTIP] = 0xf00f2033; + Colors[EGDC_TOOLTIP_BACKGROUND]=0xc0cbd2d9; + Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0; + Colors[EGDC_WINDOW] = 0xf0f0f0f0; + Colors[EGDC_WINDOW_SYMBOL] = 0xd0161616; + Colors[EGDC_ICON] = 0xd0161616; + Colors[EGDC_ICON_HIGH_LIGHT]= 0xd0606060; + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 48; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 3; + Sizes[EGDS_TEXT_DISTANCE_Y] = 2; + } + + Texts[EGDT_MSG_BOX_OK] = L"OK"; + Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel"; + Texts[EGDT_MSG_BOX_YES] = L"Yes"; + Texts[EGDT_MSG_BOX_NO] = L"No"; + Texts[EGDT_WINDOW_CLOSE] = L"Close"; + Texts[EGDT_WINDOW_RESTORE] = L"Restore"; + Texts[EGDT_WINDOW_MINIMIZE] = L"Minimize"; + Texts[EGDT_WINDOW_MAXIMIZE] = L"Maximize"; + + Icons[EGDI_WINDOW_MAXIMIZE] = 225; + Icons[EGDI_WINDOW_RESTORE] = 226; + Icons[EGDI_WINDOW_CLOSE] = 227; + Icons[EGDI_WINDOW_MINIMIZE] = 228; + Icons[EGDI_CURSOR_UP] = 229; + Icons[EGDI_CURSOR_DOWN] = 230; + Icons[EGDI_CURSOR_LEFT] = 231; + Icons[EGDI_CURSOR_RIGHT] = 232; + Icons[EGDI_MENU_MORE] = 232; + Icons[EGDI_CHECK_BOX_CHECKED] = 233; + Icons[EGDI_DROP_DOWN] = 234; + Icons[EGDI_SMALL_CURSOR_UP] = 235; + Icons[EGDI_SMALL_CURSOR_DOWN] = 236; + Icons[EGDI_RADIO_BUTTON_CHECKED] = 237; + Icons[EGDI_MORE_LEFT] = 238; + Icons[EGDI_MORE_RIGHT] = 239; + Icons[EGDI_MORE_UP] = 240; + Icons[EGDI_MORE_DOWN] = 241; + Icons[EGDI_WINDOW_RESIZE] = 242; + Icons[EGDI_EXPAND] = 243; + Icons[EGDI_COLLAPSE] = 244; + + Icons[EGDI_FILE] = 245; + Icons[EGDI_DIRECTORY] = 246; + + for (u32 i=0; idrop(); + } + + if (SpriteBank) + SpriteBank->drop(); +} + + + +//! returns default color +video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const +{ + if ((u32)color < EGDC_COUNT) + return Colors[color]; + else + return video::SColor(); +} + + +//! sets a default color +void CGUISkin::setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) +{ + if ((u32)which < EGDC_COUNT) + Colors[which] = newColor; +} + + +//! returns size for the given size type +s32 CGUISkin::getSize(EGUI_DEFAULT_SIZE size) const +{ + if ((u32)size < EGDS_COUNT) + return Sizes[size]; + else + return 0; +} + + +//! sets a default size +void CGUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size) +{ + if ((u32)which < EGDS_COUNT) + Sizes[which] = size; +} + + + +//! returns the default font +IGUIFont* CGUISkin::getFont(EGUI_DEFAULT_FONT which) const +{ + if (((u32)which < EGDS_COUNT) && Fonts[which]) + return Fonts[which]; + else + return Fonts[EGDF_DEFAULT]; +} + +//! sets a default font +void CGUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which) +{ + if ((u32)which >= EGDS_COUNT) + return; + + if (Fonts[which]) + Fonts[which]->drop(); + + Fonts[which] = font; + + if (Fonts[which]) + Fonts[which]->grab(); +} + + +//! gets the sprite bank stored +IGUISpriteBank* CGUISkin::getSpriteBank() const +{ + return SpriteBank; +} + + +//! set a new sprite bank or remove one by passing 0 +void CGUISkin::setSpriteBank(IGUISpriteBank* bank) +{ + if (SpriteBank) + SpriteBank->drop(); + + if (bank) + bank->grab(); + + SpriteBank = bank; +} + + +//! Returns a default icon +u32 CGUISkin::getIcon(EGUI_DEFAULT_ICON icon) const +{ + if ((u32)icon < EGDI_COUNT) + return Icons[icon]; + else + return 0; +} + +//! Sets a default icon +void CGUISkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index) +{ + if ((u32)icon < EGDI_COUNT) + Icons[icon] = index; +} + +//! Returns a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +const wchar_t* CGUISkin::getDefaultText(EGUI_DEFAULT_TEXT text) const +{ + if ((u32)text < EGDT_COUNT) + return Texts[text].c_str(); + else + return Texts[0].c_str(); +} + + +//! Sets a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +void CGUISkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) +{ + if ((u32)which < EGDT_COUNT) + Texts[which] = newText; +} + +//! draws a standard 3d button pane +/** Used for drawing for example buttons in normal state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +void CGUISkin::draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.X += 1; + rect.LowerRightCorner.Y += 1; + draw3DSunkenPane(element, + getColor( EGDC_WINDOW ).getInterpolated( 0xFFFFFFFF, 0.9f ) + ,false, true, rect, clip); + return; + } + + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a pressed 3d button pane +/** Used for drawing for example buttons in pressed state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +void CGUISkin::draw3DButtonPanePressed(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a sunken 3d pane +/** Used for drawing the background of edit, combo or check boxes. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param bgcolor: Background color. +\param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DSunkenPane(IGUIElement* element, video::SColor bgcolor, + bool flat, bool fillBackGround, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if (flat) + { + // draw flat sunken pane + if (fillBackGround) + Driver->draw2DRectangle(bgcolor, rect, clip); + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect = r; + rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect = r; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + } + else + { + // draw deep sunken pane + if (fillBackGround) + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_LIGHT), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(bgcolor, rect, clip); + } +} + + +//! draws a window background +/** Used for drawing the background of dialogs and windows. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param titleBarColor: Title color. +\param drawTitleBar: True to enable title drawing. +\param rect: Defining area where to draw. +\param clip: Clip area. +\return Returns rect where to draw title bar text. */ +core::rect CGUISkin::draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect& r, + const core::rect* cl) +{ + if (!Driver) + return r; + + core::rect rect = r; + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, cl); + + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, cl); + + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, cl); + + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, cl); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, cl); + + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, cl); + + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, cl); + } + else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.9f ); + const video::SColor c2 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.8f ); + + Driver->draw2DRectangle(rect, c1, c1, c2, c2, cl); + } + else + { + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + const video::SColor c1 = getColor(EGDC_3D_FACE); + Driver->draw2DRectangle(rect, c1, c1, c1, c2, cl); + } + + rect = r; + rect.UpperLeftCorner.X += 2; + rect.UpperLeftCorner.Y += 2; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + getSize(EGDS_WINDOW_BUTTON_WIDTH) + 2; + + if (drawTitleBar) + { + // draw title bar + //if (!UseGradient) + // Driver->draw2DRectangle(titleBarColor, rect, cl); + //else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c = titleBarColor.getInterpolated( 0xffffffff, 0.8f); + Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, cl); + } + else + { + const video::SColor c = titleBarColor.getInterpolated(video::SColor(255,0,0,0), 0.2f); + Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, cl); + } + } + + return rect; +} + + +//! draws a standard 3d menu pane +/** Used for drawing for menus and context menus. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DMenuPane(IGUIElement* element, + const core::rect& r, const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.Y -= 3; + draw3DButtonPaneStandard(element, rect, clip); + return; + } + + // in this skin, this is exactly what non pressed buttons look like, + // so we could simply call + // draw3DButtonPaneStandard(element, rect, clip); + // here. + // but if the skin is transparent, this doesn't look that nice. So + // We draw it a little bit better, with some more draw2DRectangle calls, + // but there aren't that much menus visible anyway. + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + + if (!UseGradient) + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a standard 3d tool bar +/** Used for drawing for toolbars and menus. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DToolBar(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect = r; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = 0xF0000000 | getColor(EGDC_3D_FACE).color; + const video::SColor c2 = 0xF0000000 | getColor(EGDC_3D_SHADOW).color; + + rect.LowerRightCorner.Y += 1; + Driver->draw2DRectangle(rect, c1, c2, c1, c2, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a tab button +/** Used for drawing for tab buttons on top of tabs. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param active: Specifies if the tab is currently active. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DTabButton(IGUIElement* element, bool active, + const core::rect& frameRect, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect tr = frameRect; + + tr.LowerRightCorner.X -= 2; + tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1; + tr.UpperLeftCorner.X += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw left highlight + tr = frameRect; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw grey background + tr = frameRect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + tr.LowerRightCorner.X -= 2; + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip); + + // draw right middle gray shadow + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), tr, clip); +} + + +//! draws a tab control body +/** \param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param border: Specifies if the border should be drawn. +\param background: Specifies if the background should be drawn. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip) +{ + if (!Driver) + return; + + core::rect tr = rect; + + // draw border. + if (border) + { + // draw left hightlight + tr.UpperLeftCorner.Y += getSize(gui::EGDS_BUTTON_HEIGHT) + 2; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw right shadow + tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + // draw lower shadow + tr = rect; + tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + } + + if (background) + { + tr = rect; + tr.UpperLeftCorner.Y += getSize(gui::EGDS_BUTTON_HEIGHT) + 2; + tr.LowerRightCorner.X -= 1; + tr.UpperLeftCorner.X += 1; + tr.LowerRightCorner.Y -= 1; + + if (!UseGradient) + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip); + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(tr, c1, c1, c2, c2, clip); + } + } +} + + +//! draws an icon, usually from the skin's sprite bank +/** \param parent: Pointer to the element which wishes to draw this icon. +This parameter is usually not used by IGUISkin, but can be used for example +by more complex implementations to find out how to draw the part exactly. +\param icon: Specifies the icon to be drawn. +\param position: The position to draw the icon +\param starttime: The time at the start of the animation +\param currenttime: The present time, used to calculate the frame number +\param loop: Whether the animation should loop or not +\param clip: Clip area. */ +void CGUISkin::drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime, u32 currenttime, + bool loop, const core::rect* clip) +{ + if (!SpriteBank) + return; + + SpriteBank->draw2DSprite(Icons[icon], position, clip, + video::SColor(255,0,0,0), starttime, currenttime, loop, true); +} + + +EGUI_SKIN_TYPE CGUISkin::getType() const +{ + return Type; +} + + +//! draws a 2d rectangle. +void CGUISkin::draw2DRectangle(IGUIElement* element, + const video::SColor &color, const core::rect& pos, + const core::rect* clip) +{ + Driver->draw2DRectangle(color, pos, clip); +} + + +//! Writes attributes of the object. +//! Implement this to expose the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml serialization purposes. +void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + u32 i; + for (i=0; iaddColor(GUISkinColorNames[i], Colors[i]); + + for (i=0; iaddInt(GUISkinSizeNames[i], Sizes[i]); + + for (i=0; iaddString(GUISkinTextNames[i], Texts[i].c_str()); + + for (i=0; iaddInt(GUISkinIconNames[i], Icons[i]); +} + + +//! Reads attributes of the object. +//! Implement this to set the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml deserialization purposes. +void CGUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + u32 i; + for (i=0; igetAttributeAsColor(GUISkinColorNames[i]); + + for (i=0; igetAttributeAsInt(GUISkinSizeNames[i]); + + for (i=0; igetAttributeAsStringW(GUISkinTextNames[i]); + + for (i=0; igetAttributeAsInt(GUISkinIconNames[i]); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUISkin.h b/src/dep/src/irrlicht/CGUISkin.h new file mode 100644 index 0000000..7a6b955 --- /dev/null +++ b/src/dep/src/irrlicht/CGUISkin.h @@ -0,0 +1,246 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SKIN_H_INCLUDED__ +#define __C_GUI_SKIN_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; +} +namespace gui +{ + + class CGUISkin : public IGUISkin + { + public: + + CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver); + + //! destructor + virtual ~CGUISkin(); + + //! returns default color + virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const; + + //! sets a default color + virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor); + + //! returns size for the given size type + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const; + + //! sets a default size + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size); + + //! returns the default font + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const; + + //! sets a default font + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT); + + //! sets the sprite bank used for drawing icons + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! gets the sprite bank used for drawing icons + virtual IGUISpriteBank* getSpriteBank() const; + + //! Returns a default icon + /** Returns the sprite index within the sprite bank */ + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const; + + //! Sets a default icon + /** Sets the sprite index used for drawing icons like arrows, + close buttons and ticks in checkboxes + \param icon: Enum specifying which icon to change + \param index: The sprite index used to draw this icon */ + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index); + + //! Returns a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const; + + //! Sets a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText); + + //! draws a standard 3d button pane + /** Used for drawing for example buttons in normal state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a pressed 3d button pane + /** Used for drawing for example buttons in pressed state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a sunken 3d pane + /** Used for drawing the background of edit, combo or check boxes. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param bgcolor: Background color. + \param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, + bool fillBackGround, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a window background + /** Used for drawing the background of dialogs and windows. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param titleBarColor: Title color. + \param drawTitleBar: True to enable title drawing. + \param rect: Defining area where to draw. + \param clip: Clip area. + \return Returns rect where to draw title bar text. */ + virtual core::rect draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a standard 3d menu pane + /** Used for drawing for menus and context menus. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a standard 3d tool bar + /** Used for drawing for toolbars and menus. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DToolBar(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a tab button + /** Used for drawing for tab buttons on top of tabs. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param active: Specifies if the tab is currently active. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a tab control body + /** \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param border: Specifies if the border should be drawn. + \param background: Specifies if the background should be drawn. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabBody(IGUIElement* element, bool border, + bool background, + const core::rect& rect, + const core::rect* clip=0); + + //! draws an icon, usually from the skin's sprite bank + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param icon: Specifies the icon to be drawn. + \param position: The position to draw the icon + \param starttime: The time at the start of the animation + \param currenttime: The present time, used to calculate the frame number + \param loop: Whether the animation should loop or not + \param clip: Clip area. */ + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect* clip=0); + + + //! draws a 2d rectangle. + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param color: Color of the rectangle to draw. The alpha component specifies how + transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color, + const core::rect& pos, const core::rect* clip = 0); + + + //! get the type of this skin + virtual EGUI_SKIN_TYPE getType() const; + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + private: + + video::SColor Colors[EGDC_COUNT]; + s32 Sizes[EGDS_COUNT]; + u32 Icons[EGDI_COUNT]; + IGUIFont* Fonts[EGDF_COUNT]; + IGUISpriteBank* SpriteBank; + core::stringw Texts[EGDT_COUNT]; + video::IVideoDriver* Driver; + bool UseGradient; + + EGUI_SKIN_TYPE Type; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGUISpinBox.cpp b/src/dep/src/irrlicht/CGUISpinBox.cpp new file mode 100644 index 0000000..2748632 --- /dev/null +++ b/src/dep/src/irrlicht/CGUISpinBox.cpp @@ -0,0 +1,269 @@ +// Copyright (C) 2006 Michael Zeilfelder +// This file uses the licence of the Irrlicht Engine. + +#include "CGUISpinBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIEditBox.h" +#include "CGUIButton.h" +#include "IGUIEnvironment.h" +#include "IEventReceiver.h" +#include "fast_atof.h" +#include +#include + + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUISpinBox::CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle) +: IGUISpinBox(environment, parent, id, rectangle), + EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f), + RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"), + DecimalPlaces(-1) +{ + s32 ButtonWidth = 16; + IGUISpriteBank *sb = 0; + if (environment && environment->getSkin()) + { + ButtonWidth = environment->getSkin()->getSize(EGDS_SCROLLBAR_SIZE); + sb = environment->getSkin()->getSpriteBank(); + } + + ButtonSpinDown = Environment->addButton( + core::rect(rectangle.getWidth() - ButtonWidth, rectangle.getHeight()/2 +1, + rectangle.getWidth(), rectangle.getHeight()), this); + ButtonSpinDown->grab(); + ButtonSpinDown->setSubElement(true); + ButtonSpinDown->setTabStop(false); + ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT); + + ButtonSpinUp = Environment->addButton( + core::rect(rectangle.getWidth() - ButtonWidth, 0, + rectangle.getWidth(), rectangle.getHeight()/2), this); + ButtonSpinUp->grab(); + ButtonSpinUp->setSubElement(true); + ButtonSpinUp->setTabStop(false); + ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER); + if (sb) + { + IGUISkin *skin = environment->getSkin(); + ButtonSpinDown->setSpriteBank(sb); + ButtonSpinDown->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + ButtonSpinDown->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + ButtonSpinUp->setSpriteBank(sb); + ButtonSpinUp->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL)); + ButtonSpinUp->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_UP), skin->getColor(EGDC_WINDOW_SYMBOL)); + } + else + { + ButtonSpinDown->setText(L"-"); + ButtonSpinUp->setText(L"+"); + } + + const core::rect rectEdit(0, 0, rectangle.getWidth() - ButtonWidth - 1, rectangle.getHeight()); + EditBox = Environment->addEditBox(text, rectEdit, true, this, -1); + EditBox->grab(); + EditBox->setSubElement(true); + EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); +} + + +//! destructor +CGUISpinBox::~CGUISpinBox() +{ + if (ButtonSpinUp) + ButtonSpinUp->drop(); + if (ButtonSpinDown) + ButtonSpinDown->drop(); + if (EditBox) + EditBox->drop(); +} + + +IGUIEditBox* CGUISpinBox::getEditBox() const +{ + return EditBox; +} + + +void CGUISpinBox::setValue(f32 val) +{ + wchar_t str[100]; + + swprintf(str, 99, FormatString.c_str(), val); + EditBox->setText(str); + verifyValueRange(); +} + + +f32 CGUISpinBox::getValue() const +{ + const wchar_t* val = EditBox->getText(); + if ( !val ) + return 0.f; + core::stringc tmp(val); + return core::fast_atof(tmp.c_str()); +} + + +void CGUISpinBox::setRange(f32 min, f32 max) +{ + RangeMin = min; + RangeMax = max; + verifyValueRange(); +} + + +f32 CGUISpinBox::getMin() const +{ + return RangeMin; +} + + +f32 CGUISpinBox::getMax() const +{ + return RangeMax; +} + + +f32 CGUISpinBox::getStepSize() const +{ + return StepSize; +} + + +void CGUISpinBox::setStepSize(f32 step) +{ + StepSize = step; +} + + +//! Sets the number of decimal places to display. +void CGUISpinBox::setDecimalPlaces(s32 places) +{ + DecimalPlaces = places; + if (places == -1) + FormatString = "%f"; + else + { + FormatString = "%."; + FormatString += places; + FormatString += "f"; + } + setValue(getValue()); +} + + +bool CGUISpinBox::OnEvent(const SEvent& event) +{ + bool changeEvent = false; + switch(event.EventType) + { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == ButtonSpinUp) + { + f32 val = getValue(); + val += StepSize; + setValue(val); + changeEvent = true; + } + else if ( event.GUIEvent.Caller == ButtonSpinDown) + { + f32 val = getValue(); + val -= StepSize; + setValue(val); + changeEvent = true; + } + } + if ( event.GUIEvent.EventType == EGET_EDITBOX_ENTER ) + { + if (event.GUIEvent.Caller == EditBox) + { + verifyValueRange(); + changeEvent = true; + } + } + break; + default: + break; + } + + if ( changeEvent ) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + + e.GUIEvent.EventType = EGET_SPINBOX_CHANGED; + if ( Parent ) + Parent->OnEvent(e); + return true; + } + + return IGUIElement::OnEvent(event); +} + + +void CGUISpinBox::verifyValueRange() +{ + f32 val = getValue(); + if ( val < RangeMin ) + val = RangeMin; + else if ( val > RangeMax ) + val = RangeMax; + else + return; + + setValue(val); +} + + +//! Sets the new caption of the element +void CGUISpinBox::setText(const wchar_t* text) +{ + EditBox->setText(text); + setValue(getValue()); + verifyValueRange(); +} + + +//! Returns caption of this element. +const wchar_t* CGUISpinBox::getText() const +{ + return EditBox->getText(); +} + + +//! Writes attributes of the element. +void CGUISpinBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUIElement::serializeAttributes(out, options); + out->addFloat("Min", getMin()); + out->addFloat("Max", getMax()); + out->addFloat("Step", getStepSize()); + out->addInt("DecimalPlaces", DecimalPlaces); +} + +//! Reads attributes of the element +void CGUISpinBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IGUIElement::deserializeAttributes(in, options); + setRange(in->getAttributeAsFloat("Min"), in->getAttributeAsFloat("Max")); + setStepSize(in->getAttributeAsFloat("Step")); + setDecimalPlaces(in->getAttributeAsInt("DecimalPlaces")); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUISpinBox.h b/src/dep/src/irrlicht/CGUISpinBox.h new file mode 100644 index 0000000..3e8279d --- /dev/null +++ b/src/dep/src/irrlicht/CGUISpinBox.h @@ -0,0 +1,101 @@ +// Copyright (C) 2006 Michael Zeilfelder +// This file uses the licence of the Irrlicht Engine. + +#ifndef __C_GUI_SPIN_BOX_H_INCLUDED__ +#define __C_GUI_SPIN_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISpinBox.h" + +namespace irr +{ +namespace gui +{ + class IGUIEditBox; + class IGUIButton; + + class CGUISpinBox : public IGUISpinBox + { + public: + + //! constructor + CGUISpinBox(const wchar_t* text, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle); + + //! destructor + virtual ~CGUISpinBox(); + + //! Access the edit box used in the spin control + /** \param enable: If set to true, the override color, which can be set + with IGUIEditBox::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual IGUIEditBox* getEditBox() const; + + //! set the current value of the spinbox + /** \param val: value to be set in the spinbox */ + virtual void setValue(f32 val); + + //! Get the current value of the spinbox + virtual f32 getValue() const; + + //! set the range of values which can be used in the spinbox + /** \param min: minimum value + \param max: maximum value */ + virtual void setRange(f32 min, f32 max); + + //! get the minimum value which can be used in the spinbox + virtual f32 getMin() const; + + //! get the maximum value which can be used in the spinbox + virtual f32 getMax() const; + + //! step size by which values are changed when pressing the spin buttons + /** \param step: stepsize used for value changes when pressing spin buttons */ + virtual void setStepSize(f32 step=1.f); + + //! returns the step size + virtual f32 getStepSize() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Sets the new caption of the element + virtual void setText(const wchar_t* text); + + //! Returns caption of this element. + virtual const wchar_t* getText() const; + + //! Sets the number of decimal places to display. + /** \param places: The number of decimal places to display, use -1 to reset */ + virtual void setDecimalPlaces(s32 places); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + virtual void verifyValueRange(); + + IGUIEditBox * EditBox; + IGUIButton * ButtonSpinUp; + IGUIButton * ButtonSpinDown; + f32 StepSize; + f32 RangeMin; + f32 RangeMax; + + core::stringw FormatString; + s32 DecimalPlaces; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_SPIN_BOX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CGUISpriteBank.cpp b/src/dep/src/irrlicht/CGUISpriteBank.cpp new file mode 100644 index 0000000..9c4cf9b --- /dev/null +++ b/src/dep/src/irrlicht/CGUISpriteBank.cpp @@ -0,0 +1,136 @@ + +#include "CGUISpriteBank.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "ITexture.h" + +namespace irr +{ +namespace gui +{ + +CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) : + Environment(env), Driver(0) +{ + if (Environment) + { + Driver = Environment->getVideoDriver(); + if (Driver) + Driver->grab(); + } +} + + +CGUISpriteBank::~CGUISpriteBank() +{ + // drop textures + for (u32 i=0; idrop(); + + // drop video driver + if (Driver) + Driver->drop(); +} + + +core::array< core::rect >& CGUISpriteBank::getPositions() +{ + return Rectangles; +} + + +core::array< SGUISprite >& CGUISpriteBank::getSprites() +{ + return Sprites; +} + + +u32 CGUISpriteBank::getTextureCount() const +{ + return Textures.size(); +} + + +video::ITexture* CGUISpriteBank::getTexture(u32 index) const +{ + if (index < Textures.size()) + return Textures[index]; + else + return 0; +} + + +void CGUISpriteBank::addTexture(video::ITexture* texture) +{ + if (texture) + texture->grab(); + + Textures.push_back(texture); +} + + +void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture) +{ + while (index > Textures.size()) + Textures.push_back(0); + + if (Textures[index]) + Textures[index]->drop(); + + if (texture) + texture->grab(); + + Textures[index] = texture; +} + + +//! draws a sprite in 2d with scale and color +void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos, + const core::rect* clip, const video::SColor& color, + u32 starttime, u32 currenttime, bool loop, bool center) +{ + if (Sprites[index].Frames.empty() || index >= Sprites.size()) + return; + + // work out frame number + u32 frame = 0; + if (Sprites[index].frameTime) + { + u32 f = ((currenttime - starttime) / Sprites[index].frameTime); + if (loop) + frame = f % Sprites[index].Frames.size(); + else + frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size() : f; + } + + const video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber]; + if (!tex) + return; + + const u32 rn = Sprites[index].Frames[frame].rectNumber; + if (rn >= Rectangles.size()) + return; + + const core::rect& r = Rectangles[rn]; + + if (center) + { + core::position2di p = pos; + p -= r.getSize() / 2; + Driver->draw2DImage(tex, p, r, clip, color, true); + } + else + { + Driver->draw2DImage(tex, pos, r, clip, color, true); + } +} + + +} // namespace gui +} // namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUISpriteBank.h b/src/dep/src/irrlicht/CGUISpriteBank.h new file mode 100644 index 0000000..b907a45 --- /dev/null +++ b/src/dep/src/irrlicht/CGUISpriteBank.h @@ -0,0 +1,62 @@ + +#ifndef __C_GUI_SPRITE_BANK_H_INCLUDED__ +#define __C_GUI_SPRITE_BANK_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISpriteBank.h" + +namespace irr +{ + +namespace video +{ + class IVideoDriver; + class ITexture; +} + +namespace gui +{ + + class IGUIEnvironment; + +//! Sprite bank interface. +class CGUISpriteBank : public IGUISpriteBank +{ +public: + + CGUISpriteBank(IGUIEnvironment* env); + virtual ~CGUISpriteBank(); + + virtual core::array< core::rect >& getPositions(); + virtual core::array< SGUISprite >& getSprites(); + + virtual u32 getTextureCount() const; + virtual video::ITexture* getTexture(u32 index) const; + virtual void addTexture(video::ITexture* texture); + virtual void setTexture(u32 index, video::ITexture* texture); + + //! draws a sprite in 2d with position and color + virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false); + +protected: + + core::array Sprites; + core::array< core::rect > Rectangles; + core::array Textures; + IGUIEnvironment* Environment; + video::IVideoDriver* Driver; + +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_SPRITE_BANK_H_INCLUDED__ + + diff --git a/src/dep/src/irrlicht/CGUIStaticText.cpp b/src/dep/src/irrlicht/CGUIStaticText.cpp new file mode 100644 index 0000000..c26ea30 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIStaticText.cpp @@ -0,0 +1,457 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIStaticText.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIStaticText::CGUIStaticText(const wchar_t* text, bool border, + IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect& rectangle, + bool background) +: IGUIStaticText(environment, parent, id, rectangle), Border(border), + HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_UPPERLEFT), + OverrideColorEnabled(false), WordWrap(false), Background(background), + OverrideColor(video::SColor(101,255,255,255)), BGColor(video::SColor(101,210,210,210)), + OverrideFont(0), LastBreakFont(0) +{ + #ifdef _DEBUG + setDebugName("CGUIStaticText"); + #endif + + Text = text; + if (environment && environment->getSkin()) + { + BGColor = environment->getSkin()->getColor(gui::EGDC_3D_FACE); + } +} + + +//! destructor +CGUIStaticText::~CGUIStaticText() +{ + if (OverrideFont) + OverrideFont->drop(); +} + + +//! draws the element and its children +void CGUIStaticText::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect frameRect(AbsoluteRect); + + // draw background + + if (Background) + { + driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect); + } + + // draw the border + + if (Border) + { + skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); + frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); + } + + // draw the text + if (Text.size()) + { + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(); + + if (font) + { + if (!WordWrap) + { + if (VAlign == EGUIA_LOWERRIGHT) + { + frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - + font->getDimension(L"A").Height - font->getKerningHeight(); + } + if (HAlign == EGUIA_LOWERRIGHT) + { + frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - + font->getDimension(Text.c_str()).Width; + } + + font->draw(Text.c_str(), frameRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), + HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, &AbsoluteClippingRect); + } + else + { + if (font != LastBreakFont) + breakText(); + + core::rect r = frameRect; + s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); + s32 totalHeight = height * BrokenText.size(); + if (VAlign == EGUIA_CENTER) + { + r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2); + } + else if (VAlign == EGUIA_LOWERRIGHT) + { + r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight; + } + + for (u32 i=0; igetDimension(BrokenText[i].c_str()).Width; + } + + font->draw(BrokenText[i].c_str(), r, + OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), + HAlign == EGUIA_CENTER, false, &AbsoluteClippingRect); + + r.LowerRightCorner.Y += height; + r.UpperLeftCorner.Y += height; + } + } + } + } + + IGUIElement::draw(); +} + + +//! Sets another skin independent font. +void CGUIStaticText::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + breakText(); +} + + +IGUIFont * CGUIStaticText::getOverrideFont() const +{ + return OverrideFont; +} + + +//! Sets another color for the text. +void CGUIStaticText::setOverrideColor(video::SColor color) +{ + OverrideColor = color; + OverrideColorEnabled = true; +} + + +//! Sets another color for the text. +void CGUIStaticText::setBackgroundColor(video::SColor color) +{ + BGColor = color; + Background = true; +} + + +//! Sets whether to draw the background +void CGUIStaticText::setDrawBackground(bool draw) +{ + Background = draw; +} + + +//! Sets whether to draw the border +void CGUIStaticText::setDrawBorder(bool draw) +{ + Border = draw; +} + + +void CGUIStaticText::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; +} + + +video::SColor const& CGUIStaticText::getOverrideColor() const +{ + return OverrideColor; +} + + +//! Sets if the static text should use the overide color or the +//! color in the gui skin. +void CGUIStaticText::enableOverrideColor(bool enable) +{ + OverrideColorEnabled = enable; +} + + +bool CGUIStaticText::isOverrideColorEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return OverrideColorEnabled; +} + + +//! Enables or disables word wrap for using the static text as +//! multiline text control. +void CGUIStaticText::setWordWrap(bool enable) +{ + WordWrap = enable; + breakText(); +} + + +bool CGUIStaticText::isWordWrapEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return WordWrap; +} + + +//! Breaks the single text line. +void CGUIStaticText::breakText() +{ + IGUISkin* skin = Environment->getSkin(); + + if (!WordWrap || !skin) + return; + + BrokenText.clear(); + + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(); + + if (!font) + return; + + LastBreakFont = font; + + core::stringw line; + core::stringw word; + core::stringw whitespace; + s32 size = Text.size(); + s32 length = 0; + s32 elWidth = RelativeRect.getWidth() - 6; + wchar_t c; + + for (s32 i=0; igetDimension(whitespace.c_str()).Width; + s32 worldlgth = font->getDimension(word.c_str()).Width; + + if (length + worldlgth + whitelgth > elWidth) + { + // break to next line + length = worldlgth; + BrokenText.push_back(line); + line = word; + } + else + { + // add word to line + line += whitespace; + line += word; + length += whitelgth + worldlgth; + } + + word = L""; + whitespace = L""; + } + + whitespace += c; + + // compute line break + if (lineBreak) + { + line += whitespace; + line += word; + BrokenText.push_back(line); + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } + else + { + // yippee this is a word.. + word += c; + } + } + + line += whitespace; + line += word; + BrokenText.push_back(line); +} + + +//! Sets the new caption of this element. +void CGUIStaticText::setText(const wchar_t* text) +{ + IGUIElement::setText(text); + breakText(); +} + +void CGUIStaticText::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + breakText(); +} + + +//! Returns the height of the text in pixels when it is drawn. +s32 CGUIStaticText::getTextHeight() const +{ + IGUISkin* skin = Environment->getSkin(); + + if (!skin) + return 0; + + IGUIFont* font = OverrideFont; + if (!OverrideFont) + font = skin->getFont(); + + if (!font) + return 0; + + s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); + + if (WordWrap) + height *= BrokenText.size(); + + return height; +} + + +s32 CGUIStaticText::getTextWidth() const +{ + IGUIFont * font = OverrideFont; + + if(!OverrideFont) + { + IGUISkin * skin = Environment->getSkin(); + if(skin) + font = skin->getFont(); + } + + if(!font) + return 0; + + if(WordWrap) + { + s32 widest = 0; + + for(u32 line = 0; line < BrokenText.size(); ++line) + { + s32 width = font->getDimension(BrokenText[line].c_str()).Width; + + if(width > widest) + widest = width; + } + + return widest; + } + else + { + return font->getDimension(Text.c_str()).Width; + } +} + + +//! Writes attributes of the element. +//! Implement this to expose the attributes of your element for +//! scripting languages, editors, debuggers or xml serialization purposes. +void CGUIStaticText::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIStaticText::serializeAttributes(out,options); + + out->addBool ("Border", Border); + out->addBool ("OverrideColorEnabled",OverrideColorEnabled); + out->addBool ("WordWrap", WordWrap); + out->addBool ("Background", Background); + out->addColor ("OverrideColor", OverrideColor); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + + // out->addFont ("OverrideFont", OverrideFont); +} + + +//! Reads attributes of the element +void CGUIStaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIStaticText::deserializeAttributes(in,options); + + Border = in->getAttributeAsBool("Border"); + OverrideColor = in->getAttributeAsColor("OverrideColor"); + + enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled")); + setWordWrap(in->getAttributeAsBool("WordWrap")); + Background = in->getAttributeAsBool("Background"); + + setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); + + // OverrideFont = in->getAttributeAsFont("OverrideFont"); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIStaticText.h b/src/dep/src/irrlicht/CGUIStaticText.h new file mode 100644 index 0000000..637a45c --- /dev/null +++ b/src/dep/src/irrlicht/CGUIStaticText.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_STATIC_TEXT_H_INCLUDED__ +#define __C_GUI_STATIC_TEXT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIStaticText.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class CGUIStaticText : public IGUIStaticText + { + public: + + //! constructor + CGUIStaticText(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle, + bool background = false); + + //! destructor + virtual ~CGUIStaticText(); + + //! draws the element and its children + virtual void draw(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Gets the override font (if any) + virtual IGUIFont * getOverrideFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Sets another color for the background. + virtual void setBackgroundColor(video::SColor color); + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + //! Sets whether to draw the border + virtual void setDrawBorder(bool draw); + + //! Sets alignment mode for text + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! Gets the override color + virtual video::SColor const & getOverrideColor() const; + + //! Sets if the static text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + virtual bool isOverrideColorEnabled() const; + + //! Enables or disables word wrap for using the static text as + //! multiline text control. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + virtual bool isWordWrapEnabled() const; + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text); + + //! Returns the height of the text in pixels when it is drawn. + virtual s32 getTextHeight() const; + + //! Returns the width of the current text, in the current font + virtual s32 getTextWidth() const; + + //! Updates the absolute position, splits text if word wrap is enabled + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + //! Breaks the single text line. + void breakText(); + + bool Border; + EGUI_ALIGNMENT HAlign, VAlign; + bool OverrideColorEnabled; + bool WordWrap; + bool Background; + + video::SColor OverrideColor, BGColor; + gui::IGUIFont* OverrideFont; + gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated. + + core::array< core::stringw > BrokenText; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGUITabControl.cpp b/src/dep/src/irrlicht/CGUITabControl.cpp new file mode 100644 index 0000000..9b8360a --- /dev/null +++ b/src/dep/src/irrlicht/CGUITabControl.cpp @@ -0,0 +1,500 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUITabControl.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +// ------------------------------------------------------------------ +// Tab +// ------------------------------------------------------------------ + +//! constructor +CGUITab::CGUITab(s32 number, IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + s32 id) + : IGUITab(environment, parent, id, rectangle), Number(number), + DrawBackground(false), BackColor(0,0,0,0) +{ + #ifdef _DEBUG + setDebugName("CGUITab"); + #endif +} + + +//! Returns number of tab in tabcontrol. Can be accessed +//! later IGUITabControl::getTab() by this number. +s32 CGUITab::getNumber() const +{ + return Number; +} + + +//! Sets the number +void CGUITab::setNumber(s32 n) +{ + Number = n; +} + + +//! draws the element and its children +void CGUITab::draw() +{ + if (!IsVisible) + return; + + IGUISkin *skin = Environment->getSkin(); + + if (skin && DrawBackground) + skin->draw2DRectangle(this, BackColor, AbsoluteRect, &AbsoluteClippingRect); + + IGUIElement::draw(); +} + + +//! sets if the tab should draw its background +void CGUITab::setDrawBackground(bool draw) +{ + DrawBackground = draw; +} + + +//! sets the color of the background, if it should be drawn. +void CGUITab::setBackgroundColor(video::SColor c) +{ + BackColor = c; +} + + +//! returns true if the tab is drawing its background, false if not +bool CGUITab::isDrawingBackground() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return DrawBackground; +} + + +//! returns the color of the background +video::SColor CGUITab::getBackgroundColor() const +{ + return BackColor; +} + + +//! Writes attributes of the element. +void CGUITab::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUITab::serializeAttributes(out,options); + + out->addInt ("TabNumber", Number); + out->addBool ("DrawBackground", DrawBackground); + out->addColor ("BackColor", BackColor); + +} + + +//! Reads attributes of the element +void CGUITab::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUITab::deserializeAttributes(in,options); + + setNumber(in->getAttributeAsInt("TabNumber")); + setDrawBackground(in->getAttributeAsBool("DrawBackground")); + setBackgroundColor(in->getAttributeAsColor("BackColor")); + + if (Parent && Parent->getType() == EGUIET_TAB_CONTROL) + { + ((CGUITabControl*)Parent)->addTab(this); + if (isVisible()) + ((CGUITabControl*)Parent)->setActiveTab(this); + } +} + + +// ------------------------------------------------------------------ +// Tabcontrol +// ------------------------------------------------------------------ + +//! destructor +CGUITabControl::CGUITabControl(IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + bool fillbackground, bool border, s32 id) + : IGUITabControl(environment, parent, id, rectangle), ActiveTab(-1), + Border(border), FillBackground(fillbackground) +{ + #ifdef _DEBUG + setDebugName("CGUITabControl"); + #endif +} + + +//! destructor +CGUITabControl::~CGUITabControl() +{ + for (s32 i=0; i<(s32)Tabs.size(); ++i) + if (Tabs[i]) + Tabs[i]->drop(); +} + + +//! Adds a tab +IGUITab* CGUITabControl::addTab(const wchar_t* caption, s32 id) +{ + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return 0; + + s32 tabheight = skin->getSize(gui::EGDS_BUTTON_HEIGHT) + 2; + core::rect r(1,tabheight, + AbsoluteRect.getWidth()-1, + AbsoluteRect.getHeight()-1); + + CGUITab* tab = new CGUITab(Tabs.size(), Environment, this, + r, id); + tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + + tab->setText(caption); + tab->setVisible(false); + Tabs.push_back(tab); + + if (ActiveTab == -1) + { + ActiveTab = 0; + tab->setVisible(true); + } + + return tab; +} + + +//! adds a tab which has been created elsewhere +void CGUITabControl::addTab(CGUITab* tab) +{ + if (!tab) + return; + + // check if its already added + for (s32 i=0; i < (s32)Tabs.size(); ++i) + if (Tabs[i] == tab) + return; + + tab->grab(); + + if (tab->getNumber() == -1) + tab->setNumber((s32)Tabs.size()); + + while (tab->getNumber() >= (s32)Tabs.size()) + Tabs.push_back(0); + + if (Tabs[tab->getNumber()]) + { + Tabs.push_back(Tabs[tab->getNumber()]); + Tabs[Tabs.size()-1]->setNumber(Tabs.size()); + } + Tabs[tab->getNumber()] = tab; + + if (ActiveTab == -1) + ActiveTab = tab->getNumber(); + + + if (tab->getNumber() == ActiveTab) + { + setActiveTab(ActiveTab); + } +} + + +//! Returns amount of tabs in the tabcontrol +s32 CGUITabControl::getTabCount() const +{ + return Tabs.size(); +} + + +//! Returns a tab based on zero based index +IGUITab* CGUITabControl::getTab(s32 idx) const +{ + if (idx < 0 || idx >= (s32)Tabs.size()) + return 0; + + return Tabs[idx]; +} + + +//! called if an event happened. +bool CGUITabControl::OnEvent(const SEvent& event) +{ + if (!IsEnabled) + return Parent ? Parent->OnEvent(event) : false; + + switch(event.EventType) + { + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + Environment->setFocus(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Environment->removeFocus(this); + selectTab(core::position2d(event.MouseInput.X, event.MouseInput.Y)); + return true; + default: + break; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +void CGUITabControl::selectTab(core::position2d p) +{ + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(); + + core::rect frameRect(AbsoluteRect); + + s32 tabheight = skin->getSize(gui::EGDS_BUTTON_HEIGHT); + frameRect.UpperLeftCorner.Y += 2; + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + tabheight; + s32 pos = frameRect.UpperLeftCorner.X + 2; + + for (u32 i=0; igetText(); + + // get text length + s32 len = 20; + if (font) + len += font->getDimension(text).Width; + + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + pos += len; + + if (frameRect.isPointInside(p)) + { + setActiveTab(i); + return; + } + } +} + + +//! draws the element and its children +void CGUITabControl::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + IGUIFont* font = skin->getFont(); + + core::rect frameRect(AbsoluteRect); + + if (Tabs.empty()) + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), + frameRect, &AbsoluteClippingRect); + + if (!font) + return; + + s32 tabheight = skin->getSize(gui::EGDS_BUTTON_HEIGHT); + frameRect.UpperLeftCorner.Y += 2; + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + tabheight; + core::rect tr; + s32 pos = frameRect.UpperLeftCorner.X + 2; + + // left and right pos of the active tab + s32 left = 0; + s32 right = 0; + const wchar_t* activetext = 0; + + for (s32 i=0; i<(s32)Tabs.size(); ++i) + { + // get Text + const wchar_t* text = 0; + if (Tabs[i]) + text = Tabs[i]->getText(); + + // get text length + s32 len = font->getDimension(text).Width + 20; + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + pos += len; + + if (i == ActiveTab) + { + left = frameRect.UpperLeftCorner.X; + right = frameRect.LowerRightCorner.X; + activetext = text; + } + else + { + skin->draw3DTabButton(this, false, frameRect, &AbsoluteClippingRect); + + // draw text + font->draw(text, frameRect, skin->getColor(EGDC_BUTTON_TEXT), + true, true, &AbsoluteClippingRect); + } + } + + // draw active tab + if (left != 0 && right != 0) + { + frameRect.UpperLeftCorner.X = left-2; + frameRect.LowerRightCorner.X = right+2; + frameRect.UpperLeftCorner.Y -= 2; + + skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect); + + // draw text + font->draw(activetext, frameRect, skin->getColor(EGDC_BUTTON_TEXT), + true, true, &AbsoluteClippingRect); + + // draw upper highlight frame + tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; + tr.LowerRightCorner.X = left - 1; + tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; + tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); + + tr.UpperLeftCorner.X = right; + tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); + } + + skin->draw3DTabBody(this, Border, FillBackground, AbsoluteRect, &AbsoluteClippingRect); + + IGUIElement::draw(); +} + + +//! Returns which tab is currently active +s32 CGUITabControl::getActiveTab() const +{ + return ActiveTab; +} + + +bool CGUITabControl::setActiveTab(IGUIElement *tab) +{ + for (s32 i=0; i<(s32)Tabs.size(); ++i) + if (Tabs[i] == tab) + return setActiveTab(i); + return false; +} + + +//! Brings a tab to front. +bool CGUITabControl::setActiveTab(s32 idx) +{ + if ((u32)idx >= Tabs.size()) + return false; + + bool changed = (ActiveTab != idx); + + ActiveTab = idx; + + for (s32 i=0; i<(s32)Tabs.size(); ++i) + if (Tabs[i]) + Tabs[i]->setVisible( i == ActiveTab ); + + if (changed) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_TAB_CHANGED; + Parent->OnEvent(event); + } + + return true; +} + + +//! Removes a child. +void CGUITabControl::removeChild(IGUIElement* child) +{ + bool isTab = false; + + u32 i=0; + // check if it is a tab + while (idrop(); + Tabs.erase(i); + isTab = true; + } + else + ++i; + } + + // reassign numbers + if (isTab) + { + for (i=0; isetNumber(i); + } + + // remove real element + IGUIElement::removeChild(child); +} + + +//! Writes attributes of the element. +void CGUITabControl::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUITabControl::serializeAttributes(out,options); + + out->addInt("ActiveTab", ActiveTab); + out->addBool("Border", Border); + out->addBool("FillBackground", FillBackground); +} + + +//! Reads attributes of the element +void CGUITabControl::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Border = in->getAttributeAsBool("Border"); + FillBackground = in->getAttributeAsBool("FillBackground"); + + ActiveTab = -1; + + IGUITabControl::deserializeAttributes(in,options); + + setActiveTab(in->getAttributeAsInt("ActiveTab")); +} + + +} // end namespace irr +} // end namespace gui + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUITabControl.h b/src/dep/src/irrlicht/CGUITabControl.h new file mode 100644 index 0000000..76375d1 --- /dev/null +++ b/src/dep/src/irrlicht/CGUITabControl.h @@ -0,0 +1,132 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_TAB_CONTROL_H_INCLUDED__ +#define __C_GUI_TAB_CONTROL_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUITabControl.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + // A tab, onto which other gui elements could be added. + class CGUITab : public IGUITab + { + public: + + //! constructor + CGUITab(s32 number, IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + s32 id); + + //! Returns number of this tab in tabcontrol. Can be accessed + //! later IGUITabControl::getTab() by this number. + virtual s32 getNumber() const; + + //! Sets the number + virtual void setNumber(s32 n); + + //! draws the element and its children + virtual void draw(); + + //! sets if the tab should draw its background + virtual void setDrawBackground(bool draw=true); + + //! sets the color of the background, if it should be drawn. + virtual void setBackgroundColor(video::SColor c); + + //! returns true if the tab is drawing its background, false if not + virtual bool isDrawingBackground() const; + + //! returns the color of the background + virtual video::SColor getBackgroundColor() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + + private: + + s32 Number; + bool DrawBackground; + video::SColor BackColor; + }; + + + + //! A standard tab control + class CGUITabControl : public IGUITabControl + { + public: + + //! destructor + CGUITabControl(IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + bool fillbackground=true, bool border=true, s32 id=-1); + + //! destructor + virtual ~CGUITabControl(); + + //! Adds a tab + virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1); + + //! Adds a tab that has already been created + virtual void addTab(CGUITab* tab); + + //! Returns amount of tabs in the tabcontrol + virtual s32 getTabCount() const; + + //! Returns a tab based on zero based index + virtual IGUITab* getTab(s32 idx) const; + + //! Brings a tab to front. + virtual bool setActiveTab(s32 idx); + + //! Brings a tab to front. + virtual bool setActiveTab(IGUIElement *tab); + + //! Returns which tab is currently active + virtual s32 getActiveTab() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Removes a child. + virtual void removeChild(IGUIElement* child); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void selectTab(core::position2d p); + + core::array Tabs; + s32 ActiveTab; + bool Border; + bool FillBackground; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGUIToolBar.cpp b/src/dep/src/irrlicht/CGUIToolBar.cpp new file mode 100644 index 0000000..2430172 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIToolBar.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIToolBar.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIFont.h" +#include "CGUIButton.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIToolBar::CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +:IGUIToolBar(environment, parent, id, rectangle), ButtonX(5) +{ + #ifdef _DEBUG + setDebugName("CGUIToolBar"); + #endif + + // calculate position and find other menubars + s32 y = 0; + s32 parentwidth = 100; + + if (parent) + { + parentwidth = Parent->getAbsolutePosition().getWidth(); + + const core::list& children = parent->getChildren(); + core::list::ConstIterator it = children.begin(); + for (; it != children.end(); ++it) + { + core::rect r = (*it)->getAbsolutePosition(); + if (r.UpperLeftCorner.X == 0 && r.UpperLeftCorner.Y <= y && + r.LowerRightCorner.X == parentwidth) + y = r.LowerRightCorner.Y; + } + } + + core::rect rr; + rr.UpperLeftCorner.X = 0; + rr.UpperLeftCorner.Y = y; + s32 height = Environment->getSkin()->getSize ( EGDS_MENU_HEIGHT ); + + /*IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(); + if (font) + { + s32 t = font->getDimension(L"A").Height + 5; + if (t > height) + height = t; + }*/ + + rr.LowerRightCorner.X = parentwidth; + rr.LowerRightCorner.Y = rr.UpperLeftCorner.Y + height; + setRelativePosition(rr); +} + + +//! called if an event happened. +bool CGUIToolBar::OnEvent(const SEvent& event) +{ + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y))) + return true; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void CGUIToolBar::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + core::rect rect = AbsoluteRect; + core::rect* clip = 0; + + // draw frame + skin->draw3DToolBar(this, rect, clip); + + IGUIElement::draw(); +} + + +//! Updates the absolute position. +void CGUIToolBar::updateAbsolutePosition() +{ + if (Parent) + { + DesiredRect.UpperLeftCorner.X = 0; + DesiredRect.LowerRightCorner.X = Parent->getAbsolutePosition().getWidth(); + } + + IGUIElement::updateAbsolutePosition(); +} + + +//! Adds a button to the tool bar +IGUIButton* CGUIToolBar::addButton(s32 id, const wchar_t* text,const wchar_t* tooltiptext, + video::ITexture* img, video::ITexture* pressed, bool isPushButton, + bool useAlphaChannel) +{ + ButtonX += 3; + + core::rect rectangle(ButtonX,2,0,0); + if ( img ) + { + const core::dimension2di &size = img->getOriginalSize(); + rectangle.LowerRightCorner.X = rectangle.UpperLeftCorner.X + size.Width + 8; + rectangle.LowerRightCorner.Y = rectangle.UpperLeftCorner.Y + size.Height + 6; + } + + ButtonX += rectangle.getWidth(); + + IGUIButton* button = new CGUIButton(Environment, this, id, rectangle); + button->drop(); + + if (text) + button->setText(text); + + if (tooltiptext) + button->setToolTipText(tooltiptext); + + if (img) + button->setImage(img); + + if (pressed) + button->setPressedImage(pressed); + + if (isPushButton) + button->setIsPushButton(isPushButton); + + if (useAlphaChannel) + button->setUseAlphaChannel(useAlphaChannel); + + return button; +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIToolBar.h b/src/dep/src/irrlicht/CGUIToolBar.h new file mode 100644 index 0000000..3f2fced --- /dev/null +++ b/src/dep/src/irrlicht/CGUIToolBar.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_TOOL_BAR_H_INCLUDED__ +#define __C_GUI_TOOL_BAR_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIToolbar.h" + +namespace irr +{ +namespace gui +{ + + //! Stays at the top of its parent like the menu bar and contains tool buttons + class CGUIToolBar : public IGUIToolBar + { + public: + + //! constructor + CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + //! Adds a button to the tool bar + virtual IGUIButton* addButton(s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext=0, + video::ITexture* img=0, video::ITexture* pressed=0, + bool isPushButton=false, bool useAlphaChannel=false); + + private: + + s32 ButtonX; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGUIWindow.cpp b/src/dep/src/irrlicht/CGUIWindow.cpp new file mode 100644 index 0000000..e479c67 --- /dev/null +++ b/src/dep/src/irrlicht/CGUIWindow.cpp @@ -0,0 +1,266 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIWindow.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIWindow(environment, parent, id, rectangle), Dragging(false) +{ + #ifdef _DEBUG + setDebugName("CGUIWindow"); + #endif + + IGUISkin* skin = 0; + if (environment) + skin = environment->getSkin(); + + IGUISpriteBank* sprites = 0; + video::SColor color(255,255,255,255); + + s32 buttonw = 15; + if (skin) + { + buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + sprites = skin->getSpriteBank(); + color = skin->getColor(EGDC_WINDOW_SYMBOL); + } + s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" ); + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (sprites) + { + CloseButton->setSpriteBank(sprites); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color); + } + posx -= buttonw + 2; + + RestoreButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" ); + RestoreButton->setVisible(false); + RestoreButton->setSubElement(true); + RestoreButton->setTabStop(false); + RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (sprites) + { + RestoreButton->setSpriteBank(sprites); + RestoreButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESTORE), color); + RestoreButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESTORE), color); + } + posx -= buttonw + 2; + + MinButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" ); + MinButton->setVisible(false); + MinButton->setSubElement(true); + MinButton->setTabStop(false); + MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (sprites) + { + MinButton->setSpriteBank(sprites); + MinButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_MINIMIZE), color); + MinButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_MINIMIZE), color); + } + + MinButton->grab(); + RestoreButton->grab(); + CloseButton->grab(); + + // this element is a tab group + setTabGroup(true); + setTabStop(true); + setTabOrder(-1); +} + + +//! destructor +CGUIWindow::~CGUIWindow() +{ + if (MinButton) + MinButton->drop(); + + if (RestoreButton) + RestoreButton->drop(); + + if (CloseButton) + CloseButton->drop(); +} + + +//! called if an event happened. +bool CGUIWindow::OnEvent(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + Dragging = false; + } + else + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED) + { + if (event.GUIEvent.Caller == this && Parent) + { + Parent->bringToFront(this); + } + } + else + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == CloseButton) + { + if (Parent) + { + // send close event to parent + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_ELEMENT_CLOSED; + + // if the event was not absorbed + if (!Parent->OnEvent(e)) + { + remove(); + } + return true; + + } + else + { + remove(); + return true; + } + } + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = true; + if (!Environment->hasFocus(this)) + { + Environment->setFocus(this); + if (Parent) + Parent->bringToFront(this); + } + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + return true; + case EMIE_MOUSE_MOVED: + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent) + if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) + + return true; + + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + break; + default: + break; + } + default: + break; + } + + return IGUIElement::OnEvent(event); +} + + +//! Updates the absolute position. +void CGUIWindow::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); +} + + +//! draws the element and its children +void CGUIWindow::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + core::rect rect = AbsoluteRect; + core::rect *cl = &AbsoluteClippingRect; + + // draw body fast + rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), + AbsoluteRect, &AbsoluteClippingRect); + + if (Text.size()) + { + rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); + rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y); + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, cl); + } + + IGUIElement::draw(); +} + + +//! Returns pointer to the close button +IGUIButton* CGUIWindow::getCloseButton() const +{ + return CloseButton; +} + + +//! Returns pointer to the minimize button +IGUIButton* CGUIWindow::getMinimizeButton() const +{ + return MinButton; +} + + +//! Returns pointer to the maximize button +IGUIButton* CGUIWindow::getMaximizeButton() const +{ + return RestoreButton; +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/dep/src/irrlicht/CGUIWindow.h b/src/dep/src/irrlicht/CGUIWindow.h new file mode 100644 index 0000000..136635d --- /dev/null +++ b/src/dep/src/irrlicht/CGUIWindow.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_WINDOW_H_INCLUDED__ +#define __C_GUI_WINDOW_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIWindow.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + + class CGUIWindow : public IGUIWindow + { + public: + + //! constructor + CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIWindow(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! update absolute position + virtual void updateAbsolutePosition(); + + //! draws the element and its children + virtual void draw(); + + //! Returns pointer to the close button + virtual IGUIButton* getCloseButton() const; + + //! Returns pointer to the minimize button + virtual IGUIButton* getMinimizeButton() const; + + //! Returns pointer to the maximize button + virtual IGUIButton* getMaximizeButton() const; + + protected: + + core::position2d DragStart; + bool Dragging; + + IGUIButton* CloseButton; + IGUIButton* MinButton; + IGUIButton* RestoreButton; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/dep/src/irrlicht/CGeometryCreator.cpp b/src/dep/src/irrlicht/CGeometryCreator.cpp new file mode 100644 index 0000000..fd83063 --- /dev/null +++ b/src/dep/src/irrlicht/CGeometryCreator.cpp @@ -0,0 +1,639 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGeometryCreator.h" +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "CImage.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +// creates a hill plane +IMesh* CGeometryCreator::createHillPlaneMesh( + const core::dimension2d& tileSize, + const core::dimension2d& tc, video::SMaterial* material, + f32 hillHeight, const core::dimension2d& ch, + const core::dimension2d& textureRepeatCount) +{ + core::dimension2d tileCount = tc; + core::dimension2d countHills = ch; + + if (countHills.Width < 0.01f) + countHills.Width = 1.f; + if (countHills.Height < 0.01f) + countHills.Height = 1.f; + + // center + const core::position2d center((tileSize.Width * tileCount.Width) / 2.0f, (tileSize.Height * tileCount.Height) / 2.0f); + + // texture coord step + const core::dimension2d tx( + textureRepeatCount.Width / tileCount.Width, + textureRepeatCount.Height / tileCount.Height); + + // add one more point in each direction for proper tile count + ++tileCount.Height; + ++tileCount.Width; + + SMeshBuffer* buffer = new SMeshBuffer(); + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + + // create vertices from left-front to right-back + u32 x; + + f32 sx=0.f, tsx=0.f; + for (x=0; xVertices.push_back(vtx); + sy += tileSize.Height; + tsy += tx.Height; + } + sx += tileSize.Width; + tsx += tx.Width; + } + + // create indices + + for (x=0; xIndices.push_back(current); + buffer->Indices.push_back(current + 1); + buffer->Indices.push_back(current + tileCount.Height); + + buffer->Indices.push_back(current + 1); + buffer->Indices.push_back(current + 1 + tileCount.Height); + buffer->Indices.push_back(current + tileCount.Height); + } + } + + // recalculate normals + for (u32 i=0; iIndices.size(); i+=3) + { + core::plane3d p( + buffer->Vertices[buffer->Indices[i+0]].Pos, + buffer->Vertices[buffer->Indices[i+1]].Pos, + buffer->Vertices[buffer->Indices[i+2]].Pos); + + buffer->Vertices[buffer->Indices[i+0]].Normal = p.Normal; + buffer->Vertices[buffer->Indices[i+1]].Normal = p.Normal; + buffer->Vertices[buffer->Indices[i+2]].Normal = p.Normal; + } + + if (material) + buffer->Material = *material; + + buffer->recalculateBoundingBox(); + + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + mesh->recalculateBoundingBox(); + buffer->drop(); + return mesh; +} + + + +IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture, + video::IImage* heightmap, const core::dimension2d& stretchSize, + f32 maxHeight, video::IVideoDriver* driver, + const core::dimension2d maxVtxBlockSize, + bool debugBorders) +{ + if (!texture || !heightmap) + return 0; + + // debug border + const s32 borderSkip = debugBorders ? 0 : 1; + + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + + SMesh* mesh = new SMesh(); + + const u32 tm = os::Timer::getRealTime()/1000; + const core::dimension2d hMapSize= heightmap->getDimension(); + const core::dimension2d tMapSize= texture->getDimension(); + const core::position2d thRel((f32)tMapSize.Width / hMapSize.Width, (f32)tMapSize.Height / hMapSize.Height); + + video::SMaterial material; + + core::position2d processed(0,0); + while (processed.Y blockSize = maxVtxBlockSize; + if (processed.X + blockSize.Width > hMapSize.Width) + blockSize.Width = hMapSize.Width - processed.X; + if (processed.Y + blockSize.Height > hMapSize.Height) + blockSize.Height = hMapSize.Height - processed.Y; + + SMeshBuffer* buffer = new SMeshBuffer(); + + // add vertices of vertex block + s32 y; + + for (y=0; ygetPixel(x+processed.X, y+processed.Y); + const f32 height = ((clr.getRed() + clr.getGreen() + clr.getBlue()) / 3.0f)/255.0f * maxHeight; + + vtx.Pos.set((f32)(x+processed.X) * stretchSize.Width, + height, (f32)(y+processed.Y) * stretchSize.Height); + + vtx.TCoords.set((x+0.5f) / blockSize.Width, + (y+0.5f) / blockSize.Height); + buffer->Vertices.push_back(vtx); + } + } + + // add indices of vertex block + for (y=0; yIndices.push_back(c); + buffer->Indices.push_back(c + blockSize.Width); + buffer->Indices.push_back(c + 1); + + buffer->Indices.push_back(c + 1); + buffer->Indices.push_back(c + blockSize.Width); + buffer->Indices.push_back(c + 1 + blockSize.Width); + } + } + + // recalculate normals + for (s32 i=0; i<(s32)buffer->Indices.size(); i+=3) + { + core::plane3d p( + buffer->Vertices[buffer->Indices[i+0]].Pos, + buffer->Vertices[buffer->Indices[i+1]].Pos, + buffer->Vertices[buffer->Indices[i+2]].Pos); + p.Normal.normalize(); + + buffer->Vertices[buffer->Indices[i+0]].Normal = p.Normal; + buffer->Vertices[buffer->Indices[i+1]].Normal = p.Normal; + buffer->Vertices[buffer->Indices[i+2]].Normal = p.Normal; + } + + if (buffer->Vertices.size()) + { + c8 textureName[64]; + // create texture for this block + video::IImage* img = new video::CImage(texture, + core::position2d(core::floor32(processed.X*thRel.X), core::floor32(processed.Y*thRel.Y)), + core::dimension2d(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y))); + + sprintf(textureName, "terrain%u_%u", tm, mesh->getMeshBufferCount()); + + material.setTexture(0, driver->addTexture(textureName, img)); + + if (material.getTexture(0)) + { + c8 tmp[255]; + sprintf(tmp, "Generated terrain texture (%dx%d): %s", + material.getTexture(0)->getSize().Width, + material.getTexture(0)->getSize().Height, + textureName); + os::Printer::log(tmp); + } + else + os::Printer::log("Could not create terrain texture.", textureName, ELL_ERROR); + + buffer->Material = material; + img->drop(); + } + + buffer->recalculateBoundingBox(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + // keep on processing + processed.X += maxVtxBlockSize.Width - borderSkip; + } + + // keep on processing + processed.X = 0; + processed.Y += maxVtxBlockSize.Height - borderSkip; + } + + mesh->recalculateBoundingBox(); + return mesh; +} + +/* + a cylinder, a cone and a cross + point up on (0,1.f, 0.f ) +*/ +IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder, + const u32 tesselationCone, + const f32 height, + const f32 cylinderHeight, + const f32 width0, + const f32 width1, + const video::SColor vtxColor0, + const video::SColor vtxColor1) +{ + SMeshBuffer* buffer; + video::S3DVertex v; + u32 i; + + v.Color = vtxColor0; + + // cylinder + buffer = new SMeshBuffer(); + + // floor, bottom + f32 angleStep = (core::PI * 2.f ) / tesselationCylinder; + + for ( i = 0; i != tesselationCylinder; ++i ) + { + f32 angle = angleStep * f32(i); + v.Color = vtxColor0; + v.Pos.X = width0 * cosf ( angle ); + v.Pos.Y = 0.f; + v.Pos.Z = width0 * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + buffer->Vertices.push_back ( v ); + + v.Pos.X = width0 * 0.5f * cosf ( angle ); + v.Pos.Y = cylinderHeight; + v.Pos.Z = width0 * 0.5f * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + buffer->Vertices.push_back ( v ); + + angle += ( angleStep / 2.f ); + v.Color = vtxColor1; + v.Pos.X = ( width0 * 0.75f ) * cosf ( angle ); + v.Pos.Y = 0.f; + v.Pos.Z = ( width0 * 0.75f ) * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + buffer->Vertices.push_back ( v ); + + v.Pos.X = ( width0 * 0.25f ) * cosf ( angle ); + v.Pos.Y = cylinderHeight; + v.Pos.Z = ( width0 * 0.25f ) * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + buffer->Vertices.push_back ( v ); + + } + + u32 nonWrappedSize = ( ( tesselationCylinder * 2 ) - 1 ) * 2; + for ( i = 0; i != nonWrappedSize; i += 2 ) + { + buffer->Indices.push_back ( i + 2 ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( i + 1 ); + + buffer->Indices.push_back ( i + 2 ); + buffer->Indices.push_back ( i + 1 ); + buffer->Indices.push_back ( i + 3 ); + } + + buffer->Indices.push_back ( 0 ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( i + 1 ); + + buffer->Indices.push_back ( 0 ); + buffer->Indices.push_back ( i + 1 ); + buffer->Indices.push_back ( 1 ); + + // close down + v.Pos.X = 0.f; + v.Pos.Y = 0.f; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = -1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back ( v ); + + u32 index = buffer->Vertices.size () - 1; + + for ( i = 0; i != nonWrappedSize; i += 2 ) + { + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( i + 2 ); + } + + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( 0 ); + +/* + // close top + v.Pos.X = 0.f; + v.Pos.Y = cylinderHeight; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = 1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back ( v ); + + index = buffer->Vertices.size () - 1; + + for ( i = 0; i != nonWrappedSize; i += 2 ) + { + buffer->Indices.push_back ( i + 1 ); + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 3 ); + } + + buffer->Indices.push_back ( i + 1 ); + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( 1 ); +*/ + // add to mesh + SMesh* mesh = new SMesh(); + buffer->recalculateBoundingBox(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + // cone + buffer = new SMeshBuffer(); + + angleStep = (core::PI * 2.f ) / tesselationCone; + + v.Color = vtxColor0; + for ( i = 0; i != tesselationCone; ++i ) + { + f32 angle = angleStep * f32(i); + + v.Color = vtxColor0; + v.Pos.X = width1 * cosf ( angle ); + v.Pos.Y = cylinderHeight; + v.Pos.Z = width1 * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + + buffer->Vertices.push_back ( v ); + + angle += angleStep / 2.f; + v.Color = vtxColor1; + v.Pos.X = (width1 * 0.75f ) * cosf ( angle ); + v.Pos.Y = cylinderHeight; + v.Pos.Z = (width1 * 0.75f ) * sinf ( angle ); + v.Normal = v.Pos; + v.Normal.normalize (); + + buffer->Vertices.push_back ( v ); + } + nonWrappedSize = buffer->Vertices.size () - 1; + + // close top + v.Pos.X = 0.f; + v.Pos.Y = height; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = 1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back ( v ); + + index = buffer->Vertices.size () - 1; + + for ( i = 0; i != nonWrappedSize; i += 1 ) + { + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 1 ); + } + + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( 0 ); + + // close down + v.Pos.X = 0.f; + v.Pos.Y = cylinderHeight; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = -1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back ( v ); + + index = buffer->Vertices.size () - 1; + + for ( i = 0; i != nonWrappedSize; i += 1 ) + { + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( i + 1 ); + } + + buffer->Indices.push_back ( index ); + buffer->Indices.push_back ( i + 0 ); + buffer->Indices.push_back ( 0 ); + + // add to already existing mesh + buffer->recalculateBoundingBox(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + mesh->recalculateBoundingBox(); + return mesh; +} + + + +/* A sphere with proper normals and texture coords */ +IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY) +{ + SMeshBuffer* buffer = new SMeshBuffer(); + + // thanks to Alfaz93 who made his code available for Irrlicht on which + // this one is based! + + // we are creating the sphere mesh here. + + if (polyCountX < 2) + polyCountX = 2; + if (polyCountY < 2) + polyCountY = 2; + if (polyCountX * polyCountY > 32767) // prevent u16 overflow + if (polyCountX > polyCountY) // prevent u16 overflow + polyCountX = 32767/polyCountY-1; + else + polyCountY = 32767/(polyCountX+1); + + u32 polyCountXPitch = polyCountX+1; // get to same vertex on next level + buffer->Vertices.set_used((polyCountXPitch * polyCountY) + 2); + buffer->Indices.set_used((polyCountX * polyCountY) * 6); + + video::SColor clr(100, 255,255,255); + + u32 i=0; + u32 level = 0; + + for (u32 p1 = 0; p1 < polyCountY-1; ++p1) + { + //main quads, top to bottom + for (u32 p2 = 0; p2 < polyCountX - 1; ++p2) + { + const u32 curr = level + p2; + buffer->Indices[i] = curr + polyCountXPitch; + buffer->Indices[++i] = curr; + buffer->Indices[++i] = curr + 1; + buffer->Indices[++i] = curr + polyCountXPitch; + buffer->Indices[++i] = curr+1; + buffer->Indices[++i] = curr + 1 + polyCountXPitch; + ++i; + } + + // the connectors from front to end + buffer->Indices[i] = level + polyCountX - 1 + polyCountXPitch; + buffer->Indices[++i] = level + polyCountX - 1; + buffer->Indices[++i] = level + polyCountX; + ++i; + + buffer->Indices[i] = level + polyCountX - 1 + polyCountXPitch; + buffer->Indices[++i] = level + polyCountX; + buffer->Indices[++i] = level + polyCountX + polyCountXPitch; + ++i; + level += polyCountXPitch; + } + + const u32 polyCountSq = polyCountXPitch * polyCountY; // top point + const u32 polyCountSq1 = polyCountSq + 1; // bottom point + const u32 polyCountSqM1 = (polyCountY - 1) * polyCountXPitch; // last row's first vertex + + for (u32 p2 = 0; p2 < polyCountX - 1; ++p2) + { + // create triangles which are at the top of the sphere + + buffer->Indices[i] = polyCountSq; + buffer->Indices[++i] = p2 + 1; + buffer->Indices[++i] = p2; + ++i; + + // create triangles which are at the bottom of the sphere + + buffer->Indices[i] = polyCountSqM1 + p2; + buffer->Indices[++i] = polyCountSqM1 + p2 + 1; + buffer->Indices[++i] = polyCountSq1; + ++i; + } + + // create final triangle which is at the top of the sphere + + buffer->Indices[i] = polyCountSq; + buffer->Indices[++i] = polyCountX; + buffer->Indices[++i] = polyCountX-1; + ++i; + + // create final triangle which is at the bottom of the sphere + + buffer->Indices[i] = polyCountSqM1 + polyCountX - 1; + buffer->Indices[++i] = polyCountSqM1; + buffer->Indices[++i] = polyCountSq1; + + // calculate the angle which separates all points in a circle + const f64 AngleX = 2 * core::PI / polyCountX; + const f64 AngleY = core::PI / polyCountY; + + i = 0; + f64 axz; + + // we don't start at 0. + + f64 ay = 0;//AngleY / 2; + + for (u32 y = 0; y < polyCountY; ++y) + { + ay += AngleY; + const f64 sinay = sin(ay); + axz = 0; + + // calculate the necessary vertices without the doubled one + for (u32 xz = 0;xz < polyCountX; ++xz) + { + // calculate points position + + const core::vector3df pos((f32)(radius * cos(axz) * sinay), + (f32)(radius * cos(ay)), + (f32)(radius * sin(axz) * sinay)); + // for spheres the normal is the position + core::vector3df normal(pos); + normal.normalize(); + + // calculate texture coordinates via sphere mapping + // tu is the same on each level, so only calculate once + f32 tu = 0.5f; + if (y==0) + { + if (normal.Y != -1.0f && normal.Y != 1.0f) + tu = (f32)(acos(core::clamp(normal.X/sinay, -1.0, 1.0)) * 0.5 *core::RECIPROCAL_PI64); + if (normal.Z < 0.0f) + tu=1-tu; + } + else + tu = buffer->Vertices[i-polyCountXPitch].TCoords.X; + buffer->Vertices[i] = video::S3DVertex(pos.X, pos.Y, pos.Z, + normal.X, normal.Y, normal.Z, + clr, tu, + (f32)(ay*core::RECIPROCAL_PI64)); + ++i; + axz += AngleX; + } + // This is the doubled vertex on the initial position + buffer->Vertices[i] = video::S3DVertex(buffer->Vertices[i-polyCountX]); + buffer->Vertices[i].TCoords.X=1.0f; + ++i; + } + + // the vertex at the top of the sphere + buffer->Vertices[i] = video::S3DVertex(0.0f,radius,0.0f, 0.0f,1.0f,0.0f, clr, 0.5f, 0.0f); + + // the vertex at the bottom of the sphere + ++i; + buffer->Vertices[i] = video::S3DVertex(0.0f,-radius,0.0f, 0.0f,-1.0f,0.0f, clr, 0.5f, 1.0f); + + // recalculate bounding box + + buffer->BoundingBox.reset(buffer->Vertices[i].Pos); + buffer->BoundingBox.addInternalPoint(buffer->Vertices[i-1].Pos); + buffer->BoundingBox.addInternalPoint(radius,0.0f,0.0f); + buffer->BoundingBox.addInternalPoint(-radius,0.0f,0.0f); + buffer->BoundingBox.addInternalPoint(0.0f,0.0f,radius); + buffer->BoundingBox.addInternalPoint(0.0f,0.0f,-radius); + + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + mesh->recalculateBoundingBox(); + return mesh; +} + +} // end namespace scene +} // end namespace irr diff --git a/src/dep/src/irrlicht/CGeometryCreator.h b/src/dep/src/irrlicht/CGeometryCreator.h new file mode 100644 index 0000000..4e310cc --- /dev/null +++ b/src/dep/src/irrlicht/CGeometryCreator.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GEOMETRY_CREATOR_H_INCLUDED__ +#define __C_GEOMETRY_CREATOR_H_INCLUDED__ + +#include "IMesh.h" +#include "IImage.h" + + + +namespace irr +{ +namespace video +{ + class IVideoDriver; + class SMaterial; +} + +namespace scene +{ + +//! class for creating geometry on the fly +class CGeometryCreator +{ +public: + + static IMesh* createHillPlaneMesh( + const core::dimension2d& tileSize, const core::dimension2d& tileCount, + video::SMaterial* material, f32 hillHeight, const core::dimension2d& countHills, + const core::dimension2d& textureRepeatCount); + + static IMesh* createTerrainMesh(video::IImage* texture, + video::IImage* heightmap, const core::dimension2d& stretchSize, + f32 maxHeight, video::IVideoDriver* driver, + const core::dimension2d defaultVertexBlockSize, + bool debugBorders=false); + + static IMesh* createArrowMesh(const u32 tesselationCylinder, + const u32 tesselationCone, const f32 height, + const f32 cylinderHeight, const f32 width0, + const f32 width1, const video::SColor vtxColor0, + const video::SColor vtxColor1); + + static IMesh* createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY); +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImage.cpp b/src/dep/src/irrlicht/CImage.cpp new file mode 100644 index 0000000..8a0353d --- /dev/null +++ b/src/dep/src/irrlicht/CImage.cpp @@ -0,0 +1,1436 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImage.h" +#include "irrString.h" +#include "SoftwareDriver2_helper.h" +#include "CColorConverter.h" + +namespace irr +{ + + struct SBlitJob + { + AbsRectangle Dest; + AbsRectangle Source; + + u32 argb; + + void * src; + void * dst; + + s32 width; + s32 height; + + u32 srcPitch; + u32 dstPitch; + + u32 srcPixelMul; + u32 dstPixelMul; + }; + + // Blitter Operation + enum eBlitter + { + BLITTER_INVALID = 0, + BLITTER_COLOR, + BLITTER_COLOR_ALPHA, + BLITTER_TEXTURE, + BLITTER_TEXTURE_ALPHA_BLEND, + BLITTER_TEXTURE_ALPHA_COLOR_BLEND + }; + + typedef void (*tExecuteBlit) ( const SBlitJob * job ); + + + // Bitfields Cohen Sutherland + enum eClipCode + { + CLIPCODE_EMPTY = 0, + CLIPCODE_BOTTOM = 1, + CLIPCODE_TOP = 2, + CLIPCODE_LEFT = 4, + CLIPCODE_RIGHT = 8 + }; + +inline u32 GetClipCode ( const AbsRectangle &r, const core::position2d &p ) +{ + u32 code = CLIPCODE_EMPTY; + + if ( p.X < r.x0 ) + code = CLIPCODE_LEFT; + else + if ( p.X > r.x1 ) + code = CLIPCODE_RIGHT; + + if ( p.Y < r.y0 ) + code |= CLIPCODE_TOP; + else + if ( p.Y > r.y1 ) + code |= CLIPCODE_BOTTOM; + + return code; +} + + +/*! + Cohen Sutherland clipping + @return: 1 if valid +*/ + +static int ClipLine (const AbsRectangle &clipping, + core::position2d &p0, + core::position2d &p1, + const core::position2d& p0_in, + const core::position2d& p1_in) +{ + u32 code0; + u32 code1; + u32 code; + + p0 = p0_in; + p1 = p1_in; + + code0 = GetClipCode ( clipping, p0 ); + code1 = GetClipCode ( clipping, p1 ); + + // trivial accepted + while ( code0 | code1 ) + { + s32 x=0; + s32 y=0; + + // trivial reject + if ( code0 & code1 ) + return 0; + + if ( code0 ) + { + // clip first point + code = code0; + } + else + { + // clip last point + code = code1; + } + + if ( (code & CLIPCODE_BOTTOM) == CLIPCODE_BOTTOM ) + { + // clip bottom viewport + y = clipping.y1; + x = p0.X + ( p1.X - p0.X ) * ( y - p0.Y ) / ( p1.Y - p0.Y ); + } + else + if ( (code & CLIPCODE_TOP) == CLIPCODE_TOP ) + { + // clip to viewport + y = clipping.y0; + x = p0.X + ( p1.X - p0.X ) * ( y - p0.Y ) / ( p1.Y - p0.Y ); + } + else + if ( (code & CLIPCODE_RIGHT) == CLIPCODE_RIGHT ) + { + // clip right viewport + x = clipping.x1; + y = p0.Y + ( p1.Y - p0.Y ) * ( x - p0.X ) / ( p1.X - p0.X ); + } + else + if ( (code & CLIPCODE_LEFT) == CLIPCODE_LEFT ) + { + // clip left viewport + x = clipping.x0; + y = p0.Y + ( p1.Y - p0.Y ) * ( x - p0.X ) / ( p1.X - p0.X ); + } + + if ( code == code0 ) + { + // modify first point + p0.X = x; + p0.Y = y; + code0 = GetClipCode ( clipping, p0 ); + } + else + { + // modify second point + p1.X = x; + p1.Y = y; + code1 = GetClipCode ( clipping, p1 ); + } + } + + return 1; +} + +/* +*/ +inline void GetClip(AbsRectangle &clipping, video::IImage * t) +{ + clipping.x0 = 0; + clipping.y0 = 0; + clipping.x1 = t->getDimension().Width - 1; + clipping.y1 = t->getDimension().Height - 1; +} + +/* +*/ +static void RenderLine32_Decal(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb ) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 4; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u32 *dst; + dst = (u32*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + while ( run ) + { + *dst = argb; + + dst = (u32*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u32*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } + + t->unlock(); +} + + +/* +*/ +static void RenderLine32_Blend(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb, u32 alpha) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 4; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u32 *dst; + dst = (u32*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + while ( run ) + { + *dst = PixelBlend32 ( *dst, argb, alpha ); + + dst = (u32*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u32*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } + + t->unlock(); +} + +/* +*/ +static void RenderLine16_Decal (video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb ) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 2; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u16 *dst; + dst = (u16*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + while ( run ) + { + *dst = argb; + + dst = (u16*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u16*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } + + t->unlock(); +} + +/* +*/ +static void RenderLine16_Blend (video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb, + u32 alpha) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 2; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u16 *dst; + dst = (u16*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + while ( run ) + { + *dst = PixelBlend16 ( *dst, argb, alpha ); + + dst = (u16*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u16*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } + + t->unlock(); +} + + +/*! +*/ +static void executeBlit_TextureCopy_x_to_x ( const SBlitJob * job ) +{ + const void *src = (void*) job->src; + void *dst = (void*) job->dst; + + const u32 widthPitch = job->width * job->dstPixelMul; + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memcpy ( dst, src, widthPitch ); + + src = (void*) ( (u8*) (src) + job->srcPitch ); + dst = (void*) ( (u8*) (dst) + job->dstPitch ); + } +} + + +/*! +*/ +static void executeBlit_TextureCopy_32_to_16 ( const SBlitJob * job ) +{ + const u32 *src = static_cast(job->src); + u16 *dst = static_cast(job->dst); + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + //16 bit Blitter depends on pre-multiplied color + const u32 s = PixelLerp32 ( src[dx] | 0xFF000000, extractAlpha ( src[dx] ) ); + dst[dx] = video::A8R8G8B8toA1R5G5B5 ( s ); + } + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_TextureCopy_24_to_16 ( const SBlitJob * job ) +{ + const void *src = (void*) job->src; + u16 *dst = (u16*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + u8 * s = (u8*) src; + + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = video::RGB16(s[0], s[1], s[2]); + s += 3; + } + + src = (void*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + + +/*! +*/ +static void executeBlit_TextureCopy_16_to_32 ( const SBlitJob * job ) +{ + const u16 *src = (u16*) job->src; + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = video::A1R5G5B5toA8R8G8B8 ( src[dx] ); + } + + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_TextureCopy_24_to_32 ( const SBlitJob * job ) +{ + void *src = (void*) job->src; + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + u8 * s = (u8*) src; + + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2]; + s += 3; + } + + src = (void*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + + +/*! +*/ +static void executeBlit_TextureBlend_16_to_16 ( const SBlitJob * job ) +{ + u32 dx; + s32 dy; + + u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + + const u32 rdx = job->width >> 1; + const u32 off = core::if_c_a_else_b ( job->width & 1 ,job->width - 1, 0 ); + + + if ( 0 == off ) + { + for ( dy = 0; dy != job->height; ++dy ) + { + for ( dx = 0; dx != rdx; ++dx ) + { + dst[dx] = PixelBlend16_simd ( dst[dx], src[dx] ); + } + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + + } + else + { + for ( dy = 0; dy != job->height; ++dy ) + { + for ( dx = 0; dx != rdx; ++dx ) + { + dst[dx] = PixelBlend16_simd ( dst[dx], src[dx] ); + } + + ((u16*) dst)[off] = PixelBlend16 ( ((u16*) dst)[off], ((u16*) src)[off] ); + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + + } +} + +/*! +*/ +static void executeBlit_TextureBlend_32_to_32 ( const SBlitJob * job ) +{ + u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend32 ( dst[dx], src[dx] ); + } + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_TextureBlendColor_16_to_16 ( const SBlitJob * job ) +{ + u16 *src = (u16*) job->src; + u16 *dst = (u16*) job->dst; + + u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb ); + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend16 ( dst[dx], PixelMul16_2 ( src[dx], blend ) ); + } + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + + +/*! +*/ +static void executeBlit_TextureBlendColor_32_to_32 ( const SBlitJob * job ) +{ + u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend32 ( dst[dx], PixelMul32_2 ( src[dx], job->argb ) ); + } + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_Color_16_to_16 ( const SBlitJob * job ) +{ + u16 *dst = (u16*) job->dst; + + u16 c0 = video::A8R8G8B8toA1R5G5B5 ( job->argb ); + u32 c = c0 | c0 << 16; + + if ( 0 == (job->srcPitch & 3 ) ) + { + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memset32 ( dst, c, job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + s32 dx = job->width - 1; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memset32 ( dst, c, job->srcPitch ); + dst[dx] = c0; + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + + } +} + +/*! +*/ +static void executeBlit_Color_32_to_32 ( const SBlitJob * job ) +{ + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memset32 ( dst, job->argb, job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_ColorAlpha_16_to_16 ( const SBlitJob * job ) +{ + u16 *dst = (u16*) job->dst; + + const u32 alpha = extractAlpha ( job->argb ) >> 3; + const u32 src = video::A8R8G8B8toA1R5G5B5 ( job->argb ); + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend16 ( dst[dx], src, alpha ); + } + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_ColorAlpha_32_to_32 ( const SBlitJob * job ) +{ + u32 *dst = (u32*) job->dst; + + const u32 alpha = extractAlpha ( job->argb ); + const u32 src = job->argb; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend32 ( dst[dx], src, alpha ); + } + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static tExecuteBlit getBlitter ( eBlitter operation,const video::IImage * dest,const video::IImage * source ) +{ + video::ECOLOR_FORMAT sourceFormat = (video::ECOLOR_FORMAT) -1; + video::ECOLOR_FORMAT destFormat = (video::ECOLOR_FORMAT) -1; + + if ( source ) + sourceFormat = source->getColorFormat (); + + if ( dest ) + destFormat = dest->getColorFormat (); + + switch ( operation ) + { + case BLITTER_TEXTURE: + { + if ( sourceFormat == destFormat ) + return executeBlit_TextureCopy_x_to_x; + + if ( destFormat == video::ECF_A1R5G5B5 && sourceFormat == video::ECF_A8R8G8B8 ) + return executeBlit_TextureCopy_32_to_16; + + if ( destFormat == video::ECF_A1R5G5B5 && sourceFormat == video::ECF_R8G8B8 ) + return executeBlit_TextureCopy_24_to_16; + + if ( destFormat == video::ECF_A8R8G8B8 && sourceFormat == video::ECF_A1R5G5B5 ) + return executeBlit_TextureCopy_16_to_32; + + if ( destFormat == video::ECF_A8R8G8B8 && sourceFormat == video::ECF_R8G8B8 ) + return executeBlit_TextureCopy_24_to_32; + + } break; + + case BLITTER_TEXTURE_ALPHA_BLEND: + { + if ( destFormat == video::ECF_A1R5G5B5 && sourceFormat == video::ECF_A1R5G5B5 ) + return executeBlit_TextureBlend_16_to_16; + + if ( destFormat == video::ECF_A8R8G8B8 && sourceFormat == video::ECF_A8R8G8B8 ) + return executeBlit_TextureBlend_32_to_32; + + } break; + + case BLITTER_TEXTURE_ALPHA_COLOR_BLEND: + { + if ( destFormat == video::ECF_A1R5G5B5 && sourceFormat == video::ECF_A1R5G5B5 ) + return executeBlit_TextureBlendColor_16_to_16; + + if ( destFormat == video::ECF_A8R8G8B8 && sourceFormat == video::ECF_A8R8G8B8 ) + return executeBlit_TextureBlendColor_32_to_32; + } break; + + case BLITTER_COLOR: + { + if ( destFormat == video::ECF_A1R5G5B5 ) + return executeBlit_Color_16_to_16; + + if ( destFormat == video::ECF_A8R8G8B8 ) + return executeBlit_Color_32_to_32; + } break; + + case BLITTER_COLOR_ALPHA: + { + if ( destFormat == video::ECF_A1R5G5B5 ) + return executeBlit_ColorAlpha_16_to_16; + + if ( destFormat == video::ECF_A8R8G8B8 ) + return executeBlit_ColorAlpha_32_to_32; + + } break; + + case BLITTER_INVALID: + break; + } +/* + char buf[64]; + sprintf ( buf, "Blit: %d %d->%d unsupported",operation,sourceFormat,destFormat ); + os::Printer::log (buf ); +*/ + return 0; + +} + + + +/*! + a generic 2D Blitter +*/ +static s32 Blit ( eBlitter operation, + video::IImage * dest, + const core::rect *destClipping, + const core::position2d *destPos, + video::IImage * const source, + const core::rect *sourceClipping, + u32 argb + ) +{ + tExecuteBlit blitter = getBlitter ( operation, dest, source ); + if ( 0 == blitter ) + { + return 0; + } + + // Clipping + AbsRectangle sourceClip; + AbsRectangle destClip; + AbsRectangle v; + + SBlitJob job; + + if ( sourceClipping ) + { + sourceClip.x0 = sourceClipping->UpperLeftCorner.X; + sourceClip.y0 = sourceClipping->UpperLeftCorner.Y; + sourceClip.x1 = sourceClipping->LowerRightCorner.X; + sourceClip.y1 = sourceClipping->LowerRightCorner.Y; + } + else + { + sourceClip.x0 = 0; + sourceClip.y0 = 0; + sourceClip.x1 = source ? source->getDimension().Width : 0; + sourceClip.y1 = source ? source->getDimension().Height : 0; + } + + if ( destClipping ) + { + destClip.x0 = destClipping->UpperLeftCorner.X; + destClip.y0 = destClipping->UpperLeftCorner.Y; + destClip.x1 = destClipping->LowerRightCorner.X; + destClip.y1 = destClipping->LowerRightCorner.Y; + } + else + { + destClip.x0 = 0; + destClip.y0 = 0; + destClip.x1 = dest ? dest->getDimension().Width : 0; + destClip.y1 = dest ? dest->getDimension().Height : 0; + } + + v.x0 = destPos ? destPos->X : 0; + v.y0 = destPos ? destPos->Y : 0; + v.x1 = v.x0 + ( sourceClip.x1 - sourceClip.x0 ); + v.y1 = v.y0 + ( sourceClip.y1 - sourceClip.y0 ); + + intersect ( job.Dest, destClip, v ); + if ( !isValid ( job.Dest ) ) + return 0; + + job.width = job.Dest.x1 - job.Dest.x0; + job.height = job.Dest.y1 - job.Dest.y0; + + + job.Source.x0 = sourceClip.x0 + ( job.Dest.x0 - v.x0 ); + job.Source.x1 = job.Source.x0 + job.width; + + job.Source.y0 = sourceClip.y0 + ( job.Dest.y0 - v.y0 ); + job.Source.y1 = job.Source.y0 + job.height; + + job.argb = argb; + + if ( source ) + { + job.srcPitch = source->getPitch(); + job.srcPixelMul = source->getBytesPerPixel(); + job.src = (void*) ( (u8*) source->lock() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) ); + } + else + { + // use srcPitch for color operation on dest + job.srcPitch = job.width * dest->getBytesPerPixel(); + } + + job.dstPitch = dest->getPitch(); + job.dstPixelMul = dest->getBytesPerPixel(); + job.dst = (void*) ( (u8*) dest->lock() + ( job.Dest.y0 * job.dstPitch ) + ( job.Dest.x0 * job.dstPixelMul ) ); + + blitter ( &job ); + + if ( source ) + source->unlock (); + + if ( dest ) + dest->unlock(); + + return 1; +} + +} + +namespace irr +{ +namespace video +{ + +//! constructor +CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d& size) +:Data(0), Size(size), Format(format), DeleteMemory(true) +{ + initData(); +} + + +//! constructor +CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d& size, void* data, + bool ownForeignMemory, bool deleteForeignMemory) +: Data(0), Size(size), Format(format), DeleteMemory(deleteForeignMemory) +{ + if (ownForeignMemory) + { + Data = (void*)0xbadf00d; + initData(); + Data = data; + } + else + { + Data = 0; + initData(); + memcpy(Data, data, Size.Height * Pitch); + } +} + + + +//! constructor +CImage::CImage(ECOLOR_FORMAT format, IImage* imageToCopy) +: Data(0), Format(format), DeleteMemory(true) +{ + if (!imageToCopy) + return; + + Size = imageToCopy->getDimension(); + initData(); + + // now copy data from other image + + Blit ( BLITTER_TEXTURE, this, 0, 0, imageToCopy, 0,0 ); +} + + + +//! constructor +CImage::CImage(IImage* imageToCopy, const core::position2d& pos, + const core::dimension2d& size) + : Data(0), Size(0,0), DeleteMemory(true) +{ + if (!imageToCopy) + return; + + Format = imageToCopy->getColorFormat(); + Size = size; + + initData(); + + core::rect sClip( pos.X, pos.Y, pos.X + size.Width,pos.Y + size.Height ); + Blit ( BLITTER_TEXTURE, this, 0, 0, imageToCopy, &sClip,0 ); +} + + + +//! assumes format and size has been set and creates the rest +void CImage::initData() +{ + setBitMasks(); + BitsPerPixel = getBitsPerPixelFromFormat(Format); + BytesPerPixel = BitsPerPixel / 8; + + // Pitch should be aligned... + Pitch = BytesPerPixel * Size.Width; + + if (!Data) + Data = new s8[Size.Height * Pitch]; +} + + +//! destructor +CImage::~CImage() +{ + if ( DeleteMemory ) + delete [] (s8*)Data; +} + + +//! Returns width and height of image data. +const core::dimension2d& CImage::getDimension() const +{ + return Size; +} + + + +//! Returns bits per pixel. +u32 CImage::getBitsPerPixel() const +{ + return BitsPerPixel; +} + + +//! Returns bytes per pixel +u32 CImage::getBytesPerPixel() const +{ + return BytesPerPixel; +} + + + +//! Returns image data size in bytes +u32 CImage::getImageDataSizeInBytes() const +{ + return Pitch * Size.Height; +} + + + +//! Returns image data size in pixels +u32 CImage::getImageDataSizeInPixels() const +{ + return Size.Width * Size.Height; +} + + + +//! returns mask for red value of a pixel +u32 CImage::getRedMask() const +{ + return RedMask; +} + + + +//! returns mask for green value of a pixel +u32 CImage::getGreenMask() const +{ + return GreenMask; +} + + + +//! returns mask for blue value of a pixel +u32 CImage::getBlueMask() const +{ + return BlueMask; +} + + + +//! returns mask for alpha value of a pixel +u32 CImage::getAlphaMask() const +{ + return AlphaMask; +} + + +void CImage::setBitMasks() +{ + switch(Format) + { + case ECF_A1R5G5B5: + AlphaMask = 0x1<<15; + RedMask = 0x1F<<10; + GreenMask = 0x1F<<5; + BlueMask = 0x1F; + break; + case ECF_R5G6B5: + AlphaMask = 0x0; + RedMask = 0x1F<<11; + GreenMask = 0x3F<<5; + BlueMask = 0x1F; + break; + case ECF_R8G8B8: + AlphaMask = 0x0; + RedMask = 0x00FF0000; + GreenMask = 0x0000FF00; + BlueMask = 0x000000FF; + break; + case ECF_A8R8G8B8: + AlphaMask = 0xFF000000; + RedMask = 0x00FF0000; + GreenMask = 0x0000FF00; + BlueMask = 0x000000FF; + break; + } +} + + +u32 CImage::getBitsPerPixelFromFormat(ECOLOR_FORMAT format) +{ + switch(format) + { + case ECF_A1R5G5B5: + return 16; + case ECF_R5G6B5: + return 16; + case ECF_R8G8B8: + return 24; + case ECF_A8R8G8B8: + return 32; + } + + return 0; +} + +//! sets a pixel +void CImage::setPixel(u32 x, u32 y, const SColor &color ) +{ + if (x >= (u32)Size.Width || y >= (u32)Size.Height) + return; + + switch(Format) + { + case ECF_A1R5G5B5: + { + u16 * dest = (u16*) ((u8*) Data + ( y * Pitch ) + ( x << 1 )); + *dest = video::A8R8G8B8toA1R5G5B5 ( color.color ); + } break; + + case ECF_R5G6B5: + { + u16 * dest = (u16*) ((u8*) Data + ( y * Pitch ) + ( x << 1 )); + *dest = video::A8R8G8B8toR5G6B5 ( color.color ); + } break; + + case ECF_R8G8B8: + { + u8* dest = (u8*) Data + ( y * Pitch ) + ( x * 3 ); + dest[0] = color.getRed(); + dest[1] = color.getGreen(); + dest[2] = color.getBlue(); + } break; + + case ECF_A8R8G8B8: + { + u32 * dest = (u32*) ((u8*) Data + ( y * Pitch ) + ( x << 2 )); + *dest = color.color; + } break; + } +} + + +//! returns a pixel +SColor CImage::getPixel(u32 x, u32 y) const +{ + if (x >= (u32)Size.Width || y >= (u32)Size.Height) + return SColor(0); + + switch(Format) + { + case ECF_A1R5G5B5: + return A1R5G5B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]); + case ECF_R5G6B5: + return R5G6B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]); + case ECF_A8R8G8B8: + return ((u32*)Data)[y*Size.Width + x]; + case ECF_R8G8B8: + { + u8* p = &((u8*)Data)[(y*3)*Size.Width + (x*3)]; + return SColor(255,p[0],p[1],p[2]); + } + } + + return SColor(0); +} + + +//! returns the color format +ECOLOR_FORMAT CImage::getColorFormat() const +{ + return Format; +} + +//! draws a rectangle +void CImage::drawRectangle(const core::rect& rect, const SColor &color) +{ + Blit ( color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA, + this, 0, &rect.UpperLeftCorner, 0, &rect, color.color ); +} + + +//! copies this surface into another +void CImage::copyTo(IImage* target, const core::position2d& pos) +{ + Blit ( BLITTER_TEXTURE, target, 0, &pos, this, 0, 0 ); +} + + +//! copies this surface into another +void CImage::copyTo(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect) +{ + Blit ( BLITTER_TEXTURE, target, clipRect, &pos, this, &sourceRect, 0 ); +} + + + +//! copies this surface into another, using the alpha mask, an cliprect and a color to add with +void CImage::copyToWithAlpha(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const SColor &color, const core::rect* clipRect) +{ + // color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF + Blit ( color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND, + target, clipRect, &pos, this, &sourceRect, color.color ); +} + + + +//! draws a line from to with color +void CImage::drawLine(const core::position2d& from, const core::position2d& to, const SColor &color) +{ + AbsRectangle clip; + GetClip ( clip, this ); + + core::position2d p[2]; + + if ( ClipLine ( clip, p[0], p[1], from, to ) ) + { + u32 alpha = extractAlpha ( color.color ); + + switch ( Format ) + { + case ECF_A1R5G5B5: + if ( alpha == 256 ) + { + RenderLine16_Decal ( this, p[0], p[1], video::A8R8G8B8toA1R5G5B5 ( color.color ) ); + } + else + { + RenderLine16_Blend ( this, p[0], p[1], video::A8R8G8B8toA1R5G5B5 ( color.color ), alpha >> 3 ); + } + break; + case ECF_A8R8G8B8: + if ( alpha == 256 ) + { + RenderLine32_Decal ( this, p[0], p[1], color.color ); + } + else + { + RenderLine32_Blend ( this, p[0], p[1], color.color, alpha ); + } + break; + } + } +} + + + +//! copies this surface into another, scaling it to the target image size +// note: this is very very slow. (i didn't want to write a fast version. +// but hopefully, nobody wants to scale surfaces every frame. +void CImage::copyToScaling(void* target, s32 width, s32 height, ECOLOR_FORMAT format, u32 pitch) +{ + if (!target || !width || !height) + return; + + const u32 bpp=getBitsPerPixelFromFormat(format)/8; + if (0==pitch) + pitch = width*bpp; + + if (Format==format && Size.Width==width && Size.Height==height) + { + if (pitch==Pitch) + { + memcpy(target, Data, height*pitch); + return; + } + else + { + u8* tgtpos = (u8*) target; + u8* dstpos = (u8*) Data; + const u32 bwidth = width*bpp; + for (s32 y=0; y& targetSize = target->getDimension(); + + if (targetSize==Size) + { + copyTo(target); + return; + } + + copyToScaling(target->lock(), targetSize.Width, targetSize.Height, target->getColorFormat()); + target->unlock(); +} + +//! copies this surface into another, scaling it to fit it. +void CImage::copyToScalingBoxFilter(IImage* target, s32 bias) +{ + const core::dimension2d destSize = target->getDimension(); + + const f32 sourceXStep = (f32) Size.Width / (f32) destSize.Width; + const f32 sourceYStep = (f32) Size.Height / (f32) destSize.Height; + + target->lock(); + + s32 fx = core::ceil32 ( sourceXStep ); + s32 fy = core::ceil32 ( sourceYStep ); + f32 sx; + f32 sy; + + sy = 0.f; + for ( s32 y = 0; y != destSize.Height; ++y ) + { + sx = 0.f; + for ( s32 x = 0; x != destSize.Width; ++x ) + { + target->setPixel ( x, y, getPixelBox( core::floor32 ( sx ), core::floor32 ( sy ), fx, fy, bias ) ); + sx += sourceXStep; + } + sy += sourceYStep; + } + + target->unlock (); +} + + +//! fills the surface with given color +void CImage::fill(const SColor &color) +{ + u32 c; + + switch ( Format ) + { + case ECF_A1R5G5B5: + c = video::A8R8G8B8toA1R5G5B5 ( color.color ); + c |= c << 16; + break; + case ECF_R5G6B5: + c = video::A8R8G8B8toR5G6B5 ( color.color ); + c |= c << 16; + break; + case ECF_A8R8G8B8: + c = color.color; + break; + default: +// os::Printer::log("CImage::Format not supported", ELL_ERROR); + return; + } + + memset32 ( Data, c, getImageDataSizeInBytes () ); +} + + +//! get a filtered pixel +inline SColor CImage::getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const +{ + SColor c; + s32 a = 0, r = 0, g = 0, b = 0; + + for ( s32 dx = 0; dx != fx; ++dx ) + { + for ( s32 dy = 0; dy != fy; ++dy ) + { + c = getPixel ( x + dx , y + dy ); + + a += c.getAlpha (); + r += c.getRed(); + g += c.getGreen(); + b += c.getBlue(); + } + } + + s32 sdiv = s32_log2_s32(fx * fy); + + a = core::s32_clamp ( ( a >> sdiv ) + bias, 0, 255 ); + r = core::s32_clamp ( ( r >> sdiv ) + bias, 0, 255 ); + g = core::s32_clamp ( ( g >> sdiv ) + bias, 0, 255 ); + b = core::s32_clamp ( ( b >> sdiv ) + bias, 0, 255 ); + + c.set ( a, r, g, b ); + return c; +} + + +} // end namespace video +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CImage.h b/src/dep/src/irrlicht/CImage.h new file mode 100644 index 0000000..4cf97c9 --- /dev/null +++ b/src/dep/src/irrlicht/CImage.h @@ -0,0 +1,152 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_H_INCLUDED__ +#define __C_IMAGE_H_INCLUDED__ + +#include "IImage.h" +#include "rect.h" + +namespace irr +{ +namespace video +{ + +//! IImage implementation with a lot of special image operations for +//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice. +class CImage : public IImage +{ +public: + + //! constructor from another image with format change + CImage(ECOLOR_FORMAT format, IImage* imageToCopy); + + //! constructor from raw image data + //! \param useForeignMemory: If true, the image will use the data pointer + //! directly and own it from now on, which means it will also try to delete [] the + //! data when the image will be destructed. If false, the memory will by copied. + CImage(ECOLOR_FORMAT format, const core::dimension2d& size, + void* data, bool ownForeignMemory=true, bool deleteMemory = true); + + //! constructor for empty image + CImage(ECOLOR_FORMAT format, const core::dimension2d& size); + + //! constructor using a part from another image + CImage(IImage* imageToCopy, + const core::position2d& pos, const core::dimension2d& size); + + //! destructor + virtual ~CImage(); + + //! Lock function. + virtual void* lock() + { + return Data; + }; + + //! Unlock function. + virtual void unlock() {}; + + //! Returns width and height of image data. + virtual const core::dimension2d& getDimension() const; + + //! Returns bits per pixel. + virtual u32 getBitsPerPixel() const; + + //! Returns bytes per pixel + virtual u32 getBytesPerPixel() const; + + //! Returns image data size in bytes + virtual u32 getImageDataSizeInBytes() const; + + //! Returns image data size in pixels + virtual u32 getImageDataSizeInPixels() const; + + //! returns mask for red value of a pixel + virtual u32 getRedMask() const; + + //! returns mask for green value of a pixel + virtual u32 getGreenMask() const; + + //! returns mask for blue value of a pixel + virtual u32 getBlueMask() const; + + //! returns mask for alpha value of a pixel + virtual u32 getAlphaMask() const; + + //! returns a pixel + virtual SColor getPixel(u32 x, u32 y) const; + + //! sets a pixel + virtual void setPixel(u32 x, u32 y, const SColor &color ); + + //! returns the color format + virtual ECOLOR_FORMAT getColorFormat() const; + + //! draws a rectangle + void drawRectangle(const core::rect& rect, const SColor &color); + + //! copies this surface into another + void copyTo(IImage* target, const core::position2d& pos=core::position2d(0,0)); + + //! copies this surface into another + void copyTo(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect=0); + + //! copies this surface into another, using the alpha mask, an cliprect and a color to add with + void copyToWithAlpha(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const SColor &color, const core::rect* clipRect = 0); + + //! copies this surface into another, scaling it to fit. + void copyToScaling(void* target, s32 width, s32 height, ECOLOR_FORMAT format, u32 pitch=0); + + //! copies this surface into another, scaling it to fit. + void copyToScaling(IImage* target); + + //! copies this surface into another, scaling it to fit, appyling a box filter + void copyToScalingBoxFilter(IImage* target, s32 bias = 0); + + //! draws a line from to + void drawLine(const core::position2d& from, const core::position2d& to, const SColor &color); + + //! fills the surface with black or white + void fill(const SColor &color); + + //! returns pitch of image + virtual u32 getPitch() const + { + return Pitch; + } + + static u32 getBitsPerPixelFromFormat(ECOLOR_FORMAT format); + + +private: + + //! assumes format and size has been set and creates the rest + void initData(); + + void setBitMasks(); + + inline SColor getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const; + + void* Data; + core::dimension2d Size; + u32 BitsPerPixel; + u32 BytesPerPixel; + u32 Pitch; + ECOLOR_FORMAT Format; + + bool DeleteMemory; + + u32 RedMask; + u32 GreenMask; + u32 BlueMask; + u32 AlphaMask; +}; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderBMP.cpp b/src/dep/src/irrlicht/CImageLoaderBMP.cpp new file mode 100644 index 0000000..2d6e94c --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderBMP.cpp @@ -0,0 +1,367 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderBMP.h" + +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + +#include "IReadFile.h" +#include "SColor.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderBMP::CImageLoaderBMP() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderBMP"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderBMP::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".bmp") != 0; +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const +{ + u16 headerID; + file->read(&headerID, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + headerID = os::Byteswap::byteswap(headerID); +#endif + return headerID == 0x4d42; +} + + +void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const +{ + u8* p = bmpData; + u8* newBmp = new u8[(width+pitch)*height]; + u8* d = newBmp; + u8* destEnd = newBmp + (width+pitch)*height; + s32 line = 0; + + while (bmpData - p < size && d < destEnd) + { + if (*p == 0) + { + ++p; + + switch(*p) + { + case 0: // end of line + ++p; + ++line; + d = newBmp + (line*(width+pitch)); + break; + case 1: // end of bmp + delete [] bmpData; + bmpData = newBmp; + return; + case 2: + ++p; d +=(u8)*p; // delta + ++p; d += ((u8)*p)*(width+pitch); + ++p; + break; + default: + { + // absolute mode + s32 count = (u8)*p; ++p; + s32 readAdditional = ((2-(count%2))%2); + s32 i; + + for (i=0; i> readShift) & 0x0f; + readShift -= 4; + if (readShift < 0) + { + ++*p; + readShift = 4; + } + + u8 mask = 0x0f << shift; + *d = (*d & (~mask)) | ((color << shift) & mask); + + shift -= 4; + if (shift < 0) + { + shift = 4; + ++d; + } + + } + + for (i=0; i> 4) & 0x0f; + ++p; + + for (s32 i=0; iread(&header, sizeof(header)); + +#ifdef __BIG_ENDIAN__ + header.Id = os::Byteswap::byteswap(header.Id); + header.FileSize = os::Byteswap::byteswap(header.FileSize); + header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset); + header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize); + header.Width = os::Byteswap::byteswap(header.Width); + header.Height = os::Byteswap::byteswap(header.Height); + header.Planes = os::Byteswap::byteswap(header.Planes); + header.BPP = os::Byteswap::byteswap(header.BPP); + header.Compression = os::Byteswap::byteswap(header.Compression); + header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize); + header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX); + header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY); + header.Colors = os::Byteswap::byteswap(header.Colors); + header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors); +#endif + + s32 pitch = 0; + + //! return if the header is false + + if (header.Id != 0x4d42) + return 0; + + if (header.Compression > 2) // we'll only handle RLE-Compression + { + os::Printer::log("Compression mode not supported.", ELL_ERROR); + return 0; + } + + // adjust bitmap data size to dword boundary + header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4; + + // read palette + + long pos = file->getPos(); + s32 paletteSize = (header.BitmapDataOffset - pos) / 4; + + s32* paletteData = 0; + if (paletteSize) + { + paletteData = new s32[paletteSize]; + file->read(paletteData, paletteSize * sizeof(s32)); +#ifdef __BIG_ENDIAN__ + for (s32 i=0; i(file->getSize()) - header.BitmapDataOffset; + } + + file->seek(header.BitmapDataOffset); + + f32 t = (header.Width) * (header.BPP / 8.0f); + s32 widthInBytes = (s32)t; + t -= widthInBytes; + if (t!=0.0f) + ++widthInBytes; + + s32 lineData = widthInBytes + ((4-(widthInBytes%4)))%4; + pitch = lineData - widthInBytes; + + u8* bmpData = new u8[header.BitmapDataSize]; + file->read(bmpData, header.BitmapDataSize); + + // decompress data if needed + switch(header.Compression) + { + case 1: // 8 bit rle + decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); + break; + case 2: // 4 bit rle + decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); + break; + } + + // create surface + + IImage* image = 0; + switch(header.BPP) + { + case 1: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); + break; + case 4: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); + break; + case 8: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); + break; + case 16: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); + break; + case 24: + image = new CImage(ECF_R8G8B8, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->lock(), header.Width, header.Height, pitch, true, true); + break; + case 32: // thx to Reinhard Ostermeier + image = new CImage(ECF_A8R8G8B8, core::dimension2d(header.Width, header.Height)); + if (image) + CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->lock(), header.Width, header.Height, pitch, true); + break; + }; + if (image) + image->unlock(); + + // clean up + + delete [] paletteData; + delete [] bmpData; + + return image; +} + + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderBMP() +{ + return new CImageLoaderBMP; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderBMP.h b/src/dep/src/irrlicht/CImageLoaderBMP.h new file mode 100644 index 0000000..c4de366 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderBMP.h @@ -0,0 +1,110 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_BMP_H_INCLUDED__ +#define __C_IMAGE_LOADER_BMP_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + +#include "IImageLoader.h" + + +namespace irr +{ +namespace video +{ + + + // byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + struct SBMPHeader + { + u16 Id; // BM - Windows 3.1x, 95, NT, 98, 2000, ME, XP + // BA - OS/2 Bitmap Array + // CI - OS/2 Color Icon + // CP - OS/2 Color Pointer + // IC - OS/2 Icon + // PT - OS/2 Pointer + u32 FileSize; + u32 Reserved; + u32 BitmapDataOffset; + u32 BitmapHeaderSize; // should be 28h for windows bitmaps or + // 0Ch for OS/2 1.x or F0h for OS/2 2.x + u32 Width; + u32 Height; + u16 Planes; + u16 BPP; // 1: Monochrome bitmap + // 4: 16 color bitmap + // 8: 256 color bitmap + // 16: 16bit (high color) bitmap + // 24: 24bit (true color) bitmap + // 32: 32bit (true color) bitmap + + u32 Compression; // 0: none (Also identified by BI_RGB) + // 1: RLE 8-bit / pixel (Also identified by BI_RLE4) + // 2: RLE 4-bit / pixel (Also identified by BI_RLE8) + // 3: Bitfields (Also identified by BI_BITFIELDS) + + u32 BitmapDataSize; // Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary. + u32 PixelPerMeterX; + u32 PixelPerMeterY; + u32 Colors; + u32 ImportantColors; + } PACK_STRUCT; + + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + +/*! + Surface Loader for Windows bitmaps +*/ +class CImageLoaderBMP : public IImageLoader +{ +public: + + //! constructor + CImageLoaderBMP(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + void decompress8BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const; + + void decompress4BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const; +}; + + +} // end namespace video +} // end namespace irr + + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderJPG.cpp b/src/dep/src/irrlicht/CImageLoaderJPG.cpp new file mode 100644 index 0000000..fb4a6b2 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderJPG.cpp @@ -0,0 +1,260 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderJPG.h" + +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + +#include "IReadFile.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CImageLoaderJPG::CImageLoaderJPG() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderJPG"); + #endif +} + + + +//! destructor +CImageLoaderJPG::~CImageLoaderJPG() +{ +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderJPG::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".jpg") != 0; +} + + +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ + + // struct for handling jpeg errors + struct irr_jpeg_error_mgr + { + // public jpeg error fields + struct jpeg_error_mgr pub; + + // for longjmp, to return to caller on a fatal error + jmp_buf setjmp_buffer; + }; + +void CImageLoaderJPG::init_source (j_decompress_ptr cinfo) +{ + // DO NOTHING +} + + + +boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo) +{ + // DO NOTHING + return 1; +} + + + +void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count) +{ + jpeg_source_mgr * src = cinfo->src; + if(count > 0) + { + src->bytes_in_buffer -= count; + src->next_input_byte += count; + } +} + + + +void CImageLoaderJPG::term_source (j_decompress_ptr cinfo) +{ + // DO NOTHING +} + + +void CImageLoaderJPG::error_exit (j_common_ptr cinfo) +{ + // unfortunately we need to use a goto rather than throwing an exception + // as gcc crashes under linux crashes when using throw from within + // extern c code + + // Always display the message + (*cinfo->err->output_message) (cinfo); + + // cinfo->err really points to a irr_error_mgr struct + irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err; + + longjmp(myerr->setjmp_buffer, 1); +} + + +void CImageLoaderJPG::output_message(j_common_ptr cinfo) +{ + // display the error message. + c8 temp1[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, temp1); + os::Printer::log("JPEG FATAL ERROR",temp1, ELL_ERROR); +} +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const +{ + #ifndef _IRR_COMPILE_WITH_LIBJPEG_ + return false; + #else + + if (!file) + return false; + + s32 jfif = 0; + file->seek(6); + file->read(&jfif, sizeof(s32)); + return (jfif == 0x4a464946 || jfif == 0x4649464a); + + #endif +} + +//! creates a surface from the file +IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const +{ + #ifndef _IRR_COMPILE_WITH_LIBJPEG_ + return 0; + #else + + u8 **rowPtr=0; + u8* input = new u8[file->getSize()]; + file->read(input, file->getSize()); + + // allocate and initialize JPEG decompression object + struct jpeg_decompress_struct cinfo; + struct irr_jpeg_error_mgr jerr; + + //We have to set up the error handler first, in case the initialization + //step fails. (Unlikely, but it could happen if you are out of memory.) + //This routine fills in the contents of struct jerr, and returns jerr's + //address which we place into the link field in cinfo. + + cinfo.err = jpeg_std_error(&jerr.pub); + cinfo.err->error_exit = error_exit; + cinfo.err->output_message = output_message; + + // compatibility fudge: + // we need to use setjmp/longjmp for error handling as gcc-linux + // crashes when throwing within external c code + if (setjmp(jerr.setjmp_buffer)) + { + // If we get here, the JPEG code has signaled an error. + // We need to clean up the JPEG object and return. + + jpeg_destroy_decompress(&cinfo); + + delete [] input; + // if the row pointer was created, we delete it. + if (rowPtr) + delete [] rowPtr; + + // return null pointer + return 0; + } + + // Now we can initialize the JPEG decompression object. + jpeg_create_decompress(&cinfo); + + // specify data source + jpeg_source_mgr jsrc; + + // Set up data pointer + jsrc.bytes_in_buffer = file->getSize(); + jsrc.next_input_byte = (JOCTET*)input; + cinfo.src = &jsrc; + + jsrc.init_source = init_source; + jsrc.fill_input_buffer = fill_input_buffer; + jsrc.skip_input_data = skip_input_data; + jsrc.resync_to_restart = jpeg_resync_to_restart; + jsrc.term_source = term_source; + + // Decodes JPG input from whatever source + // Does everything AFTER jpeg_create_decompress + // and BEFORE jpeg_destroy_decompress + // Caller is responsible for arranging these + setting up cinfo + + // read file parameters with jpeg_read_header() + jpeg_read_header(&cinfo, TRUE); + + cinfo.out_color_space=JCS_RGB; + cinfo.out_color_components=3; + cinfo.do_fancy_upsampling=FALSE; + + // Start decompressor + jpeg_start_decompress(&cinfo); + + // Get image data + u16 rowspan = cinfo.image_width * cinfo.out_color_components; + u32 width = cinfo.image_width; + u32 height = cinfo.image_height; + + // Allocate memory for buffer + u8* output = new u8[rowspan * height]; + + // Here we use the library's state variable cinfo.output_scanline as the + // loop counter, so that we don't have to keep track ourselves. + // Create array of row pointers for lib + rowPtr = new u8* [height]; + + for( u32 i = 0; i < height; i++ ) + rowPtr[i] = &output[ i * rowspan ]; + + u32 rowsRead = 0; + + while( cinfo.output_scanline < cinfo.output_height ) + rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead ); + + delete [] rowPtr; + // Finish decompression + + jpeg_finish_decompress(&cinfo); + + // Release JPEG decompression object + // This is an important step since it will release a good deal of memory. + jpeg_destroy_decompress(&cinfo); + + // convert image + IImage* image = new CImage(ECF_R8G8B8, + core::dimension2d(width, height), output); + + delete [] input; + + return image; + + #endif +} + + + +//! creates a loader which is able to load jpeg images +IImageLoader* createImageLoaderJPG() +{ + return new CImageLoaderJPG(); +} + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderJPG.h b/src/dep/src/irrlicht/CImageLoaderJPG.h new file mode 100644 index 0000000..83d15f3 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderJPG.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_JPG_H_INCLUDED__ +#define __C_IMAGE_LOADER_JPG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + +#include "IImageLoader.h" + +#include // required for jpeglib.h +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ +extern "C" { + #ifndef _IRR_USE_NON_SYSTEM_JPEG_LIB_ + #include // use system lib + #else + #include "jpeglib/jpeglib.h" // use irrlicht jpeglib + #endif + #include +} +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + + +namespace irr +{ +namespace video +{ + + +//! Surface Loader for JPG images +class CImageLoaderJPG : public IImageLoader +{ +public: + + //! constructor + CImageLoaderJPG(); + + //! destructor + virtual ~CImageLoaderJPG(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + #ifdef _IRR_COMPILE_WITH_LIBJPEG_ + // several methods used via function pointers by jpeglib + + /* Receives control for a fatal error. Information sufficient to + generate the error message has been stored in cinfo->err; call + output_message to display it. Control must NOT return to the caller; + generally this routine will exit() or longjmp() somewhere. + Typically you would override this routine to get rid of the exit() + default behavior. Note that if you continue processing, you should + clean up the JPEG object with jpeg_abort() or jpeg_destroy(). + */ + static void error_exit (j_common_ptr cinfo); + + /* output error messages via Irrlicht logger. */ + static void output_message(j_common_ptr cinfo); + + /* Initialize source. This is called by jpeg_read_header() before any + data is actually read. Unlike init_destination(), it may leave + bytes_in_buffer set to 0 (in which case a fill_input_buffer() call + will occur immediately). */ + static void init_source (j_decompress_ptr cinfo); + + /* This is called whenever bytes_in_buffer has reached zero and more + data is wanted. In typical applications, it should read fresh data + into the buffer (ignoring the current state of next_input_byte and + bytes_in_buffer), reset the pointer & count to the start of the + buffer, and return TRUE indicating that the buffer has been reloaded. + It is not necessary to fill the buffer entirely, only to obtain at + least one more byte. bytes_in_buffer MUST be set to a positive value + if TRUE is returned. A FALSE return should only be used when I/O + suspension is desired (this mode is discussed in the next section). */ + static boolean fill_input_buffer (j_decompress_ptr cinfo); + + /* Skip num_bytes worth of data. The buffer pointer and count should + be advanced over num_bytes input bytes, refilling the buffer as + needed. This is used to skip over a potentially large amount of + uninteresting data (such as an APPn marker). In some applications + it may be possible to optimize away the reading of the skipped data, + but it's not clear that being smart is worth much trouble; large + skips are uncommon. bytes_in_buffer may be zero on return. + A zero or negative skip count should be treated as a no-op. */ + static void skip_input_data (j_decompress_ptr cinfo, long num_bytes); + + /* Terminate source --- called by jpeg_finish_decompress() after all + data has been read. Often a no-op. */ + static void term_source (j_decompress_ptr cinfo); + + #endif // _IRR_COMPILE_WITH_LIBJPEG_ +}; + + +} // end namespace video +} // end namespace irr + + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPCX.cpp b/src/dep/src/irrlicht/CImageLoaderPCX.cpp new file mode 100644 index 0000000..596989f --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPCX.cpp @@ -0,0 +1,188 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPCX.h" + +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + +#include "IReadFile.h" +#include "SColor.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPCX::CImageLoaderPCX() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPCX"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPCX::isALoadableFileExtension(const c8* fileName) const +{ + return (strstr(fileName, ".PCX") != 0) || (strstr(fileName, ".pcx") != 0); +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPCX::isALoadableFileFormat(io::IReadFile* file) const +{ + u8 headerID; + file->read(&headerID, sizeof(headerID)); + return headerID == 0x0a; +} + + +//! creates a image from the file +IImage* CImageLoaderPCX::loadImage(io::IReadFile* file) const +{ + SPCXHeader header; + s32* paletteData = 0; + + file->read(&header, sizeof(header)); + #ifdef __BIG_ENDIAN__ + header.XMin = os::Byteswap::byteswap(header.XMin); + header.YMin = os::Byteswap::byteswap(header.YMin); + header.XMax = os::Byteswap::byteswap(header.XMax); + header.YMax = os::Byteswap::byteswap(header.YMax); + header.HorizDPI = os::Byteswap::byteswap(header.HorizDPI); + header.VertDPI = os::Byteswap::byteswap(header.VertDPI); + header.BytesPerLine = os::Byteswap::byteswap(header.BytesPerLine); + header.PaletteType = os::Byteswap::byteswap(header.PaletteType); + header.HScrSize = os::Byteswap::byteswap(header.HScrSize); + header.VScrSize = os::Byteswap::byteswap(header.VScrSize); + #endif + + //! return if the header is wrong + if (header.Manufacturer != 0x0a && header.Encoding != 0x01) + return 0; + + // return if this isn't a supported type + if( (header.BitsPerPixel != 8) && (header.BitsPerPixel != 24) ) + { + os::Printer::log("Unsupported bits per pixel in PCX file.", + file->getFileName(), irr::ELL_WARNING); + return 0; + } + + // read palette + if( header.BitsPerPixel == 8 ) + { + // the palette indicator (usually a 0x0c is found infront of the actual palette data) + // is ignored because some exporters seem to forget to write it. This would result in + // no image loaded before, now only wrong colors will be set. + const long pos = file->getPos(); + file->seek( file->getSize()-256*3, false ); + + u8 *tempPalette = new u8[768]; + paletteData = new s32[256]; + memset(paletteData, 0xFF, 256*sizeof(s32)); + file->read( tempPalette, 768 ); + + for( s32 i=0; i<256; i++ ) + { + paletteData[i] = (tempPalette[i*3+0] << 16) | + (tempPalette[i*3+1] << 8) | + (tempPalette[i*3+2] ); + } + + delete [] tempPalette; + + file->seek( pos ); + } + else if( header.BitsPerPixel == 4 ) + { + paletteData = new s32[16]; + memset(paletteData, 0, 16*sizeof(s32)); + for( s32 i=0; i<256; i++ ) + { + paletteData[i] = (header.Palette[i*3+0] << 16) | + (header.Palette[i*3+1] << 8) | + (header.Palette[i*3+2]); + } + } + + // read image data + s32 width, height, imagebytes; + width = header.XMax - header.XMin + 1; + height = header.YMax - header.YMin + 1; + imagebytes = header.BytesPerLine * height * header.Planes * header.BitsPerPixel / 8; + u8* PCXData = new u8[imagebytes]; + + u8 cnt, value; + for( s32 offset = 0; offset < imagebytes; ) + { + file->read( &cnt, 1 ); + if( !((cnt & 0xc0) == 0xc0) ) + { + value = cnt; + cnt = 1; + } + else + { + cnt &= 0x3f; + file->read( &value, 1 ); + } + memset(PCXData+offset, value, cnt); + offset += cnt; + } + + // create image + video::IImage* image = 0; + s32 pitch = header.BytesPerLine - width * header.Planes * header.BitsPerPixel / 8; + + if (pitch < 0) + pitch = -pitch; + + switch(header.BitsPerPixel) // TODO: Other formats + { + case 8: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(width, height)); + if (image) + CColorConverter::convert8BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pitch); + break; + case 24: + image = new CImage(ECF_R8G8B8, core::dimension2d(width, height)); + if (image) + CColorConverter::convert24BitTo24Bit(PCXData, (u8*)image->lock(), width, height, pitch); + break; + }; + if (image) + image->unlock(); + + // clean up + + delete [] paletteData; + delete [] PCXData; + + return image; +} + + +//! creates a loader which is able to load pcx images +IImageLoader* createImageLoaderPCX() +{ + return new CImageLoaderPCX(); +} + + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPCX.h b/src/dep/src/irrlicht/CImageLoaderPCX.h new file mode 100644 index 0000000..268ad61 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPCX.h @@ -0,0 +1,92 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_PCX_H_INCLUDED__ +#define __C_IMAGE_LOADER_PCX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + struct SPCXHeader + { + u8 Manufacturer; + u8 Version; + u8 Encoding; + u8 BitsPerPixel; + u16 XMin; + u16 YMin; + u16 XMax; + u16 YMax; + u16 HorizDPI; + u16 VertDPI; + u8 Palette[48]; + u8 Reserved; + u8 Planes; + u16 BytesPerLine; + u16 PaletteType; + u16 HScrSize; + u16 VScrSize; + u8 Filler[54]; + } PACK_STRUCT; + + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + +/*! + Image Loader for Windows PCX bitmaps. + This loader was written and sent in by Dean P. Macri. I modified + only some small bits of it. +*/ +class CImageLoaderPCX : public IImageLoader +{ +public: + + //! constructor + CImageLoaderPCX(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPNG.cpp b/src/dep/src/irrlicht/CImageLoaderPNG.cpp new file mode 100644 index 0000000..52827a9 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPNG.cpp @@ -0,0 +1,272 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPNG.h" + +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + #ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include // use system lib png + #else // _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include "libpng/png.h" // use irrlicht included lib png + #endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +#include "CImage.h" +#include "CReadFile.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +// PNG function for error handling +static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG FATAL ERROR", msg, ELL_ERROR); + longjmp(png_ptr->jmpbuf, 1); +} + +// PNG function for file reading +void PNGAPI user_read_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + // changed by zola { + io::IReadFile* file=(io::IReadFile*)png_ptr->io_ptr; + check=(png_size_t) file->read((void*)data,length); + // } + + if (check != length) + png_error(png_ptr, "Read Error"); +} +#endif // _IRR_COMPILE_WITH_LIBPNG_ + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPng::isALoadableFileExtension(const c8* fileName) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + // added fix for file extension check by jox + const c8* ext = strrchr(fileName, '.'); + if (ext == 0) + return false; + return (strcmp(ext, ".PNG") == 0) || (strcmp(ext, ".png") == 0); +#else + return false; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file) + return false; + + png_byte buffer[8]; + // Read the first few bytes of the PNG file + if (file->read(buffer, 8) != 8) + return false; + + // Check if it really is a PNG file + return !png_sig_cmp(buffer, 0, 8); +#else + return false; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + +// load in the image data +IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file) + return 0; + + video::IImage* image = 0; + //Used to point to image rows + u8** RowPointers = 0; + + png_byte buffer[8]; + // Read the first few bytes of the PNG file + if( file->read(buffer, 8) != 8 ) + { + os::Printer::log("LOAD PNG: can't read file\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Check if it really is a PNG file + if( png_sig_cmp(buffer, 0, 8) ) + { + os::Printer::log("LOAD PNG: not really a png\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Allocate the png read struct + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, (png_error_ptr)png_cpexcept_error, NULL); + if (!png_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create read struct failure\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Allocate the png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 0; + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + if (RowPointers) + delete [] RowPointers; + return 0; + } + + // changed by zola so we don't need to have public FILE pointers + png_set_read_fn(png_ptr, file, user_read_data_fcn); + + png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature + + png_read_info(png_ptr, info_ptr); // Read the info section of the png file + + u32 Width; + u32 Height; + s32 BitDepth; + s32 ColorType; + { + // Use temporary variables to avoid passing casted pointers + png_uint_32 w,h; + // Extract info + png_get_IHDR(png_ptr, info_ptr, + &w, &h, + &BitDepth, &ColorType, NULL, NULL, NULL); + Width=w; + Height=h; + } + + // Convert palette color to true color + if (ColorType==PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + // Convert low bit colors to 8 bit colors + if (BitDepth < 8) + { + if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_1_2_4_to_8(png_ptr); + else + png_set_packing(png_ptr); + } + + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + + // Convert high bit colors to 8 bit colors + if (BitDepth == 16) + png_set_strip_16(png_ptr); + + // Convert gray color to true color + if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + // Update the changes + png_read_update_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, + (png_uint_32*)&Width, (png_uint_32*)&Height, + &BitDepth, &ColorType, NULL, NULL, NULL); + + // Convert RGBA to BGRA + if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) + { +#ifdef __BIG_ENDIAN__ + png_set_swap_alpha(png_ptr); +#else + png_set_bgr(png_ptr); +#endif + } + + // Update the changes + png_get_IHDR(png_ptr, info_ptr, + (png_uint_32*)&Width, (png_uint_32*)&Height, + &BitDepth, &ColorType, NULL, NULL, NULL); + + // Create the image structure to be filled by png data + if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) + image = new CImage(ECF_A8R8G8B8, core::dimension2d(Width, Height)); + else + image = new CImage(ECF_R8G8B8, core::dimension2d(Width, Height)); + if (!image) + { + os::Printer::log("LOAD PNG: Internal PNG create image struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 0; + } + + // Create array of pointers to rows in image data + RowPointers = new png_bytep[Height]; + if (!RowPointers) + { + os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + delete image; + return 0; + } + + // Fill array of pointers to rows in image data + unsigned char* data = (unsigned char*)image->lock(); + for (u32 i=0; igetPitch(); + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + delete [] RowPointers; + image->unlock(); + delete [] image; + return 0; + } + + // Read data using the library function that handles all transformations including interlacing + png_read_image(png_ptr, RowPointers); + + png_read_end(png_ptr, NULL); + delete [] RowPointers; + image->unlock(); + png_destroy_read_struct(&png_ptr,&info_ptr, 0); // Clean up memory + + return image; +#else + return 0; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + + +IImageLoader* createImageLoaderPNG() +{ + return new CImageLoaderPng(); +} + + +}// end namespace irr +}//end namespace video + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPNG.h b/src/dep/src/irrlicht/CImageLoaderPNG.h new file mode 100644 index 0000000..fc49b02 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPNG.h @@ -0,0 +1,45 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// this file was created by rt (www.tomkorp.com), based on ttk's png-reader +// i wanted to be able to read in PNG images with irrlicht :) +// why? lossless compression with 8-bit alpha channel! + +#ifndef __C_IMAGE_LOADER_PNG_H_INCLUDED__ +#define __C_IMAGE_LOADER_PNG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +//! Surface Loader for PNG files +class CImageLoaderPng : public IImageLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".png") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPPM.cpp b/src/dep/src/irrlicht/CImageLoaderPPM.cpp new file mode 100644 index 0000000..cab1122 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPPM.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2007 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPPM.h" + +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + +#include "IReadFile.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "fast_atof.h" +#include "coreutil.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPPM::CImageLoaderPPM() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPPM"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPPM::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".ppm") || strstr(fileName, ".pgm") || strstr(fileName, ".pbm"); +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPPM::isALoadableFileFormat(io::IReadFile* file) const +{ + c8 id[2]; + file->read(&id, 2); + return (id[0]=='P' && id[1]>'0' && id[1]<'7'); +} + + +//! creates a surface from the file +IImage* CImageLoaderPPM::loadImage(io::IReadFile* file) const +{ + IImage* image; + + if (file->getSize() < 12) + return 0; + + c8 id[2]; + file->read(&id, 2); + + if (id[0]!='P' || id[1]<'1' || id[1]>'6') + return 0; + + const u8 format = id[1] - '0'; + const bool binary = format>3; + + core::stringc token; + getNextToken(file, token); + const u32 width = core::strtol10(token.c_str()); + + getNextToken(file, token); + const u32 height = core::strtol10(token.c_str()); + + u8* data = 0; + const u32 size = width*height; + if (format==1 || format==4) + { + skipToNextToken(file); // go to start of data + + const u32 bytesize = size/8+(size & 3)?1:0; + if (binary) + { + if (file->getSize()-file->getPos() < (long)bytesize) + return 0; + data = new u8[bytesize]; + file->read(data, bytesize); + } + else + { + if (file->getSize()-file->getPos() < (long)(2*size)) // optimistic test + return 0; + data = new u8[bytesize]; + memset(data, 0, bytesize); + u32 shift=0; + for (u32 i=0; i(width, height)); + if (image) + CColorConverter::convert1BitTo16Bit(data, (s16*)image->lock(), width, height); + } + else + { + getNextToken(file, token); + const u32 maxDepth = core::strtol10(token.c_str()); + if (maxDepth > 255) // no double bytes yet + return 0; + + skipToNextToken(file); // go to start of data + + if (format==2 || format==5) + { + if (binary) + { + if (file->getSize()-file->getPos() < (long)size) + return 0; + data = new u8[size]; + file->read(data, size); + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)(2*size)) // optimistic test + return 0; + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)bytesize) + return 0; + data = new u8[bytesize]; + file->read(data, bytesize); + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)(2*bytesize)) // optimistic test + return 0; + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; iunlock(); + + delete [] data; + + return image; +} + + +//! read the next token from file +void CImageLoaderPPM::getNextToken(io::IReadFile* file, core::stringc& token) const +{ + token = ""; + c8 c; + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + { + token.append(c); + break; + } + } + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + token.append(c); + else + break; + } +} + + +//! skip to next token (skip whitespace) +void CImageLoaderPPM::skipToNextToken(io::IReadFile* file) const +{ + c8 c; + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + { + file->seek(-1, true); // put back + break; + } + } +} + + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderPPM() +{ + return new CImageLoaderPPM; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPPM.h b/src/dep/src/irrlicht/CImageLoaderPPM.h new file mode 100644 index 0000000..b1b7561 --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPPM.h @@ -0,0 +1,55 @@ +// Copyright (C) 2007 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_PPM_H_INCLUDED__ +#define __C_IMAGE_LOADER_PPM_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + +#include "IImageLoader.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +/*! + Surface Loader for SUN Pixmaps +*/ +class CImageLoaderPPM : public IImageLoader +{ +public: + + //! constructor + CImageLoaderPPM(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + //! read the next token from file + void getNextToken(io::IReadFile* file, core::stringc& token) const; + //! skip to next token (skip whitespace) + void skipToNextToken(io::IReadFile* file) const; +}; + +} // end namespace video +} // end namespace irr + + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderPSD.cpp b/src/dep/src/irrlicht/CImageLoaderPSD.cpp new file mode 100644 index 0000000..9ba417a --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderPSD.cpp @@ -0,0 +1,375 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPSD.h" + +#ifdef _IRR_COMPILE_WITH_PSD_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CImage.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPSD::CImageLoaderPSD() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPSD"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPSD::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".psd") != 0; +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPSD::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + u8 type[3]; + file->read(&type, sizeof(u8)*3); + return (type[2]==2); // we currently only handle tgas of type 2. +} + + + +//! creates a surface from the file +IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const +{ + u32* imageData = 0; + + PsdHeader header; + file->read(&header, sizeof(PsdHeader)); + +#ifndef __BIG_ENDIAN__ + header.version = os::Byteswap::byteswap(header.version); + header.channels = os::Byteswap::byteswap(header.channels); + header.height = os::Byteswap::byteswap(header.height); + header.width = os::Byteswap::byteswap(header.width); + header.depth = os::Byteswap::byteswap(header.depth); + header.mode = os::Byteswap::byteswap(header.mode); +#endif + + if (header.signature[0] != '8' || + header.signature[1] != 'B' || + header.signature[2] != 'P' || + header.signature[3] != 'S') + return 0; + + if (header.version != 1) + { + os::Printer::log("Unsupported PSD file version", file->getFileName(), ELL_ERROR); + return 0; + } + + if (header.mode != 3 || header.depth != 8) + { + os::Printer::log("Unsupported PSD color mode or depth.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip color mode data + + u32 l; + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image resources.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip image resources + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to layer and mask.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip layer & mask + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image data section.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // read image data + + u16 compressionType; + file->read(&compressionType, sizeof(u16)); +#ifndef __BIG_ENDIAN__ + compressionType = os::Byteswap::byteswap(compressionType); +#endif + + if (compressionType != 1 && compressionType != 0) + { + os::Printer::log("Unsupported psd compression mode.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // create image data block + + imageData = new u32[header.width * header.height]; + + bool res = false; + + if (compressionType == 0) + res = readRawImageData(file, header, imageData); // RAW image data + else + res = readRLEImageData(file, header, imageData); // RLE compressed data + + video::IImage* image = 0; + + if (res) + { + // create surface + image = new CImage(ECF_A8R8G8B8, + core::dimension2d(header.width, header.height), imageData); + } + + if (!image) + delete [] imageData; + imageData = 0; + + return image; +} + + +bool CImageLoaderPSD::readRawImageData(io::IReadFile* file, const PsdHeader& header, u32* imageData) const +{ + u8* tmpData = new u8[header.width * header.height]; + + for (s32 channel=0; channelread(tmpData, sizeof(c8) * header.width * header.height)) + { + os::Printer::log("Error reading color channel\n", file->getFileName(), ELL_ERROR); + break; + } + + s16 shift = getShiftFromChannel(channel, header); + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; xread(&rleCount[y], sizeof(u16))) + { + delete [] tmpData; + delete [] rleCount; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + +#ifndef __BIG_ENDIAN__ + rleCount[y] = os::Byteswap::byteswap(rleCount[y]); +#endif + size += rleCount[y]; + } + + s8 *buf = new s8[size]; + if (!file->read(buf, size)) + { + delete [] rleCount; + delete [] buf; + delete [] tmpData; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + + u16 *rcount=rleCount; + + s8 rh; + u16 bytesRead; + u8 *dest; + s8 *pBuf = buf; + + // decompress packbit rle + + for (s32 channel=0; channel= 0) + { + ++rh; + + while (rh--) + { + *dest = *pBuf++; + ++bytesRead; + ++dest; + } + } + else + if (rh > -128) + { + rh = -rh +1; + + while (rh--) + { + *dest = *pBuf; + ++dest; + } + + ++pBuf; + ++bytesRead; + } + } + } + + s16 shift = getShiftFromChannel(channel, header); + + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; xread(&chunkheader, sizeof(u8)); // Read The Chunk's Header + + if(chunkheader < 128) // If The Chunk Is A 'RAW' Chunk + { + chunkheader++; // Add 1 To The Value To Get Total Number Of Raw Pixels + + file->read(&data[currentByte], bytesPerPixel * chunkheader); + currentByte += bytesPerPixel * chunkheader; + } + else + { + // thnx to neojzs for some fixes with this code + + // If It's An RLE Header + chunkheader -= 127; // Subtract 127 To Get Rid Of The ID Bit + + s32 dataOffset = currentByte; + file->read(&data[dataOffset], bytesPerPixel); + + currentByte += bytesPerPixel; + + for(s32 counter = 1; counter < chunkheader; counter++) + { + for(s32 elementCounter=0; elementCounter < bytesPerPixel; elementCounter++) + data[currentByte + elementCounter] = data[dataOffset + elementCounter]; + + currentByte += bytesPerPixel; + } + } + } + + return data; +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderTGA::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + STGAFooter footer; + memset(&footer, 0, sizeof(STGAFooter)); + file->seek(file->getSize()-sizeof(STGAFooter)); + file->read(&footer, sizeof(STGAFooter)); + return (!strcmp(footer.Signature,"TRUEVISION-XFILE.")); // very old tgas are refused. +} + + + +//! creates a surface from the file +IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const +{ + STGAHeader header; + u8* colorMap = 0; + + file->read(&header, sizeof(STGAHeader)); + +#ifdef __BIG_ENDIAN__ + header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength); + header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth); + header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight); +#endif + + // skip image identification field + if (header.IdLength) + file->seek(header.IdLength, true); + + if (header.ColorMapType) + { + // read color map + colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength]; + file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength); + } + + // read image + + u8* data = 0; + + if (header.ImageType == 2) + { + const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8; + data = new u8[imageSize]; + file->read(data, imageSize); + } + else + if(header.ImageType == 10) + data = loadCompressedImage(file, header); + else + { + os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR); + if (colorMap) + delete [] colorMap; + return 0; + } + + IImage* image = 0; + + switch(header.PixelDepth) + { + case 16: + { + image = new CImage(ECF_A1R5G5B5, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert16BitTo16Bit((s16*)data, + (s16*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); + } + break; + case 24: + { + image = new CImage(ECF_R8G8B8, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert24BitTo24Bit( + (u8*)data, (u8*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true); + } + break; + case 32: + { + image = new CImage(ECF_A8R8G8B8, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert32BitTo32Bit((s32*)data, + (s32*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); + } + break; + default: + os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR); + break; + } + if (image) + image->unlock(); + delete [] data; + if (colorMap) + delete [] colorMap; + + return image; +} + + + +//! creates a loader which is able to load tgas +IImageLoader* createImageLoaderTGA() +{ + return new CImageLoaderTGA(); +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageLoaderTGA.h b/src/dep/src/irrlicht/CImageLoaderTGA.h new file mode 100644 index 0000000..b37002b --- /dev/null +++ b/src/dep/src/irrlicht/CImageLoaderTGA.h @@ -0,0 +1,91 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_TGA_H_INCLUDED__ +#define __C_IMAGE_LOADER_TGA_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_TGA_LOADER_ + +#include "IImageLoader.h" + + +namespace irr +{ +namespace video +{ + + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# define PACK_STRUCT +#endif + + // these structs are also used in the TGA writer + struct STGAHeader{ + u8 IdLength; + u8 ColorMapType; + u8 ImageType; + u8 FirstEntryIndex[2]; + u16 ColorMapLength; + u8 ColorMapEntrySize; + u8 XOrigin[2]; + u8 YOrigin[2]; + u16 ImageWidth; + u16 ImageHeight; + u8 PixelDepth; + u8 ImageDescriptor; + } PACK_STRUCT; + + struct STGAFooter + { + u32 ExtensionOffset; + u32 DeveloperOffset; + c8 Signature[18]; + } PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + +/*! + Surface Loader for targa images +*/ +class CImageLoaderTGA : public IImageLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + //! loads a compressed tga. Was written and sent in by Jon Pry, thank you very much! + u8* loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterBMP.cpp b/src/dep/src/irrlicht/CImageWriterBMP.cpp new file mode 100644 index 0000000..2bd1a38 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterBMP.cpp @@ -0,0 +1,136 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterBMP.h" + +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + +#include "CImageLoaderBMP.h" +#include "IWriteFile.h" +#include "CColorConverter.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterBMP() +{ + return new CImageWriterBMP; +} + +CImageWriterBMP::CImageWriterBMP() +{ +#ifdef _DEBUG + setDebugName("CImageWriterBMP"); +#endif +} + +bool CImageWriterBMP::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".bmp") != 0; +} + +bool CImageWriterBMP::writeImage(io::IWriteFile* file, IImage* image, u32 param) const +{ + // we always write 24-bit color because nothing really reads 32-bit + + SBMPHeader imageHeader; + imageHeader.Id = 0x4d42; + imageHeader.Reserved = 0; + imageHeader.BitmapDataOffset = sizeof(imageHeader); + imageHeader.BitmapHeaderSize = 0x28; + imageHeader.Width = image->getDimension().Width; + imageHeader.Height = image->getDimension().Height; + imageHeader.Planes = 1; + imageHeader.BPP = 24; + imageHeader.Compression = 0; + imageHeader.PixelPerMeterX = 0; + imageHeader.PixelPerMeterY = 0; + imageHeader.Colors = 0; + imageHeader.ImportantColors = 0; + + // data size is rounded up to next larger 4 bytes boundary + imageHeader.BitmapDataSize = imageHeader.Width * imageHeader.BPP / 8; + imageHeader.BitmapDataSize = (imageHeader.BitmapDataSize + 3) & ~3; + imageHeader.BitmapDataSize *= imageHeader.Height; + + // file size is data size plus offset to data + imageHeader.FileSize = imageHeader.BitmapDataOffset + imageHeader.BitmapDataSize; + + // bitmaps are stored upside down and padded so we always do this + void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0; + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R8G8B8toR8G8B8; + break; + case ECF_A8R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A8R8G8B8toB8G8R8; + break; + case ECF_A1R5G5B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A1R5G5B5toR8G8B8; + break; + case ECF_R5G6B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R5G6B5toR8G8B8; + break; + } + + // couldn't find a color converter + if (!CColorConverter_convertFORMATtoFORMAT) + return false; + + // write the bitmap header + if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader)) + return false; + + u8* scan_lines = (u8*)image->lock(); + if (!scan_lines) + return false; + + // size of one pixel in bytes + u32 pixel_size = image->getBytesPerPixel(); + + // length of one row of the source image in bytes + u32 row_stride = (pixel_size * imageHeader.Width); + + // length of one row in bytes, rounded up to nearest 4-byte boundary + s32 row_size = ((3 * imageHeader.Width) + 3) & ~3; + + // allocate and clear memory for our scan line + u8* row_pointer = new u8[row_size]; + memset(row_pointer, 0, row_size); + + // convert the image to 24-bit BGR and flip it over + s32 y; + for (y = imageHeader.Height - 1; 0 <= y; --y) + { + if (image->getColorFormat()==ECF_R8G8B8) + CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.Width, 1, 0, false, true); + else + // source, length [pixels], destination + CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.Width, row_pointer); + if (file->write(row_pointer, row_size) < row_size) + break; + } + + // clean up our scratch area + delete [] row_pointer; + + // give back image handle + image->unlock(); + + return y < 0; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterBMP.h b/src/dep/src/irrlicht/CImageWriterBMP.h new file mode 100644 index 0000000..ddd4f1e --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterBMP.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_BMP_H_INCLUDED__ +#define _C_IMAGE_WRITER_BMP_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterBMP : public IImageWriter +{ +public: + //! constructor + CImageWriterBMP(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif +#endif // _C_IMAGE_WRITER_BMP_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CImageWriterJPG.cpp b/src/dep/src/irrlicht/CImageWriterJPG.cpp new file mode 100644 index 0000000..a30f3a6 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterJPG.cpp @@ -0,0 +1,236 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterJPG.h" + +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + +#include "CColorConverter.h" +#include "IWriteFile.h" +#include "CImage.h" +#include "CColorConverter.h" +#include "irrString.h" + +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ +#include // required for jpeglib.h +extern "C" +{ +#ifndef _IRR_USE_NON_SYSTEM_JPEG_LIB_ + #include + #include +#else + #include "jpeglib/jpeglib.h" + #include "jpeglib/jerror.h" +#endif +#include +} + + +namespace irr +{ +namespace video +{ + + +typedef struct +{ + struct jpeg_destination_mgr pub; /* public fields */ + + JOCTET * buffer; /* image buffer */ + u32 buffer_size; /* image buffer size */ +} mem_destination_mgr; + + +typedef mem_destination_mgr * mem_dest_ptr; + +void init_destination (j_compress_ptr cinfo) +{ + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + + /* image buffer must be allocated before mem_dest routines are called. */ + if(dest->buffer == NULL) { + //fprintf(stderr, "jmem_dest: init_destination: buffer not allocated\n"); + } + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = dest->buffer_size; +} + + +boolean empty_output_buffer (j_compress_ptr cinfo) +{ + /* + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + */ + // empty_output_buffer: buffer should not ever be full\n"); + return FALSE; +} + + +void term_destination (j_compress_ptr cinfo) +{ + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + size_t datacount = dest->buffer_size - dest->pub.free_in_buffer; +} + +void jpeg_memory_dest (j_compress_ptr cinfo, u8 *jfif_buffer, + s32 buf_size) +{ + mem_dest_ptr dest; + + if(jfif_buffer == NULL) { + //fprintf(stderr, "jpeg_memory_dest: memory buffer needs to be allocated\n"); + //ERREXIT(cinfo, JERR_BUFFER_SIZE); + return; + } + + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + (size_t) sizeof(mem_destination_mgr)); + } + + dest = (mem_dest_ptr) cinfo->dest; /* for casting */ + + /* Initialize method pointers */ + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + + /* Initialize private member */ + dest->buffer = (JOCTET*)jfif_buffer; + dest->buffer_size = buf_size; +} + +/* write_JPEG_memory: store JPEG compressed image into memory. +*/ +void write_JPEG_memory (void *img_buf, s32 width, s32 height, u32 bpp, u32 pitch, + u8 *jpeg_buffer, u32 jpeg_buffer_size, + s32 quality, u32 *jpeg_comp_size) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + + /* More stuff */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_memory_dest(&cinfo, jpeg_buffer, jpeg_buffer_size); + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = bpp; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = (u8*) img_buf + (cinfo.next_scanline * pitch ); + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + /* Step 6: Finish compression */ + jpeg_finish_compress(&cinfo); + + { + mem_dest_ptr dest = (mem_dest_ptr) cinfo.dest; + *jpeg_comp_size = dest->buffer_size - dest->pub.free_in_buffer; + } + + jpeg_destroy_compress(&cinfo); +} + +} // namespace video +} // namespace irr + +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterJPG() +{ + return new CImageWriterJPG; +} + +CImageWriterJPG::CImageWriterJPG() +{ +#ifdef _DEBUG + setDebugName("CImageWriterJPG"); +#endif +} + + +bool CImageWriterJPG::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".jpg") != 0 || strstr(fileName, ".jpeg") != 0; +} + + +bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *input,u32 quality) const +{ +#ifndef _IRR_COMPILE_WITH_LIBJPEG_ + return false; +#else + + core::dimension2di dim = input->getDimension(); + IImage * image = new CImage(ECF_R8G8B8, dim ); + + void (*format)(const void*, s32, void*) = 0; + switch( input->getColorFormat () ) + { + case ECF_R8G8B8: format = CColorConverter::convert_R8G8B8toR8G8B8; break; + case ECF_A8R8G8B8: format = CColorConverter::convert_A8R8G8B8toR8G8B8; break; + case ECF_A1R5G5B5: format = CColorConverter::convert_A1R5G5B5toB8G8R8; break; + case ECF_R5G6B5: format = CColorConverter::convert_R5G6B5toR8G8B8; break; + } + + // couldn't find a color converter + if ( 0 == format ) + return false; + + s32 y; + void *src = input->lock(); + void *dst = image->lock(); + for ( y = 0; y!= dim.Height; ++y ) + { + format( src, dim.Width, dst ); + src = (void*) ( (u8*) src + input->getPitch () ); + dst = (void*) ( (u8*) dst + image->getPitch () ); + } + input->unlock (); + image->unlock (); + + // temp buffer + u32 destSize = image->getImageDataSizeInBytes (); + u8 * dest = new u8 [ destSize ]; + + if ( 0 == quality ) + quality = 75; + + write_JPEG_memory ( image->lock (), dim.Width, dim.Height, + image->getBytesPerPixel(), image->getPitch(), + dest, destSize, + quality, + &destSize); + + file->write ( dest, destSize ); + + image->drop (); + delete [] dest; + + return true; +#endif +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterJPG.h b/src/dep/src/irrlicht/CImageWriterJPG.h new file mode 100644 index 0000000..a990a8a --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterJPG.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_JPG_H_INCLUDED__ +#define _C_IMAGE_WRITER_JPG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterJPG : public IImageWriter +{ +public: + //! constructor + CImageWriterJPG(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} +} + +#endif // _C_IMAGE_WRITER_JPG_H_INCLUDED__ +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPCX.cpp b/src/dep/src/irrlicht/CImageWriterPCX.cpp new file mode 100644 index 0000000..8d23a88 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPCX.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPCX.h" + +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + +#include "CImageLoaderPCX.h" +#include "IWriteFile.h" +#include "os.h" // for logging +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPCX() +{ + return new CImageWriterPCX; +} + +CImageWriterPCX::CImageWriterPCX() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPCX"); +#endif +} + +bool CImageWriterPCX::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".pcx") != 0; +} + +bool CImageWriterPCX::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + os::Printer::log("PCX writer not yet implemented. Image not written.", ELL_WARNING); + return false; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPCX.h b/src/dep/src/irrlicht/CImageWriterPCX.h new file mode 100644 index 0000000..70ce87a --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPCX.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PCX_H_INCLUDED__ +#define _C_IMAGE_WRITER_PCX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPCX : public IImageWriter +{ +public: + //! constructor + CImageWriterPCX(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif +#endif // _C_IMAGE_WRITER_PCX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CImageWriterPNG.cpp b/src/dep/src/irrlicht/CImageWriterPNG.cpp new file mode 100644 index 0000000..9d2eb07 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPNG.cpp @@ -0,0 +1,208 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPNG.h" + +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + +#include "CImageLoaderPNG.h" +#include "CColorConverter.h" +#include "IWriteFile.h" +#include "irrString.h" +#include "os.h" // for logging + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +#ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include // use system lib png +#else // _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include "libpng/png.h" // use irrlicht included lib png +#endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPNG() +{ + return new CImageWriterPNG; +} + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +// PNG function for error handling +static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG FATAL ERROR", msg, ELL_ERROR); + longjmp(png_ptr->jmpbuf, 1); +} + +// PNG function for file writing +void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + io::IWriteFile* file=(io::IWriteFile*)png_ptr->io_ptr; + check=(png_size_t) file->write((void*)data,length); + + if (check != length) + png_error(png_ptr, "Write Error"); +} +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +CImageWriterPNG::CImageWriterPNG() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPNG"); +#endif +} + +bool CImageWriterPNG::isAWriteableFileExtension(const c8* fileName) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + return strstr(fileName, ".png") != 0; +#else + return false; +#endif +} + +bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file || !image) + return false; + + // Allocate the png write struct + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + NULL, (png_error_ptr)png_cpexcept_error, NULL); + if (!png_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); + return false; + } + + // Allocate the png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, NULL); + return false; + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; + } + + png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL); + + // Set info + switch(image->getColorFormat()) + { + case ECF_A8R8G8B8: + case ECF_A1R5G5B5: + png_set_IHDR(png_ptr, info_ptr, + image->getDimension().Width, image->getDimension().Height, + 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + break; + default: + png_set_IHDR(png_ptr, info_ptr, + image->getDimension().Width, image->getDimension().Height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + + s32 lineWidth=image->getDimension().Width; + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_R5G6B5: + lineWidth*=3; + break; + case ECF_A8R8G8B8: + case ECF_A1R5G5B5: + lineWidth*=4; + break; + } + u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; + if (!tmpImage) + { + os::Printer::log("LOAD PNG: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; + } + + u8* data = (u8*)image->lock(); + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_A8R8G8B8: + CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_R5G6B5: + CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_A1R5G5B5: + CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + } + image->unlock(); + + // Create array of pointers to rows in image data + + //Used to point to image rows + u8** RowPointers = new png_bytep[image->getDimension().Height]; + if (!RowPointers) + { + os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, &info_ptr); + delete [] tmpImage; + return false; + } + + data=tmpImage; + // Fill array of pointers to rows in image data + for (s32 i=0; igetDimension().Height; ++i) + { + RowPointers[i]=data; + data += lineWidth; + } + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + delete [] RowPointers; + delete [] tmpImage; + return false; + } + + png_set_rows(png_ptr, info_ptr, RowPointers); + + if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5) + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL); + else + { + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + } + + delete [] RowPointers; + delete [] tmpImage; + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; +#else + return false; +#endif +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPNG.h b/src/dep/src/irrlicht/CImageWriterPNG.h new file mode 100644 index 0000000..a13a940 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPNG.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PNG_H_INCLUDED__ +#define _C_IMAGE_WRITER_PNG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPNG : public IImageWriter +{ +public: + //! constructor + CImageWriterPNG(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_PNG_H_INCLUDED__ +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPPM.cpp b/src/dep/src/irrlicht/CImageWriterPPM.cpp new file mode 100644 index 0000000..2a3fd11 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPPM.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPPM.h" + +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + +#include "IWriteFile.h" +#include "IImage.h" +#include "dimension2d.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + + +IImageWriter* createImageWriterPPM() +{ + return new CImageWriterPPM; +} + + +CImageWriterPPM::CImageWriterPPM() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPPM"); +#endif +} + + +bool CImageWriterPPM::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".ppm") != 0; +} + + +bool CImageWriterPPM::writeImage(io::IWriteFile *file, IImage *image, u32 param) const +{ + char cache[70]; + char size; + + const core::dimension2d& imageSize = image->getDimension(); + + const bool binary = false; + + if (binary) + size = snprintf(cache, 70, "P6\n"); + else + size = snprintf(cache, 70, "P3\n"); + + if (file->write(cache, size) != size) + return false; + + size = snprintf(cache, 70, "%d %d\n", imageSize.Width, imageSize.Height); + if (file->write(cache, size) != size) + return false; + + size = snprintf(cache, 70, "255\n"); + if (file->write(cache, size) != size) + return false; + + if (binary) + { + for (s32 h = 0; h < imageSize.Height; ++h) + { + for (s32 c = 0; c < imageSize.Width; ++c) + { + const video::SColor& pixel = image->getPixel(c, h); + const u8 r = pixel.getRed() & 0xff; + const u8 g = pixel.getGreen() & 0xff; + const u8 b = pixel.getBlue() & 0xff; + file->write(&r, 1); + file->write(&g, 1); + file->write(&b, 1); + } + } + } + else + { + s32 n = 0; + + for (s32 h = 0; h < imageSize.Height; ++h) + { + for (s32 c = 0; c < imageSize.Width; ++c, ++n) + { + const video::SColor& pixel = image->getPixel(c, h); + size = snprintf(cache, 70, "%.3u %.3u %.3u%s", pixel.getRed(), pixel.getGreen(), pixel.getBlue(), n % 5 == 4 ? "\n" : " "); + if (file->write(cache, size) != size) + return false; + } + } + } + + return true; +} + + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPPM.h b/src/dep/src/irrlicht/CImageWriterPPM.h new file mode 100644 index 0000000..c09bc36 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPPM.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PPM_H_INCLUDED__ +#define _C_IMAGE_WRITER_PPM_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPPM : public IImageWriter +{ +public: + //! constructor + CImageWriterPPM(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_PPM_H_INCLUDED__ +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPSD.cpp b/src/dep/src/irrlicht/CImageWriterPSD.cpp new file mode 100644 index 0000000..9471f71 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPSD.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPSD.h" + +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + +#include "CImageLoaderPSD.h" +#include "IWriteFile.h" +#include "os.h" // for logging +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPSD() +{ + return new CImageWriterPSD; +} + +CImageWriterPSD::CImageWriterPSD() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPSD"); +#endif +} + +bool CImageWriterPSD::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".psd") != 0; +} + +bool CImageWriterPSD::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + os::Printer::log("PSD writer not yet implemented. Image not written.", ELL_WARNING); + return false; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterPSD.h b/src/dep/src/irrlicht/CImageWriterPSD.h new file mode 100644 index 0000000..9028a6f --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterPSD.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PSD_H_INCLUDED__ +#define _C_IMAGE_WRITER_PSD_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPSD : public IImageWriter +{ +public: + //! constructor + CImageWriterPSD(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image,u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _I_IMAGE_WRITER_PSD_H_INCLUDED__ +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterTGA.cpp b/src/dep/src/irrlicht/CImageWriterTGA.cpp new file mode 100644 index 0000000..6a9b358 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterTGA.cpp @@ -0,0 +1,143 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterTGA.h" + +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + +#include "CImageLoaderTGA.h" +#include "IWriteFile.h" +#include "CColorConverter.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterTGA() +{ + return new CImageWriterTGA; +} + +CImageWriterTGA::CImageWriterTGA() +{ +#ifdef _DEBUG + setDebugName("CImageWriterTGA"); +#endif +} + +bool CImageWriterTGA::isAWriteableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".tga") != 0; +} + +bool CImageWriterTGA::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + STGAHeader imageHeader; + imageHeader.IdLength = 0; + imageHeader.ColorMapType = 0; + imageHeader.ImageType = 2; + imageHeader.FirstEntryIndex[0] = 0; + imageHeader.FirstEntryIndex[1] = 0; + imageHeader.ColorMapLength = 0; + imageHeader.ColorMapEntrySize = 0; + imageHeader.XOrigin[0] = 0; + imageHeader.XOrigin[1] = 0; + imageHeader.YOrigin[0] = 0; + imageHeader.YOrigin[1] = 0; + imageHeader.ImageWidth = image->getDimension().Width; + imageHeader.ImageHeight = image->getDimension().Height; + + // top left of image is the top. the image loader needs to + // be fixed to only swap/flip + imageHeader.ImageDescriptor = (1 << 5); + + // chances are good we'll need to swizzle data, so i'm going + // to convert and write one scan line at a time. it's also + // a bit cleaner this way + void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0; + switch(image->getColorFormat()) + { + case ECF_A8R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A8R8G8B8toA8R8G8B8; + imageHeader.PixelDepth = 32; + imageHeader.ImageDescriptor |= 8; + break; + case ECF_A1R5G5B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A1R5G5B5toA1R5G5B5; + imageHeader.PixelDepth = 16; + imageHeader.ImageDescriptor |= 1; + break; + case ECF_R5G6B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R5G6B5toA1R5G5B5; + imageHeader.PixelDepth = 16; + imageHeader.ImageDescriptor |= 1; + break; + case ECF_R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R8G8B8toR8G8B8; + imageHeader.PixelDepth = 24; + imageHeader.ImageDescriptor |= 0; + break; + } + + // couldn't find a color converter + if (!CColorConverter_convertFORMATtoFORMAT) + return false; + + if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader)) + return false; + + u8* scan_lines = (u8*)image->lock(); + if (!scan_lines) + return false; + + // size of one pixel in bytes + u32 pixel_size = image->getBytesPerPixel(); + + // length of one row of the source image in bytes + u32 row_stride = (pixel_size * imageHeader.ImageWidth); + + // length of one output row in bytes + s32 row_size = ((imageHeader.PixelDepth / 8) * imageHeader.ImageWidth); + + // allocate a row do translate data into + u8* row_pointer = new u8[row_size]; + + u32 y; + for (y = 0; y < imageHeader.ImageHeight; ++y) + { + // source, length [pixels], destination + if (image->getColorFormat()==ECF_R8G8B8) + CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.ImageWidth, 1, 0, 0, true); + else + CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.ImageWidth, row_pointer); + if (file->write(row_pointer, row_size) != row_size) + break; + } + + delete [] row_pointer; + + image->unlock(); + + STGAFooter imageFooter; + imageFooter.ExtensionOffset = 0; + imageFooter.DeveloperOffset = 0; + strncpy(imageFooter.Signature, "TRUEVISION-XFILE.", 18); + + if (file->write(&imageFooter, sizeof(imageFooter)) < (s32)sizeof(imageFooter)) + return false; + + return imageHeader.ImageHeight < y; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CImageWriterTGA.h b/src/dep/src/irrlicht/CImageWriterTGA.h new file mode 100644 index 0000000..e74ae88 --- /dev/null +++ b/src/dep/src/irrlicht/CImageWriterTGA.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_TGA_H_INCLUDED__ +#define _C_IMAGE_WRITER_TGA_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterTGA : public IImageWriter +{ +public: + //! constructor + CImageWriterTGA(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const c8* fileName) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image,u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_TGA_H_INCLUDED__ +#endif + diff --git a/src/dep/src/irrlicht/CIrrDeviceLinux.cpp b/src/dep/src/irrlicht/CIrrDeviceLinux.cpp new file mode 100644 index 0000000..1941b24 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceLinux.cpp @@ -0,0 +1,1339 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceLinux.h" + +#ifdef _IRR_USE_LINUX_DEVICE_ + +#include +#include +#include +#include +#include "IEventReceiver.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include "COSOperator.h" +#include "CColorConverter.h" +#include "SIrrCreationParameters.h" +#include + +namespace irr +{ + namespace video + { + IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias); + } +} // end namespace irr + + + +namespace irr +{ + +const char* wmDeleteWindow = "WM_DELETE_WINDOW"; + +//! constructor +CIrrDeviceLinux::CIrrDeviceLinux(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, bool fullscreen, + bool sbuffer, bool vsync, bool antiAlias, + IEventReceiver* receiver, + const char* version) + : CIrrDeviceStub(version, receiver), +#ifdef _IRR_COMPILE_WITH_X11_ + display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0), +#endif + Fullscreen(fullscreen), StencilBuffer(sbuffer), AntiAlias(antiAlias), DriverType(driverType), + Width(windowSize.Width), Height(windowSize.Height), Depth(24), + Close(false), WindowActive(false), WindowMinimized(false), UseXVidMode(false), UseXRandR(false), UseGLXWindow(false), AutorepeatSupport(0) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceLinux"); + #endif + + // print version, distribution etc. + // thx to LynxLuna for pointing me to the uname function + core::stringc linuxversion; + struct utsname LinuxInfo; + uname(&LinuxInfo); + + linuxversion += LinuxInfo.sysname; + linuxversion += " "; + linuxversion += LinuxInfo.release; + linuxversion += " "; + linuxversion += LinuxInfo.version; + linuxversion += " "; + linuxversion += LinuxInfo.machine; + + Operator = new COSOperator(linuxversion.c_str()); + os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); + + // create keymap + createKeyMap(); + + // create window + if (driverType != video::EDT_NULL) + { + // create the window, only if we do not use the null device + if (!createWindow(windowSize, bits)) + return; + } + + // create cursor control + CursorControl = new CCursorControl(this, driverType == video::EDT_NULL); + + // create driver + createDriver(windowSize, vsync); + + if (!VideoDriver) + return; + + createGUIAndScene(); +} + + + +//! destructor +CIrrDeviceLinux::~CIrrDeviceLinux() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (StdHints) + XFree(StdHints); + if (display) + { + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (Context) + { + if (!glXMakeCurrent(display, None, NULL)) + os::Printer::log("Could not release glx context.", ELL_WARNING); + glXDestroyContext(display, Context); + if (UseGLXWindow) + glXDestroyWindow(display, glxWin); + Context = 0; + } + #endif // #ifdef _IRR_COMPILE_WITH_OPENGL_ + + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (UseXVidMode && Fullscreen) + { + XF86VidModeSwitchToMode(display, screennr, &oldVideoMode); + XF86VidModeSetViewPort(display, screennr, 0, 0); + } + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (UseXRandR && Fullscreen) + { + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + XRRSetScreenConfig(display,config,DefaultRootWindow(display),oldRandrMode,oldRandrRotation,CurrentTime); + XRRFreeScreenConfigInfo(config); + } + #endif + + if (DriverType == video::EDT_SOFTWARE || DriverType == video::EDT_BURNINGSVIDEO) + XDestroyImage(SoftwareImage); + XDestroyWindow(display,window); + XCloseDisplay(display); + } + if (visual) + XFree(visual); + +#endif // #ifdef _IRR_COMPILE_WITH_X11_ +} + + + +#if defined(_IRR_COMPILE_WITH_X11_) && defined(_DEBUG) +int IrrPrintXError(Display *display, XErrorEvent *event) +{ + char msg[256]; + + XGetErrorText(display, event->error_code, msg, 256); + os::Printer::log("XErrorEvent", msg, ELL_WARNING); + return 0; +} +#endif + + + +bool CIrrDeviceLinux::createWindow(const core::dimension2d& windowSize, + u32 bits) +{ + Width = windowSize.Width; + Height = windowSize.Height; + +#ifdef _IRR_COMPILE_WITH_X11_ +#ifdef _DEBUG + os::Printer::log("Creating X window...", ELL_INFORMATION); + XSetErrorHandler(IrrPrintXError); +#endif + + display = XOpenDisplay(0); + if (!display) + { + os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR); + return false; + } + + screennr = DefaultScreen(display); + + // query extension + + if (Fullscreen) + { + s32 eventbase, errorbase; + s32 bestMode = -1; + s32 defaultDepth=DefaultDepth(display,screennr); + + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + // enumerate video modes + s32 modeCount; + XF86VidModeModeInfo** modes; + + XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); + + // save current video mode + oldVideoMode = *modes[0]; + + // find fitting mode + + VideoModeList.setDesktop(defaultDepth, core::dimension2d( + modes[0]->hdisplay, modes[0]->vdisplay)); + for (s32 i = 0; ihdisplay >= Width && modes[i]->vdisplay >= Height) + bestMode = i; + else if (bestMode!=-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height && modes[i]->hdisplay < modes[bestMode]->hdisplay && modes[i]->vdisplay < modes[bestMode]->vdisplay) + bestMode = i; + VideoModeList.addMode(core::dimension2d( + modes[i]->hdisplay, modes[i]->vdisplay), defaultDepth); + } + if (bestMode != -1) + { + os::Printer::log("Starting fullscreen mode...", ELL_INFORMATION); + XF86VidModeSwitchToMode(display, screennr, modes[bestMode]); + XF86VidModeSetViewPort(display, screennr, 0, 0); + UseXVidMode=true; + } + else + { + os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING); + Fullscreen = false; + } + + XFree(modes); + } + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + s32 modeCount; + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + oldRandrMode=XRRConfigCurrentConfiguration(config,&oldRandrRotation); + XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); + VideoModeList.setDesktop(defaultDepth, core::dimension2d( + modes[oldRandrMode].width, modes[oldRandrMode].height)); + for (s32 i = 0; i= Width && (u32)modes[i].height >= Height) + bestMode = i; + else if (bestMode!=-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height && modes[i].width < modes[bestMode].width && modes[i].height < modes[bestMode].height) + bestMode = i; + VideoModeList.addMode(core::dimension2d( + modes[i].width, modes[i].height), defaultDepth); + } + if (bestMode != -1) + { + XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime); + UseXRandR=true; + } + XRRFreeScreenConfigInfo(config); + } + else + #endif + { + os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht " + "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING); + Fullscreen = false; + } + } + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + + Context=0; + GLXFBConfig glxFBConfig; + int major, minor; + bool isAvailableGLX=false; + if (DriverType==video::EDT_OPENGL) + { + isAvailableGLX=glXQueryExtension(display,&major,&minor); + if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) + { + if (major==1 && minor>2) + { + const int MAX_SAMPLES = 16; + // attribute array for the draw buffer + int visualAttrBuffer[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + GLX_ALPHA_SIZE, 4, + GLX_DEPTH_SIZE, 16, + GLX_DOUBLEBUFFER, GL_TRUE, + GLX_STENCIL_SIZE, 1, + GLX_SAMPLE_BUFFERS_ARB, GL_TRUE, + GLX_SAMPLES_ARB, MAX_SAMPLES, + None + }; + + GLXFBConfig *configList=0; + int nitems=0; + if (!AntiAlias) + { + visualAttrBuffer[17] = GL_FALSE; + visualAttrBuffer[19] = 0; + } + if (StencilBuffer) + { + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] >>= 1; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = GL_FALSE; + visualAttrBuffer[19] = 0; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + AntiAlias=false; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = GL_TRUE; + visualAttrBuffer[19] = MAX_SAMPLES; + } + } + } + } + // Next try without stencil buffer + if (!configList) + { + if (StencilBuffer) + os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING); + StencilBuffer = false; + visualAttrBuffer[15]=0; + + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] >>= 1; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = GL_FALSE; + visualAttrBuffer[19] = 0; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + AntiAlias=false; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = GL_TRUE; + visualAttrBuffer[19] = MAX_SAMPLES; + } + } + } + } + // Next try without double buffer + if (!configList) + { + os::Printer::log("No doublebuffering available.", ELL_WARNING); + visualAttrBuffer[13] = GL_FALSE; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] >>= 1; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = GL_FALSE; + visualAttrBuffer[19] = 0; + configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + AntiAlias=false; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = GL_TRUE; + visualAttrBuffer[19] = MAX_SAMPLES; + } + } + } + } + if (configList) + { + glxFBConfig=configList[0]; + XFree(configList); + UseGLXWindow=true; + visual = glXGetVisualFromFBConfig(display,glxFBConfig); + } + } + else + { + // attribute array for the draw buffer + int visualAttrBuffer[] = + { + GLX_RGBA, GL_TRUE, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + GLX_ALPHA_SIZE, 4, + GLX_DEPTH_SIZE, 16, + GLX_DOUBLEBUFFER, GL_TRUE, + GLX_STENCIL_SIZE, 1, + None + }; + + if (StencilBuffer) + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + if (!visual) + { + if (StencilBuffer) + { + os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING); + StencilBuffer = false; + } + visualAttrBuffer[15]=0; + + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + if (!visual) + { + os::Printer::log("No doublebuffering available.", ELL_WARNING); + visualAttrBuffer[13] = GL_FALSE; + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + } + } + } + } + else + os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING); + } + +#endif // _IRR_COMPILE_WITH_OPENGL_ + + // create visual with standard X methods + if (!visual) + { + XVisualInfo visTempl; //Template to hold requested values + int visNumber; // Return value of available visuals + + visTempl.screen = screennr; + visTempl.depth = 16; + while ((!visual) && (visTempl.depth<=32)) + { + visual = XGetVisualInfo(display, VisualScreenMask|VisualDepthMask, + &visTempl, &visNumber); + visTempl.depth+=8; + } + } + + if (!visual) + { + os::Printer::log("Fatal error, could not get visual.", ELL_ERROR); + XCloseDisplay(display); + display=0; + return false; + } + + // create color map + Colormap colormap; + colormap = XCreateColormap(display, + RootWindow(display, visual->screen), + visual->visual, AllocNone); + + attributes.colormap = colormap; + attributes.border_pixel = 0; + attributes.event_mask = KeyPressMask | ButtonPressMask | + StructureNotifyMask | PointerMotionMask | + ButtonReleaseMask | KeyReleaseMask; + + // create Window, either for Fullscreen or windowed mode + if (Fullscreen) + { + attributes.override_redirect = True; + + window = XCreateWindow(display, + RootWindow(display, visual->screen), + 0, 0, Width, Height, 0, visual->depth, + InputOutput, visual->visual, + CWBorderPixel | CWColormap | CWEventMask | + CWOverrideRedirect, &attributes); + + XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); + XMapRaised(display, window); + XGrabKeyboard(display, window, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + XGrabPointer(display, window, True, ButtonPressMask, + GrabModeAsync, GrabModeAsync, window, None, CurrentTime); + } + else + { // we want windowed mode + attributes.event_mask |= ExposureMask; + attributes.event_mask |= FocusChangeMask; + + window = XCreateWindow(display, + RootWindow(display, visual->screen), + 0, 0, Width, Height, 0, visual->depth, + InputOutput, visual->visual, + CWBorderPixel | CWColormap | CWEventMask, + &attributes); + + Atom wmDelete; + wmDelete = XInternAtom(display, wmDeleteWindow, True); + XSetWMProtocols(display, window, &wmDelete, 1); + XMapRaised(display, window); + } + WindowActive=true; + XkbSetDetectableAutoRepeat(display, True, &AutorepeatSupport); + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + + // connect glx context to window + if (isAvailableGLX && DriverType==video::EDT_OPENGL) + { + if (UseGLXWindow) + { + glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); + if (glxWin) + { + // create glx context + Context = glXCreateNewContext(display, glxFBConfig, GLX_RGBA_TYPE, NULL, True); + if (Context) + { + if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) + { + os::Printer::log("Could not make context current.", ELL_WARNING); + glXDestroyContext(display, Context); + } + } + else + { + os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); + } + } + else + { + os::Printer::log("Could not create GLX window.", ELL_WARNING); + } + } + else + { + Context = glXCreateContext(display, visual, NULL, True); + if (Context) + { + if (!glXMakeCurrent(display, window, Context)) + { + os::Printer::log("Could not make context current.", ELL_WARNING); + glXDestroyContext(display, Context); + } + } + else + { + os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); + } + } + } +#endif // _IRR_COMPILE_WITH_OPENGL_ + + Window tmp; + u32 borderWidth; + int x,y; + + XGetGeometry(display, window, &tmp, &x, &y, &Width, &Height, &borderWidth, &Depth); + StdHints = XAllocSizeHints(); + long num; + XGetWMNormalHints(display, window, StdHints, &num); + + // create an XImage for the software renderer + //(thx to Nadav for some clues on how to do that!) + + if (DriverType == video::EDT_SOFTWARE || DriverType == video::EDT_BURNINGSVIDEO) + { + SoftwareImage = XCreateImage(display, + visual->visual, visual->depth, + ZPixmap, 0, 0, Width, Height, + BitmapPad(display), 0); + + // use malloc because X will free it later on + SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); + } + +#endif // #ifdef _IRR_COMPILE_WITH_X11_ + return true; +} + + +//! create the driver +void CIrrDeviceLinux::createDriver(const core::dimension2d& windowSize, + bool vsync) +{ + switch(DriverType) + { +#ifdef _IRR_COMPILE_WITH_X11_ + + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(windowSize, Fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createSoftwareDriver2(windowSize, Fullscreen, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (Context) + VideoDriver = video::createOpenGLDriver(windowSize, Fullscreen, StencilBuffer, FileSystem, vsync, AntiAlias); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in Linux. Try OpenGL or Software renderer.", + ELL_ERROR); + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, windowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; +#else + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, windowSize); + break; + default: + os::Printer::log("No X11 support compiled in. Only Null driver available.", ELL_ERROR); + break; +#endif + } +} + + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceLinux::run() +{ + os::Timer::tick(); + +#ifdef _IRR_COMPILE_WITH_X11_ + if (DriverType != video::EDT_NULL) + { + SEvent irrevent; + + while (XPending(display) > 0 && !Close) + { + XEvent event; + XNextEvent(display, &event); + + switch (event.type) + { + case ConfigureNotify: + // check for changed window size + if ((event.xconfigure.width != (int) Width) || + (event.xconfigure.height != (int) Height)) + { + Width = event.xconfigure.width; + Height = event.xconfigure.height; + + // resize image data + if (DriverType == video::EDT_SOFTWARE || DriverType == video::EDT_BURNINGSVIDEO) + { + XDestroyImage(SoftwareImage); + + SoftwareImage = XCreateImage(display, + visual->visual, visual->depth, + ZPixmap, 0, 0, Width, Height, + BitmapPad(display), 0); + + // use malloc because X will free it later on + SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); + } + + if (VideoDriver) + VideoDriver->OnResize(core::dimension2d(Width, Height)); + } + break; + + case MapNotify: + WindowMinimized=false; + break; + + case UnmapNotify: + WindowMinimized=true; + break; + + case FocusIn: + WindowActive=true; + break; + + case FocusOut: + WindowActive=false; + break; + + case MotionNotify: + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + irrevent.MouseInput.X = event.xbutton.x; + irrevent.MouseInput.Y = event.xbutton.y; + + postEventFromUser(irrevent); + break; + + case ButtonPress: + case ButtonRelease: + + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.X = event.xbutton.x; + irrevent.MouseInput.Y = event.xbutton.y; + + irrevent.MouseInput.Event = irr::EMIE_COUNT; + + switch(event.xbutton.button) + { + case Button1: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP; + break; + + case Button3: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP; + break; + + case Button2: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP; + break; + + case Button4: + irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = 1.0f; + break; + + case Button5: + irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = -1.0f; + break; + } + + if (irrevent.MouseInput.Event != irr::EMIE_COUNT) + postEventFromUser(irrevent); + break; + + case MappingNotify: + XRefreshKeyboardMapping (&event.xmapping) ; + break; + + case KeyRelease: + if (0 == AutorepeatSupport) + { + // check for Autorepeat manually + // We'll do the same as Windows does: Only send KeyPressed + // So every KeyRelease is a real release + XEvent next_event; + XPeekEvent (event.xkey.display, &next_event); + if ((next_event.type == KeyPress) && + (next_event.xkey.keycode == event.xkey.keycode) && + (next_event.xkey.time == event.xkey.time)) + { + /* Ignore the key release event */ + break; + } + } + // fall-through in case the release should be handled + case KeyPress: + { + SKeyMap mp; + //mp.X11Key = XLookupKeysym(&event.xkey, 0); + char buf[5]="\0\0\0\0"; + XLookupString (&event.xkey, buf, 4, &mp.X11Key, NULL) ; + + s32 idx = KeyMap.binary_search(mp); + + if (idx != -1) + irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key; + else + { + irrevent.KeyInput.Key = (EKEY_CODE)0; + os::Printer::log("Could not find win32 key for x11 key.", ELL_WARNING); + } + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.PressedDown = (event.type == KeyPress); + mbtowc(&irrevent.KeyInput.Char, buf, 4); + irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0; + postEventFromUser(irrevent); + } + break; + + case ClientMessage: + { + char *atom = XGetAtomName(display, event.xclient.message_type); + if (*atom == *wmDeleteWindow) + { + os::Printer::log("Quit message received.", ELL_INFORMATION); + Close = true; + } + XFree(atom); + } + break; + + default: + break; + } // end switch + + } // end while + } +#endif //_IRR_COMPILE_WITH_X11_ + + return !Close; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceLinux::yield() +{ + struct timespec ts = {0,0}; + nanosleep(&ts, NULL); +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceLinux::sleep(u32 timeMs, bool pauseTimer=false) +{ + bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + +//! sets the caption of the window +void CIrrDeviceLinux::setWindowCaption(const wchar_t* text) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (DriverType == video::EDT_NULL) + return; + + XTextProperty txt; + XwcTextListToTextProperty(display, const_cast(&text), 1, XStdICCTextStyle, &txt); + XSetWMName(display, window, &txt); + XSetWMIconName(display, window, &txt); +#endif +} + + + +//! presents a surface in the client area +void CIrrDeviceLinux::present(video::IImage* image, s32 windowId, core::rect* src ) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + // this is only necessary for software drivers. + if (DriverType != video::EDT_SOFTWARE && DriverType != video::EDT_BURNINGSVIDEO) + return; + + // thx to Nadav, who send me some clues of how to display the image + // to the X Server. + + if (image->getColorFormat() != video::ECF_A1R5G5B5 && + image->getColorFormat() != video::ECF_A8R8G8B8) + { + os::Printer::log("Internal error, can only present A1R5G5B5 and A8R8G8B8 pictures."); + return; + } + + int destwidth = SoftwareImage->width; + int destheight = SoftwareImage->height; + int srcwidth = image->getDimension().Width; + int srcheight = image->getDimension().Height; + // clip images + srcheight = srcheight < destheight ? srcheight : destheight; + + if ( image->getColorFormat() == video::ECF_A8R8G8B8 ) + { + // display 24/32 bit image + + s32* srcdata = (s32*)image->lock(); + + if ((Depth == 32)||(Depth == 24)) + { + int destPitch = SoftwareImage->bytes_per_line; + u8* destData = reinterpret_cast(SoftwareImage->data); + + for (int y=0; ybytes_per_line; + u8* destData = reinterpret_cast(SoftwareImage->data); + + for (int y=0; yunlock(); + } + else + { + // display 16 bit image + + s16* srcdata = (s16*)image->lock(); + + if (Depth == 16) + { + // convert from A1R5G5B5 to R5G6B6 + + int destPitch = SoftwareImage->bytes_per_line; + u8* destData = reinterpret_cast(SoftwareImage->data); + + for (int y=0; ybytes_per_line; + u8* destData = reinterpret_cast(SoftwareImage->data); + + for (int y=0; yunlock(); + } + + GC gc = DefaultGC(display, DefaultScreen(display)); + XPutImage(display, window, gc, SoftwareImage, 0, 0, 0, 0, destwidth, destheight); +#endif +} + + + +//! notifies the device that it should close itself +void CIrrDeviceLinux::closeDevice() +{ + Close = true; +} + + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceLinux::isWindowActive() const +{ + return WindowActive; +} + + + +//! Sets if the window should be resizeable in windowed mode. +void CIrrDeviceLinux::setResizeAble(bool resize) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (DriverType == video::EDT_NULL) + return; + + XUnmapWindow(display, window); + if ( !resize ) + { + // Must be heap memory because data size depends on X Server + XSizeHints *hints = XAllocSizeHints(); + hints->flags=PSize|PMinSize|PMaxSize; + hints->min_width=hints->max_width=hints->base_width=Width; + hints->min_height=hints->max_height=hints->base_height=Height; + XSetWMNormalHints(display, window, hints); + XFree(hints); + } + else + { + XSetWMNormalHints(display, window, StdHints); + } + XMapWindow(display, window); + XFlush(display); +#endif // #ifdef _IRR_COMPILE_WITH_X11_ +} + + +//! \return Returns a pointer to a list with all video modes supported +//! by the gfx adapter. +video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() +{ + + if (!VideoModeList.getVideoModeCount()) + { + bool temporaryDisplay = false; + + if (!display) + { + display = XOpenDisplay(0); + temporaryDisplay=true; + } + if (display) + { + s32 eventbase, errorbase; + s32 defaultDepth=DefaultDepth(display,screennr); + + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + // enumerate video modes + int modeCount; + XF86VidModeModeInfo** modes; + + XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); + + // save current video mode + oldVideoMode = *modes[0]; + + // find fitting mode + + VideoModeList.setDesktop(defaultDepth, core::dimension2d( + modes[0]->hdisplay, modes[0]->vdisplay)); + for (int i = 0; i( + modes[i]->hdisplay, modes[i]->vdisplay), defaultDepth); + } + XFree(modes); + } + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + int modeCount; + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + oldRandrMode=XRRConfigCurrentConfiguration(config,&oldRandrRotation); + XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); + VideoModeList.setDesktop(defaultDepth, core::dimension2d( + modes[oldRandrMode].width, modes[oldRandrMode].height)); + for (int i = 0; i( + modes[i].width, modes[i].height), defaultDepth); + } + XRRFreeScreenConfigInfo(config); + } + else + #endif + { + os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING); + } + } + if (display && temporaryDisplay) + { + XCloseDisplay(display); + } + } + + return &VideoModeList; +} + + + +void CIrrDeviceLinux::createKeyMap() +{ + // I don't know if this is the best method to create + // the lookuptable, but I'll leave it like that until + // I find a better version. + +#ifdef _IRR_COMPILE_WITH_X11_ + KeyMap.push_back(SKeyMap(XK_BackSpace, KEY_BACK)); + KeyMap.push_back(SKeyMap(XK_Tab, KEY_TAB)); + KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_Clear, KEY_CLEAR)); + KeyMap.push_back(SKeyMap(XK_Return, KEY_RETURN)); + KeyMap.push_back(SKeyMap(XK_Pause, KEY_PAUSE)); + KeyMap.push_back(SKeyMap(XK_Scroll_Lock, KEY_SCROLL)); + KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_Escape, KEY_ESCAPE)); + KeyMap.push_back(SKeyMap(XK_Delete, KEY_DELETE)); + KeyMap.push_back(SKeyMap(XK_Home, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_Left, KEY_LEFT)); + KeyMap.push_back(SKeyMap(XK_Up, KEY_UP)); + KeyMap.push_back(SKeyMap(XK_Right, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(XK_Down, KEY_DOWN)); + KeyMap.push_back(SKeyMap(XK_Prior, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_Page_Up, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_Next, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_Page_Down, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_End, KEY_END)); + KeyMap.push_back(SKeyMap(XK_Begin, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_KP_Space, KEY_SPACE)); + KeyMap.push_back(SKeyMap(XK_KP_Tab, KEY_TAB)); + KeyMap.push_back(SKeyMap(XK_KP_Enter, KEY_RETURN)); + KeyMap.push_back(SKeyMap(XK_KP_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(XK_KP_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(XK_KP_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(XK_KP_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(XK_KP_Left, KEY_LEFT)); + KeyMap.push_back(SKeyMap(XK_KP_Up, KEY_UP)); + KeyMap.push_back(SKeyMap(XK_KP_Right, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(XK_KP_Down, KEY_DOWN)); + KeyMap.push_back(SKeyMap(XK_KP_Prior, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_KP_Page_Up, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_KP_Next, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_KP_Page_Down, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_KP_End, KEY_END)); + KeyMap.push_back(SKeyMap(XK_KP_Begin, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_KP_Insert, KEY_INSERT)); + KeyMap.push_back(SKeyMap(XK_KP_Delete, KEY_DELETE)); + KeyMap.push_back(SKeyMap(XK_KP_Equal, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_KP_Multiply, KEY_MULTIPLY)); + KeyMap.push_back(SKeyMap(XK_KP_Add, KEY_ADD)); + KeyMap.push_back(SKeyMap(XK_KP_Separator, KEY_SEPARATOR)); + KeyMap.push_back(SKeyMap(XK_KP_Subtract, KEY_SUBTRACT)); + KeyMap.push_back(SKeyMap(XK_KP_Decimal, KEY_DECIMAL)); + KeyMap.push_back(SKeyMap(XK_KP_Divide, KEY_DIVIDE)); + KeyMap.push_back(SKeyMap(XK_KP_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(XK_KP_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(XK_KP_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(XK_KP_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(XK_KP_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(XK_KP_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(XK_KP_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(XK_KP_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(XK_KP_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(XK_KP_9, KEY_KEY_9)); + KeyMap.push_back(SKeyMap(XK_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(XK_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(XK_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(XK_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(XK_F5, KEY_F5)); + KeyMap.push_back(SKeyMap(XK_F6, KEY_F6)); + KeyMap.push_back(SKeyMap(XK_F7, KEY_F7)); + KeyMap.push_back(SKeyMap(XK_F8, KEY_F8)); + KeyMap.push_back(SKeyMap(XK_F9, KEY_F9)); + KeyMap.push_back(SKeyMap(XK_F10, KEY_F10)); + KeyMap.push_back(SKeyMap(XK_F11, KEY_F11)); + KeyMap.push_back(SKeyMap(XK_F12, KEY_F12)); + KeyMap.push_back(SKeyMap(XK_Shift_L, KEY_LSHIFT)); + KeyMap.push_back(SKeyMap(XK_Shift_R, KEY_RSHIFT)); + KeyMap.push_back(SKeyMap(XK_Control_L, KEY_LCONTROL)); + KeyMap.push_back(SKeyMap(XK_Control_R, KEY_RCONTROL)); + KeyMap.push_back(SKeyMap(XK_Caps_Lock, KEY_CAPITAL)); + KeyMap.push_back(SKeyMap(XK_Shift_Lock, KEY_CAPITAL)); + KeyMap.push_back(SKeyMap(XK_Meta_L, KEY_LWIN)); + KeyMap.push_back(SKeyMap(XK_Meta_R, KEY_RWIN)); + KeyMap.push_back(SKeyMap(XK_Alt_L, KEY_LMENU)); + KeyMap.push_back(SKeyMap(XK_Alt_R, KEY_RMENU)); + KeyMap.push_back(SKeyMap(XK_ISO_Level3_Shift, KEY_RMENU)); + KeyMap.push_back(SKeyMap(XK_Menu, KEY_MENU)); + KeyMap.push_back(SKeyMap(XK_space, KEY_SPACE)); + KeyMap.push_back(SKeyMap(XK_exclam, 0)); //? + KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //? + KeyMap.push_back(SKeyMap(XK_section, 0)); //? + KeyMap.push_back(SKeyMap(XK_numbersign, 0)); //? + KeyMap.push_back(SKeyMap(XK_dollar, 0)); //? + KeyMap.push_back(SKeyMap(XK_percent, 0)); //? + KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //? + KeyMap.push_back(SKeyMap(XK_apostrophe, 0)); //? + KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //? + KeyMap.push_back(SKeyMap(XK_parenright, 0)); //? + KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //? + KeyMap.push_back(SKeyMap(XK_plus, KEY_PLUS)); //? + KeyMap.push_back(SKeyMap(XK_comma, KEY_COMMA)); //? + KeyMap.push_back(SKeyMap(XK_minus, KEY_MINUS)); //? + KeyMap.push_back(SKeyMap(XK_period, KEY_PERIOD)); //? + KeyMap.push_back(SKeyMap(XK_slash, 0)); //? + KeyMap.push_back(SKeyMap(XK_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(XK_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(XK_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(XK_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(XK_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(XK_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(XK_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(XK_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(XK_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(XK_9, KEY_KEY_9)); + KeyMap.push_back(SKeyMap(XK_colon, 0)); //? + KeyMap.push_back(SKeyMap(XK_semicolon, 0)); //? + KeyMap.push_back(SKeyMap(XK_less, 0)); //? + KeyMap.push_back(SKeyMap(XK_equal, 0)); //? + KeyMap.push_back(SKeyMap(XK_greater, 0)); //? + KeyMap.push_back(SKeyMap(XK_question, 0)); //? + KeyMap.push_back(SKeyMap(XK_at, 0)); //? + KeyMap.push_back(SKeyMap(XK_mu, 0)); //? + KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //? + KeyMap.push_back(SKeyMap(XK_A, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(XK_B, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(XK_C, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(XK_D, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(XK_E, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(XK_F, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(XK_G, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(XK_H, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(XK_I, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(XK_J, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(XK_K, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(XK_L, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(XK_M, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(XK_N, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(XK_O, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(XK_P, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(XK_Q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(XK_R, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(XK_S, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(XK_T, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(XK_U, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(XK_V, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(XK_W, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(XK_X, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(XK_Y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(XK_Z, KEY_KEY_Z)); + KeyMap.push_back(SKeyMap(XK_Adiaeresis, 0)); //? + KeyMap.push_back(SKeyMap(XK_Odiaeresis, 0)); //? + KeyMap.push_back(SKeyMap(XK_Udiaeresis, 0)); //? + KeyMap.push_back(SKeyMap(XK_bracketleft, 0)); //? + KeyMap.push_back(SKeyMap(XK_backslash, 0)); //? + KeyMap.push_back(SKeyMap(XK_bracketright, 0)); //? + KeyMap.push_back(SKeyMap(XK_asciicircum, 0)); //? + KeyMap.push_back(SKeyMap(XK_degree, 0)); //? + KeyMap.push_back(SKeyMap(XK_underscore, 0)); //? + KeyMap.push_back(SKeyMap(XK_grave, 0)); //? + KeyMap.push_back(SKeyMap(XK_acute, 0)); //? + KeyMap.push_back(SKeyMap(XK_quoteleft, 0)); //? + KeyMap.push_back(SKeyMap(XK_a, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(XK_b, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(XK_c, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(XK_d, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(XK_e, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(XK_f, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(XK_g, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(XK_h, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(XK_i, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(XK_j, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(XK_k, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(XK_l, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(XK_m, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(XK_n, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(XK_o, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(XK_p, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(XK_q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(XK_r, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(XK_s, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(XK_t, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(XK_u, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(XK_v, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(XK_w, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(XK_x, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(XK_y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(XK_z, KEY_KEY_Z)); + KeyMap.push_back(SKeyMap(XK_ssharp, 0)); //? + KeyMap.push_back(SKeyMap(XK_adiaeresis, 0)); //? + KeyMap.push_back(SKeyMap(XK_odiaeresis, 0)); //? + KeyMap.push_back(SKeyMap(XK_udiaeresis, 0)); //? + + KeyMap.sort(); +#endif +} + + +IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& param) +{ + CIrrDeviceLinux* dev = new CIrrDeviceLinux( + param.DriverType, + param.WindowSize, + param.Bits, + param.Fullscreen, + param.Stencilbuffer, + param.Vsync, + param.AntiAlias, + param.EventReceiver, + param.SDK_version_do_not_use); + + if (dev && !dev->getVideoDriver() && param.DriverType != video::EDT_NULL) + { + dev->drop(); + dev = 0; + } + + return dev; +} + + +} // end namespace + +#endif // _IRR_USE_LINUX_DEVICE_ + diff --git a/src/dep/src/irrlicht/CIrrDeviceLinux.h b/src/dep/src/irrlicht/CIrrDeviceLinux.h new file mode 100644 index 0000000..5d5f14b --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceLinux.h @@ -0,0 +1,349 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_LINUX_H_INCLUDED__ +#define __C_IRR_DEVICE_LINUX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_USE_LINUX_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "ICursorControl.h" + +#ifdef _IRR_COMPILE_WITH_X11_ + +#ifdef _IRR_COMPILE_WITH_OPENGL_ +#include +#define GLX_GLXEXT_LEGACY 1 +#include +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ +#include "glxext.h" +#endif +#endif + +#include +#include +#ifdef _IRR_LINUX_X11_VIDMODE_ +#include +#endif +#ifdef _IRR_LINUX_X11_RANDR_ +#include +#endif +#include + +#else +#define KeySym s32 +#endif + +namespace irr +{ + + class CIrrDeviceLinux : public CIrrDeviceStub, public video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceLinux(video::E_DRIVER_TYPE deviceType, + const core::dimension2d& windowSize, u32 bits, + bool fullscreen, bool stencilbuffer, bool vsync, bool antiAlias, IEventReceiver* receiver, + const char* version); + + //! destructor + virtual ~CIrrDeviceLinux(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! presents a surface in the client area + virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); + + //! Sets if the window should be resizeable in windowed mode. + virtual void setResizeAble(bool resize=false); + + private: + + //! create the driver + void createDriver(const core::dimension2d& windowSize, + bool vsync); + + bool createWindow(const core::dimension2d& windowSize, u32 bits); + + void createKeyMap(); + + //! Implementation of the linux cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceLinux* dev, bool null) + : Device(dev), IsVisible(true), Null(null), UseReferenceRect(false) + { +#ifdef _IRR_COMPILE_WITH_X11_ + if (!Null) + { + XGCValues values; + unsigned long valuemask = 0; + + XColor fg, bg; + + // this code, for making the cursor invisible was sent in by + // Sirshane, thank your very much! + + + Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); + Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); + Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) ); + XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg ); + XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg ); + + GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values ); + + XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) ); + XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 ); + XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 ); + + invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 ); + XFreeGC(Device->display, gc); + XFreePixmap(Device->display, invisBitmap); + XFreePixmap(Device->display, maskBitmap); + } +#endif + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; +#ifdef _IRR_COMPILE_WITH_X11_ + if (!Null) + { + if ( !IsVisible ) + XDefineCursor( Device->display, Device->window, invisCursor ); + else + XUndefineCursor( Device->display, Device->window ); + } +#endif + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { +#ifdef _IRR_COMPILE_WITH_X11_ + + if (!Null) + { + if (UseReferenceRect) + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, + ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + + } + else + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, x, y); + } + XFlush(Device->display); + } +#endif + CursorPos.X = x; + CursorPos.Y = y; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getPosition() + { + updateCursorPos(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateCursorPos(); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X / (f32)Device->Width, + CursorPos.Y / (f32)Device->Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + private: + + void updateCursorPos() + { +#ifdef _IRR_COMPILE_WITH_X11_ + if (Null) + return; + + Window tmp; + int itmp1, itmp2; + unsigned int maskreturn; + XQueryPointer(Device->display, Device->window, + &tmp, &tmp, + &itmp1, &itmp2, + &CursorPos.X, &CursorPos.Y, &maskreturn); + + if (CursorPos.X < 0) + CursorPos.X = 0; + if (CursorPos.X > (s32) Device->Width) + CursorPos.X = Device->Width; + if (CursorPos.Y < 0) + CursorPos.Y = 0; + if (CursorPos.Y > (s32) Device->Height) + CursorPos.Y = Device->Height; +#endif + } + + core::position2d CursorPos; + CIrrDeviceLinux* Device; + bool IsVisible; + bool Null; + bool UseReferenceRect; + core::rect ReferenceRect; +#ifdef _IRR_COMPILE_WITH_X11_ + Cursor invisCursor; +#endif + }; + + friend class CCursorControl; + +#ifdef _IRR_COMPILE_WITH_X11_ + Display *display; + XVisualInfo* visual; + int screennr; + Window window; + XSetWindowAttributes attributes; + XSizeHints* StdHints; + XImage* SoftwareImage; + #ifdef _IRR_LINUX_X11_VIDMODE_ + XF86VidModeModeInfo oldVideoMode; + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + SizeID oldRandrMode; + Rotation oldRandrRotation; + #endif + #ifdef _IRR_COMPILE_WITH_OPENGL_ + GLXWindow glxWin; + GLXContext Context; + #endif +#endif + bool Fullscreen; + bool StencilBuffer; + bool AntiAlias; + video::E_DRIVER_TYPE DriverType; + + u32 Width, Height, Depth; + bool Close; + bool WindowActive; + bool WindowMinimized; + bool UseXVidMode; + bool UseXRandR; + bool UseGLXWindow; + int AutorepeatSupport; + + struct SKeyMap + { + SKeyMap() {} + SKeyMap(s32 x11, s32 win32) + : X11Key(x11), Win32Key(win32) + { + } + + KeySym X11Key; + s32 Win32Key; + + bool operator<(const SKeyMap& o) const + { + return X11Key KeyMap; + }; + + +} // end namespace irr + +#endif // _IRR_USE_LINUX_DEVICE_ +#endif // __C_IRR_DEVICE_LINUX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CIrrDeviceSDL.cpp b/src/dep/src/irrlicht/CIrrDeviceSDL.cpp new file mode 100644 index 0000000..8eea325 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceSDL.cpp @@ -0,0 +1,533 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_USE_SDL_DEVICE_ + +#include "CIrrDeviceSDL.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include "COSOperator.h" +#include +#include +#include "SIrrCreationParameters.h" +#include + +namespace irr +{ + namespace video + { + IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias); + } + +} // end namespace irr + + + +namespace irr +{ + +const char* wmDeleteWindow = "WM_DELETE_WINDOW"; + +//! constructor +CIrrDeviceSDL::CIrrDeviceSDL(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, + bool fullscreen, bool stencilbuffer, bool vsync, + bool antiAlias, IEventReceiver* receiver, + void* windowID, const char* version) + : CIrrDeviceStub(version, receiver), Depth(bits), + Fullscreen(fullscreen), Stencilbuffer(stencilbuffer), Vsync(vsync), + AntiAlias(antiAlias), Resizeable(false), + Screen((SDL_Surface*)windowID), SDL_Flags(SDL_HWSURFACE|SDL_ANYFORMAT), + Width(windowSize.Width), Height(windowSize.Height), Close(0), + WindowActive(false) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceSDL"); + #endif + + // Initialize SDL... Timer for sleep, video for the obvious, and + // noparachute prevents SDL from catching fatal errors. + if ( SDL_Init( SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE ) < 0 ) + { + os::Printer::log( "Unable to initialize SDL!", SDL_GetError()); + Close = 1; + } + + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + + SDL_GetWMInfo(&info); + core::stringc sdlversion = "SDL Version "; + sdlversion += info.version.major; + sdlversion += "."; + sdlversion += info.version.minor; + sdlversion += "."; + sdlversion += info.version.patch; + + Operator = new COSOperator(sdlversion.c_str()); + os::Printer::log(sdlversion.c_str(), ELL_INFORMATION); + + // create keymap + createKeyMap(); + + if ( Fullscreen ) + SDL_Flags |= SDL_FULLSCREEN; + if (driverType == video::EDT_OPENGL) + SDL_Flags |= SDL_OPENGL; + else + SDL_Flags |= SDL_DOUBLEBUF; + // create window + if (driverType != video::EDT_NULL) + { + // create the window, only if we do not use the null device + createWindow(driverType); + } + + // create cursor control + CursorControl = new CCursorControl(this); + + // create driver + createDriver(driverType, windowSize); + + if (VideoDriver) + createGUIAndScene(); +} + + + +//! destructor +CIrrDeviceSDL::~CIrrDeviceSDL() +{ + if (Screen) + SDL_FreeSurface(Screen); + SDL_Quit(); +} + + + +bool CIrrDeviceSDL::createWindow(video::E_DRIVER_TYPE driverType) +{ + if ( Close ) + return false; + + if (driverType == video::EDT_OPENGL) + { + if (Depth==16) + { + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); + SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); + SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); + } + else + { + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); + } + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, Depth); + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + } + + if ( !Screen ) + Screen = SDL_SetVideoMode( Width, Height, Depth, SDL_Flags ); + if ( !Screen ) + { + os::Printer::log( "Could not initialize display!" ); + return false; + } + + return true; +} + + +//! create the driver +void CIrrDeviceSDL::createDriver(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize) +{ + switch(driverType) + { + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in SDL.", ELL_ERROR); + break; + + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(windowSize, Fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createSoftwareDriver2(windowSize, Fullscreen, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + VideoDriver = video::createOpenGLDriver(windowSize, Fullscreen, Stencilbuffer, FileSystem, Vsync, AntiAlias); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, windowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceSDL::run() +{ + os::Timer::tick(); + + SEvent irrevent; + + while ( !Close && SDL_PollEvent( &SDL_event ) ) + { + switch ( SDL_event.type ) + { + case SDL_MOUSEMOTION: + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + MouseX = irrevent.MouseInput.X = SDL_event.motion.x; + MouseY = irrevent.MouseInput.Y = SDL_event.motion.y; + + postEventFromUser(irrevent); + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.X = SDL_event.button.x; + irrevent.MouseInput.Y = SDL_event.button.y; + + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + + switch(SDL_event.button.button) + { + case 1: + irrevent.MouseInput.Event = + (SDL_event.type == SDL_MOUSEBUTTONDOWN) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP; + break; + + case 2: + irrevent.MouseInput.Event = + (SDL_event.type == SDL_MOUSEBUTTONDOWN) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP; + break; + + case 3: + irrevent.MouseInput.Event = + (SDL_event.type == SDL_MOUSEBUTTONDOWN) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP; + break; + } + + if (irrevent.MouseInput.Event != irr::EMIE_MOUSE_MOVED) + postEventFromUser(irrevent); + break; + + case SDL_KEYDOWN: + case SDL_KEYUP: + { + SKeyMap mp; + mp.SDLKey = SDL_event.key.keysym.sym; + s32 idx = KeyMap.binary_search(mp); + + if (idx != -1) + { + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key; + irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN); + postEventFromUser(irrevent); + } + else + os::Printer::log("Could not find win32 key for SDL key."); + } + break; + + case SDL_QUIT: + Close = true; + break; + + case SDL_ACTIVEEVENT: + if (SDL_event.active.state == SDL_APPMOUSEFOCUS) + WindowActive = (SDL_event.active.gain==1); + break; + + default: + break; + } // end switch + + } // end while + + return !Close; +} + + +//! pause execution temporarily +void CIrrDeviceSDL::yield() +{ + SDL_Delay(0); +} + + +//! pause execution for a specified time +void CIrrDeviceSDL::sleep(u32 timeMs, bool pauseTimer) +{ + bool wasStopped = Timer ? Timer->isStopped() : true; + if (pauseTimer && !wasStopped) + Timer->stop(); + + SDL_Delay(timeMs); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +//! sets the caption of the window +void CIrrDeviceSDL::setWindowCaption(const wchar_t* text) +{ + core::stringc textc = text; + SDL_WM_SetCaption( textc.c_str( ), textc.c_str( ) ); +} + + + +//! presents a surface in the client area +void CIrrDeviceSDL::present(video::IImage* surface, s32 windowId, core::rect* src) +{ + SDL_Rect srcClip; + SDL_Surface *sdlSurface = SDL_CreateRGBSurfaceFrom (surface->lock(), surface->getDimension().Width, surface->getDimension().Height, surface->getBitsPerPixel(), surface->getPitch(), surface->getRedMask(), surface->getGreenMask(), surface->getBlueMask(), 0); + if (src) + { + srcClip.x = src->UpperLeftCorner.X; + srcClip.y = src->UpperLeftCorner.Y; + srcClip.w = src->getWidth(); + srcClip.h = src->getHeight(); + SDL_BlitSurface(sdlSurface, &srcClip, Screen, NULL); + } + else + SDL_BlitSurface(sdlSurface, NULL, Screen, NULL); + SDL_UpdateRect(Screen, 0, 0, surface->getDimension().Width, surface->getDimension().Height); + SDL_FreeSurface(sdlSurface); + surface->unlock(); +} + + + +//! notifies the device that it should close itself +void CIrrDeviceSDL::closeDevice() +{ + Close = true; +} + + + +//! \return Returns a pointer to a list with all video modes supported +video::IVideoModeList* CIrrDeviceSDL::getVideoModeList() +{ + if (!VideoModeList.getVideoModeCount()) + { + // enumerate video modes. + const SDL_VideoInfo *vi = SDL_GetVideoInfo(); + SDL_Rect **modes = SDL_ListModes(vi->vfmt, SDL_Flags); + if (modes != (SDL_Rect **)0) + { + if (modes == (SDL_Rect **)-1) + os::Printer::log("All modes available.\n"); + else + { + for (u32 i=0; modes[i]; ++i) + VideoModeList.addMode(core::dimension2d(modes[i]->w, modes[i]->h), vi->vfmt->BitsPerPixel); + } + } + } + + return &VideoModeList; +} + + + +//! Sets if the window should be resizeable in windowed mode. +void CIrrDeviceSDL::setResizeAble(bool resize) +{ + if (resize != Resizeable) + { + if (resize) + SDL_Flags |= SDL_RESIZABLE; + else + SDL_Flags &= ~SDL_RESIZABLE; + SDL_FreeSurface(Screen); + Screen = SDL_SetVideoMode( Width, Height, Depth, SDL_Flags ); + Resizeable = resize; + } +} + + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceSDL::isWindowActive() const +{ + return WindowActive; +} + + +void CIrrDeviceSDL::createKeyMap() +{ + // I don't know if this is the best method to create + // the lookuptable, but I'll leave it like that until + // I find a better version. + + KeyMap.push_back(SKeyMap(SDLK_BACKSPACE, KEY_BACK)); + KeyMap.push_back(SKeyMap(SDLK_TAB, KEY_TAB)); + + //KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ??? + + KeyMap.push_back(SKeyMap(SDLK_CLEAR, KEY_CLEAR)); + KeyMap.push_back(SKeyMap(SDLK_RETURN, KEY_RETURN)); + KeyMap.push_back(SKeyMap(SDLK_PAUSE, KEY_PAUSE)); + + //KeyMap.push_back(SKeyMap(XK_Scroll_Lock, 0)); // ??? + //KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ??? + + KeyMap.push_back(SKeyMap(SDLK_ESCAPE, KEY_ESCAPE)); + KeyMap.push_back(SKeyMap(SDLK_DELETE, KEY_DELETE)); + KeyMap.push_back(SKeyMap(SDLK_HOME, KEY_HOME)); + KeyMap.push_back(SKeyMap(SDLK_LEFT, KEY_LEFT)); + KeyMap.push_back(SKeyMap(SDLK_UP, KEY_UP)); + KeyMap.push_back(SKeyMap(SDLK_RIGHT, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(SDLK_DOWN, KEY_DOWN)); + + KeyMap.push_back(SKeyMap(SDLK_PAGEUP, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(SDLK_PAGEDOWN, KEY_NEXT)); + KeyMap.push_back(SKeyMap(SDLK_END, KEY_END)); + KeyMap.push_back(SKeyMap(SDLK_HOME, KEY_HOME)); + KeyMap.push_back(SKeyMap(SDLK_SPACE, KEY_SPACE)); + KeyMap.push_back(SKeyMap(SDLK_TAB, KEY_TAB)); + KeyMap.push_back(SKeyMap(SDLK_RETURN, KEY_RETURN)); + + KeyMap.push_back(SKeyMap(SDLK_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(SDLK_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(SDLK_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(SDLK_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(SDLK_F5, KEY_F5)); + KeyMap.push_back(SKeyMap(SDLK_F6, KEY_F6)); + KeyMap.push_back(SKeyMap(SDLK_F7, KEY_F7)); + KeyMap.push_back(SKeyMap(SDLK_F8, KEY_F8)); + KeyMap.push_back(SKeyMap(SDLK_F9, KEY_F9)); + KeyMap.push_back(SKeyMap(SDLK_F10, KEY_F10)); + KeyMap.push_back(SKeyMap(SDLK_F11, KEY_F11)); + KeyMap.push_back(SKeyMap(SDLK_F12, KEY_F12)); + + KeyMap.push_back(SKeyMap(SDLK_LSHIFT, KEY_LSHIFT)); + KeyMap.push_back(SKeyMap(SDLK_RSHIFT, KEY_RSHIFT)); + KeyMap.push_back(SKeyMap(SDLK_LCTRL, KEY_LCONTROL)); + KeyMap.push_back(SKeyMap(SDLK_RCTRL, KEY_RCONTROL)); + + KeyMap.push_back(SKeyMap(SDLK_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(SDLK_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(SDLK_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(SDLK_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(SDLK_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(SDLK_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(SDLK_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(SDLK_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(SDLK_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(SDLK_9, KEY_KEY_9)); + + //KeyMap.push_back(SKeyMap(XK_colon, 0)); //? + //KeyMap.push_back(SKeyMap(XK_semicolon, 0)); //? + //KeyMap.push_back(SKeyMap(XK_less, 0)); //? + //KeyMap.push_back(SKeyMap(XK_equal, 0)); //? + //KeyMap.push_back(SKeyMap(XK_greater, 0)); //? + //KeyMap.push_back(SKeyMap(XK_question, 0)); //? + //KeyMap.push_back(SKeyMap(XK_at, 0)); //? + + KeyMap.push_back(SKeyMap(SDLK_a, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(SDLK_b, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(SDLK_c, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(SDLK_d, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(SDLK_e, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(SDLK_f, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(SDLK_g, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(SDLK_h, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(SDLK_i, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(SDLK_j, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(SDLK_k, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(SDLK_l, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(SDLK_m, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(SDLK_n, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(SDLK_o, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(SDLK_p, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(SDLK_q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(SDLK_r, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(SDLK_s, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(SDLK_t, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(SDLK_u, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(SDLK_v, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(SDLK_w, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(SDLK_x, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(SDLK_y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(SDLK_z, KEY_KEY_Z)); + + //KeyMap.push_back(SKeyMap(XK_bracketleft, 0)); //? + //KeyMap.push_back(SKeyMap(XK_backslash, 0)); //? + //KeyMap.push_back(SKeyMap(XK_bracketright, 0)); //? + //KeyMap.push_back(SKeyMap(XK_asciicircum, 0)); //? + //KeyMap.push_back(SKeyMap(XK_underscore, 0)); //? + //KeyMap.push_back(SKeyMap(XK_grave, 0)); //? + //KeyMap.push_back(SKeyMap(XK_quoteleft, 0)); //? + + KeyMap.sort(); +} + +IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& param) +{ + CIrrDeviceSDL* dev = new CIrrDeviceSDL( + param.DriverType, + param.WindowSize, + param.Bits, + param.Fullscreen, + param.Stencilbuffer, + param.Vsync, + param.AntiAlias, + param.EventReceiver, + param.WindowId, + param.SDK_version_do_not_use); + + if (dev && !dev->getVideoDriver() && param.DriverType != video::EDT_NULL) + { + dev->drop(); + dev = 0; + } + + return dev; +} + + +} // end namespace irr + +#endif // _IRR_USE_SDL_DEVICE_ + diff --git a/src/dep/src/irrlicht/CIrrDeviceSDL.h b/src/dep/src/irrlicht/CIrrDeviceSDL.h new file mode 100644 index 0000000..6bf4faf --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceSDL.h @@ -0,0 +1,206 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// This device code is based on the original SDL device implementation +// contributed by Shane Parker (sirshane). + +#ifndef __C_IRR_DEVICE_SDL_H_INCLUDED__ +#define __C_IRR_DEVICE_SDL_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_USE_SDL_DEVICE_ + +#include "IrrlichtDevice.h" +#include "CIrrDeviceStub.h" +#include "IImagePresenter.h" +#include "ICursorControl.h" + +#include + +namespace irr +{ + + class CIrrDeviceSDL : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceSDL(video::E_DRIVER_TYPE deviceType, + const core::dimension2d& windowSize, u32 bits, + bool fullscreen, bool stencilbuffer, bool vsync, + bool antiAlias, IEventReceiver* receiver, + void* windowID, const char* version); + + //! destructor + virtual ~CIrrDeviceSDL(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! pause execution temporarily + virtual void yield(); + + //! pause execution for a specified time + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! presents a surface in the client area + virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes supported + video::IVideoModeList* getVideoModeList(); + + //! Sets if the window should be resizeable in windowed mode. + virtual void setResizeAble(bool resize=false); + + //! Implementation of the linux cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceSDL* dev) + : Device(dev), IsVisible(true) + { + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + if ( visible ) + SDL_ShowCursor( SDL_ENABLE ); + else + SDL_ShowCursor( SDL_DISABLE ); + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + SDL_WarpMouse( x, y ); + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getPosition() + { + updateCursorPos(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateCursorPos(); + return core::position2d(CursorPos.X / (f32)Device->Width, + CursorPos.Y / (f32)Device->Height); + } + + virtual void setReferenceRect(core::rect* rect=0) + { + } + + private: + + void updateCursorPos() + { + CursorPos.X = Device->MouseX; + CursorPos.Y = Device->MouseY; + + if (CursorPos.X < 0) + CursorPos.X = 0; + if (CursorPos.X > (s32)Device->Width) + CursorPos.X = Device->Width; + if (CursorPos.Y < 0) + CursorPos.Y = 0; + if (CursorPos.Y > (s32)Device->Height) + CursorPos.Y = Device->Height; + } + + CIrrDeviceSDL* Device; + core::position2d CursorPos; + bool IsVisible; + }; + + private: + + //! create the driver + void createDriver(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize); + + bool createWindow(video::E_DRIVER_TYPE driverType); + + void createKeyMap(); + + s32 MouseX, MouseY; + u32 Depth; + bool Fullscreen; + bool Stencilbuffer; + bool Vsync; + bool AntiAlias; + bool Resizeable; + + SDL_Surface* Screen; + SDL_Event SDL_event; + int SDL_Flags; + + u32 Width, Height; + bool Close; + bool WindowActive; + + struct SKeyMap + { + SKeyMap() {} + SKeyMap(s32 x11, s32 win32) + : SDLKey(x11), Win32Key(win32) + { + } + + s32 SDLKey; + s32 Win32Key; + + bool operator<(const SKeyMap& o) const + { + return SDLKey KeyMap; + }; + +} // end namespace irr + +#endif // _IRR_USE_SDL_DEVICE_ +#endif // __C_IRR_DEVICE_SDL_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CIrrDeviceStub.cpp b/src/dep/src/irrlicht/CIrrDeviceStub.cpp new file mode 100644 index 0000000..c1b18a9 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceStub.cpp @@ -0,0 +1,226 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceStub.h" +#include "ISceneManager.h" +#include "IEventReceiver.h" +#include "IFileSystem.h" +#include "IGUIEnvironment.h" +#include "os.h" +#include "IrrCompileConfig.h" +#include "CTimer.h" +#include "CLogger.h" +#include "irrString.h" + +namespace irr +{ + +//! constructor +CIrrDeviceStub::CIrrDeviceStub(const char* version, IEventReceiver* recv) +: IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0), + Timer(0), CursorControl(0), UserReceiver(recv), Logger(0), Operator(0), + FileSystem(io::createFileSystem()), InputReceivingSceneManager(0) +{ + Timer = new CTimer(); + Logger = new CLogger(UserReceiver); + os::Printer::Logger = Logger; + + core::stringc s = "Irrlicht Engine version "; + s.append(getVersion()); + os::Printer::log(s.c_str(), ELL_INFORMATION); + + checkVersion(version); +} + + +CIrrDeviceStub::~CIrrDeviceStub() +{ + FileSystem->drop(); + + if (GUIEnvironment) + GUIEnvironment->drop(); + + if (VideoDriver) + VideoDriver->drop(); + + if (SceneManager) + SceneManager->drop(); + + if (InputReceivingSceneManager) + InputReceivingSceneManager->drop(); + + if (CursorControl) + CursorControl->drop(); + + if (Operator) + Operator->drop(); + + CursorControl = 0; + + Timer->drop(); + + Logger->drop(); +} + + +void CIrrDeviceStub::createGUIAndScene() +{ + #ifdef _IRR_COMPILE_WITH_GUI_ + // create gui environment + GUIEnvironment = gui::createGUIEnvironment(FileSystem, VideoDriver, Operator); + #endif + + // create Scene manager + SceneManager = scene::createSceneManager(VideoDriver, FileSystem, CursorControl, GUIEnvironment); + + setEventReceiver(UserReceiver); +} + + +//! returns the video driver +video::IVideoDriver* CIrrDeviceStub::getVideoDriver() +{ + return VideoDriver; +} + + + +//! return file system +io::IFileSystem* CIrrDeviceStub::getFileSystem() +{ + return FileSystem; +} + + + +//! returns the gui environment +gui::IGUIEnvironment* CIrrDeviceStub::getGUIEnvironment() +{ + return GUIEnvironment; +} + + + +//! returns the scene manager +scene::ISceneManager* CIrrDeviceStub::getSceneManager() +{ + return SceneManager; +} + + +//! \return Returns a pointer to the ITimer object. With it the +//! current Time can be received. +ITimer* CIrrDeviceStub::getTimer() +{ + return Timer; +} + + +//! Returns the version of the engine. +const char* CIrrDeviceStub::getVersion() const +{ + return IRRLICHT_SDK_VERSION; +} + +//! \return Returns a pointer to the mouse cursor control interface. +gui::ICursorControl* CIrrDeviceStub::getCursorControl() +{ + return CursorControl; +} + + +//! \return Returns a pointer to a list with all video modes supported +//! by the gfx adapter. +video::IVideoModeList* CIrrDeviceStub::getVideoModeList() +{ + return &VideoModeList; +} + + +//! checks version of sdk and prints warning if there might be a problem +bool CIrrDeviceStub::checkVersion(const char* version) +{ + if (strcmp(getVersion(), version)) + { + core::stringc w; + w = "Warning: The library version of the Irrlicht Engine ("; + w += getVersion(); + w += ") does not match the version the application was compiled with ("; + w += version; + w += "). This may cause problems."; + os::Printer::log(w.c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +//! send the event to the right receiver +void CIrrDeviceStub::postEventFromUser(const SEvent& event) +{ + bool absorbed = false; + + if (UserReceiver) + absorbed = UserReceiver->OnEvent(event); + + if (!absorbed && GUIEnvironment) + absorbed = GUIEnvironment->postEventFromUser(event); + + scene::ISceneManager* inputReceiver = InputReceivingSceneManager; + if (!inputReceiver) + inputReceiver = SceneManager; + + if (!absorbed && inputReceiver) + absorbed = inputReceiver->postEventFromUser(event); +} + + +//! Sets a new event receiver to receive events +void CIrrDeviceStub::setEventReceiver(IEventReceiver* receiver) +{ + UserReceiver = receiver; + Logger->setReceiver(receiver); + if (GUIEnvironment) + GUIEnvironment->setUserEventReceiver(receiver); +} + + +//! Returns poinhter to the current event receiver. Returns 0 if there is none. +IEventReceiver* CIrrDeviceStub::getEventReceiver() +{ + return UserReceiver; +} + + +//! \return Returns a pointer to the logger. +ILogger* CIrrDeviceStub::getLogger() +{ + return Logger; +} + + +//! Returns the operation system opertator object. +IOSOperator* CIrrDeviceStub::getOSOperator() +{ + return Operator; +} + + +//! Sets the input receiving scene manager. +void CIrrDeviceStub::setInputReceivingSceneManager(scene::ISceneManager* sceneManager) +{ + if (InputReceivingSceneManager) + InputReceivingSceneManager->drop(); + + InputReceivingSceneManager = sceneManager; + + if (InputReceivingSceneManager) + InputReceivingSceneManager->grab(); +} + + + +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CIrrDeviceStub.h b/src/dep/src/irrlicht/CIrrDeviceStub.h new file mode 100644 index 0000000..5a1d049 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceStub.h @@ -0,0 +1,124 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_STUB_H_INCLUDED__ +#define __C_IRR_DEVICE_STUB_H_INCLUDED__ + +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "CVideoModeList.h" + +namespace irr +{ + // lots of prototypes: + class ILogger; + class CLogger; + + namespace gui + { + class IGUIEnvironment; + IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs, + video::IVideoDriver* Driver, IOSOperator* op); + } + + namespace scene + { + ISceneManager* createSceneManager(video::IVideoDriver* driver, + io::IFileSystem* fs, gui::ICursorControl* cc, gui::IGUIEnvironment *gui); + } + + namespace io + { + IFileSystem* createFileSystem(); + } + + namespace video + { + IVideoDriver* createSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter); + IVideoDriver* createSoftwareDriver2(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter); + IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize); + } + + + + //! Stub for an Irrlicht Device implementation + class CIrrDeviceStub : public IrrlichtDevice + { + public: + + //! constructor + CIrrDeviceStub(const char* version, IEventReceiver* resv); + + //! destructor + virtual ~CIrrDeviceStub(); + + //! returns the video driver + virtual video::IVideoDriver* getVideoDriver(); + + //! return file system + virtual io::IFileSystem* getFileSystem(); + + //! returns the gui environment + virtual gui::IGUIEnvironment* getGUIEnvironment(); + + //! returns the scene manager + virtual scene::ISceneManager* getSceneManager(); + + //! \return Returns a pointer to the mouse cursor control interface. + virtual gui::ICursorControl* getCursorControl(); + + //! \return Returns a pointer to a list with all video modes supported + //! by the gfx adapter. + virtual video::IVideoModeList* getVideoModeList(); + + //! \return Returns a pointer to the ITimer object. With it the + //! current Time can be received. + virtual ITimer* getTimer(); + + //! Returns the version of the engine. + virtual const char* getVersion() const; + + //! send the event to the right receiver + virtual void postEventFromUser(const SEvent& event); + + //! Sets a new event receiver to receive events + virtual void setEventReceiver(IEventReceiver* receiver); + + //! Returns poinhter to the current event receiver. Returns 0 if there is none. + virtual IEventReceiver* getEventReceiver(); + + //! Sets the input receiving scene manager. + /** If set to null, the main scene manager (returned by GetSceneManager()) will receive the input */ + virtual void setInputReceivingSceneManager(scene::ISceneManager* sceneManager); + + //! \return Returns a pointer to the logger. + virtual ILogger* getLogger(); + + //! Returns the operation system opertator object. + virtual IOSOperator* getOSOperator(); + + protected: + + void createGUIAndScene(); + + //! checks version of sdk and prints warning if there might be a problem + bool checkVersion(const char* version); + + video::IVideoDriver* VideoDriver; + gui::IGUIEnvironment* GUIEnvironment; + scene::ISceneManager* SceneManager; + ITimer* Timer; + gui::ICursorControl* CursorControl; + video::CVideoModeList VideoModeList; + IEventReceiver* UserReceiver; + CLogger* Logger; + IOSOperator* Operator; + io::IFileSystem* FileSystem; + scene::ISceneManager* InputReceivingSceneManager; + }; + +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CIrrDeviceWin32.cpp b/src/dep/src/irrlicht/CIrrDeviceWin32.cpp new file mode 100644 index 0000000..2ffa0bd --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceWin32.cpp @@ -0,0 +1,957 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_USE_WINDOWS_DEVICE_ + +#include "CIrrDeviceWin32.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" + +#include "CTimer.h" +#include "irrString.h" +#include "COSOperator.h" +#include "dimension2d.h" +#include +#include "irrlicht.h" + + +namespace irr +{ + namespace video + { + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + IVideoDriver* createDirectX8Driver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io, + bool pureSoftware, bool highPrecisionFPU, bool vsync, bool antiAlias); + #endif + + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + IVideoDriver* createDirectX9Driver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io, + bool pureSoftware, bool highPrecisionFPU, bool vsync, bool antiAlias); + #endif + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, + bool vsync, bool antiAlias); + #endif + } +} // end namespace irr + + + +struct SEnvMapper +{ + HWND hWnd; + irr::CIrrDeviceWin32* irrDev; +}; + +irr::core::list EnvMap; + +SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return &(*it); + + return 0; +} + +irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return (*it).irrDev; + + return 0; +} + + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x020A + #endif + #ifndef WHEEL_DELTA + #define WHEEL_DELTA 120 + #endif + + irr::CIrrDeviceWin32* dev = 0; + irr::SEvent event; + SEnvMapper* envm = 0; + + BYTE allKeys[256]; + + static irr::s32 ClickCount=0; + if (GetCapture() != hWnd && ClickCount > 0) + ClickCount = 0; + + switch (message) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + } + return 0; + + case WM_ERASEBKGND: + return 0; + + case WM_SETCURSOR: + envm = getEnvMapperFromHWnd(hWnd); + if (envm && !envm->irrDev->getWin32CursorControl()->isVisible()) + { + SetCursor(NULL); + return 0; + } + break; + + case WM_MOUSEWHEEL: + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Wheel = ((irr::f32)((short)HIWORD(wParam))) / (irr::f32)WHEEL_DELTA; + event.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + + POINT p; // fixed by jox + p.x = 0; p.y = 0; + ClientToScreen(hWnd, &p); + event.MouseInput.X = LOWORD(lParam) - p.x; + event.MouseInput.Y = HIWORD(lParam) - p.y; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + break; + + case WM_LBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_LBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_RBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_RBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MOUSEMOVE: + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + dev = getDeviceFromHWnd(hWnd); + + if (dev) + dev->postEventFromUser(event); + + return 0; + + case WM_KEYDOWN: + case WM_KEYUP: + { + event.EventType = irr::EET_KEY_INPUT_EVENT; + event.KeyInput.Key = (irr::EKEY_CODE)wParam; + event.KeyInput.PressedDown = (message==WM_KEYDOWN); + dev = getDeviceFromHWnd(hWnd); + + WORD KeyAsc=0; + GetKeyboardState(allKeys); + ToAscii(wParam,lParam,allKeys,&KeyAsc,0); + + event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); + event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); + event.KeyInput.Char = (KeyAsc & 0x00ff); //KeyAsc >= 0 ? KeyAsc : 0; + + if (dev) + dev->postEventFromUser(event); + + return 0; + } + + case WM_SIZE: + { + // resize + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->OnResized(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_SYSCOMMAND: + // prevent screensaver or monitor powersave mode from starting + if ((wParam & 0xFFF0) == SC_SCREENSAVE || + (wParam & 0xFFF0) == SC_MONITORPOWER) + return 0; + break; + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + +namespace irr +{ + +//! constructor +CIrrDeviceWin32::CIrrDeviceWin32(video::E_DRIVER_TYPE driverType, + core::dimension2d windowSize, + u32 bits, bool fullscreen, + bool stencilbuffer, bool vsync, + bool antiAlias, + bool highPrecisionFPU, + IEventReceiver* receiver, + HWND externalWindow, + const char* version) +: CIrrDeviceStub(version, receiver), HWnd(0), ChangedToFullScreen(false), + FullScreen(fullscreen), IsNonNTWindows(false), Resized(false), + ExternalWindow(false), Win32CursorControl(0) +{ + core::stringc winversion; + getWindowsVersion(winversion); + Operator = new COSOperator(winversion.c_str()); + os::Printer::log(winversion.c_str(), ELL_INFORMATION); + + // create window + + HINSTANCE hInstance = GetModuleHandle(0); + + #ifdef _DEBUG + setDebugName("CIrrDeviceWin32"); + #endif + + // create the window, only if we do not use the null device + if (driverType != video::EDT_NULL && externalWindow==0) + { + const c8* ClassName = "CIrrDeviceWin32"; + + // Register Class + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = NULL; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = 0; + wcex.lpszClassName = ClassName; + wcex.hIconSm = 0; + + // if there is an icon, load it + wcex.hIcon = (HICON)LoadImage(hInstance, "irrlicht.ico", IMAGE_ICON, 0,0, LR_LOADFROMFILE); + + RegisterClassEx(&wcex); + + // calculate client size + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = windowSize.Width; + clientSize.bottom = windowSize.Height; + + DWORD style = WS_POPUP; + + if (!fullscreen) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + AdjustWindowRect(&clientSize, style, FALSE); + + s32 realWidth = clientSize.right - clientSize.left; + s32 realHeight = clientSize.bottom - clientSize.top; + + s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + if (fullscreen) + { + windowLeft = 0; + windowTop = 0; + } + + // create window + + HWnd = CreateWindow( ClassName, "", style, windowLeft, windowTop, + realWidth, realHeight, NULL, NULL, hInstance, NULL); + + ShowWindow(HWnd , SW_SHOW); + UpdateWindow(HWnd); + + // fix ugly ATI driver bugs. Thanks to ariaci + MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE); + } + + // attach external window + if (externalWindow) + { + HWnd = externalWindow; + RECT r; + GetWindowRect(HWnd, &r); + windowSize.Width = r.right - r.left; + windowSize.Height = r.bottom - r.top; + fullscreen = false; + ExternalWindow = true; + } + + // create cursor control + + Win32CursorControl = new CCursorControl(windowSize, HWnd, fullscreen); + CursorControl = Win32CursorControl; + + // create driver + + createDriver(driverType, windowSize, bits, fullscreen, stencilbuffer, vsync, antiAlias, highPrecisionFPU); + + if (VideoDriver) + createGUIAndScene(); + + // register environment + + SEnvMapper em; + em.irrDev = this; + em.hWnd = HWnd; + EnvMap.push_back(em); + + // set this as active window + SetActiveWindow(HWnd); + SetForegroundWindow(HWnd); +} + + + +//! destructor +CIrrDeviceWin32::~CIrrDeviceWin32() +{ + // unregister environment + + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == HWnd) + { + EnvMap.erase(it); + break; + } + + if (ChangedToFullScreen) + ChangeDisplaySettings(NULL,0); +} + + + +//! create the driver +void CIrrDeviceWin32::createDriver(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, + bool fullscreen, + bool stencilbuffer, + bool vsync, + bool antiAlias, + bool highPrecisionFPU) +{ + switch(driverType) + { + case video::EDT_DIRECT3D8: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + VideoDriver = video::createDirectX8Driver(windowSize, HWnd, bits, fullscreen, + stencilbuffer, FileSystem, false, highPrecisionFPU, vsync, antiAlias); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + break; + + case video::EDT_DIRECT3D9: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + VideoDriver = video::createDirectX9Driver(windowSize, HWnd, bits, fullscreen, + stencilbuffer, FileSystem, false, highPrecisionFPU, vsync, antiAlias); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + + break; + + case video::EDT_OPENGL: + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (fullscreen) switchToFullScreen(windowSize.Width, windowSize.Height, bits); + VideoDriver = video::createOpenGLDriver(windowSize, HWnd, bits, fullscreen, stencilbuffer, FileSystem, + vsync, antiAlias); + if (!VideoDriver) + { + os::Printer::log("Could not create OpenGL driver.", ELL_ERROR); + } + #else + os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_SOFTWARE: + + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + if (fullscreen) switchToFullScreen(windowSize.Width, windowSize.Height, bits); + VideoDriver = video::createSoftwareDriver(windowSize, fullscreen, FileSystem, this); + #else + os::Printer::log("Software driver was not compiled in.", ELL_ERROR); + #endif + + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + if (fullscreen) switchToFullScreen(windowSize.Width, windowSize.Height, bits); + VideoDriver = video::createSoftwareDriver2(windowSize, fullscreen, FileSystem, this); + #else + os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_NULL: + // create null driver + VideoDriver = video::createNullDriver(FileSystem, windowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceWin32::run() +{ + os::Timer::tick(); + + MSG msg; + + bool quit = false; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + + if (ExternalWindow && msg.hwnd == HWnd) + WndProc(HWnd, msg.message, msg.wParam, msg.lParam); + else + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + quit = true; + } + + if (!quit) + resizeIfNecessary(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return !quit; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceWin32::yield() +{ + Sleep(1); + +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceWin32::sleep(u32 timeMs, bool pauseTimer) +{ + bool wasStopped = Timer ? Timer->isStopped() : true; + if (pauseTimer && !wasStopped) + Timer->stop(); + + Sleep(timeMs); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +void CIrrDeviceWin32::resizeIfNecessary() +{ + if (!Resized) + return; + + RECT r; + GetClientRect(HWnd, &r); + + char tmp[255]; + + if (r.right < 2 || r.bottom < 2) + { + sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + } + else + { + sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + + getVideoDriver()->OnResize(irr::core::dimension2d(r.right, r.bottom)); + } + + Resized = false; +} + + + +//! sets the caption of the window +void CIrrDeviceWin32::setWindowCaption(const wchar_t* text) +{ + if (IsNonNTWindows) + { + core::stringc s = text; + SetWindowTextA(HWnd, s.c_str()); + } + else + SetWindowTextW(HWnd, text); +} + + + +//! presents a surface in the client area +void CIrrDeviceWin32::present(video::IImage* image, s32 windowId, core::rect* src ) +{ + HWND hwnd = HWnd; + if ( windowId ) + hwnd = (HWND)windowId; + + HDC dc = GetDC(hwnd); + + if ( dc ) + { + RECT rect; + GetClientRect(hwnd, &rect); + const void* memory = (const void *)image->lock(); + + BITMAPV4HEADER bi; + ZeroMemory (&bi, sizeof(bi)); + bi.bV4Size = sizeof(BITMAPINFOHEADER); + bi.bV4BitCount = image->getBitsPerPixel(); + bi.bV4Planes = 1; + bi.bV4Width = image->getDimension().Width; + bi.bV4Height = -image->getDimension().Height; + bi.bV4V4Compression = BI_BITFIELDS; + bi.bV4AlphaMask = image->getAlphaMask (); + bi.bV4RedMask = image->getRedMask (); + bi.bV4GreenMask = image->getGreenMask(); + bi.bV4BlueMask = image->getBlueMask(); + + if ( src ) + { + StretchDIBits(dc, 0,0, rect.right, rect.bottom, + src->UpperLeftCorner.X, src->UpperLeftCorner.Y, + src->getWidth(), src->getHeight(), + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + else + { + StretchDIBits(dc, 0,0, rect.right, rect.bottom, + 0, 0, image->getDimension().Width, image->getDimension().Height, + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + + image->unlock(); + + ReleaseDC(hwnd, dc); + } +} + + + +//! notifies the device that it should close itself +void CIrrDeviceWin32::closeDevice() +{ + MSG msg; + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + PostQuitMessage(0); + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + DestroyWindow(HWnd); +} + + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceWin32::isWindowActive() const +{ + bool ret = (GetActiveWindow() == HWnd); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + + +//! switches to fullscreen +bool CIrrDeviceWin32::switchToFullScreen(s32 width, s32 height, s32 bits) +{ + DEVMODE dm; + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + // use default values from current setting + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); + dm.dmPelsWidth = width; + dm.dmPelsHeight = height; + dm.dmBitsPerPel = bits; + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + + LONG ret = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); + if (ret != DISP_CHANGE_SUCCESSFUL) + { // try again without forcing display frequency + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + ret = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); + } + + switch(ret) + { + case DISP_CHANGE_SUCCESSFUL: + ChangedToFullScreen = true; + return true; + case DISP_CHANGE_RESTART: + os::Printer::log("Switch to fullscreen: The computer must be restarted in order for the graphics mode to work.", ELL_ERROR); + return false; + case DISP_CHANGE_BADFLAGS: + os::Printer::log("Switch to fullscreen: An invalid set of flags was passed in.", ELL_ERROR); + return false; + case DISP_CHANGE_BADPARAM: + os::Printer::log("Switch to fullscreen: An invalid parameter was passed in. This can include an invalid flag or combination of flags.", ELL_ERROR); + return false; + case DISP_CHANGE_FAILED: + os::Printer::log("Switch to fullscreen: The display driver failed the specified graphics mode.", ELL_ERROR); + return false; + case DISP_CHANGE_BADMODE: + os::Printer::log("Switch to fullscreen: The graphics mode is not supported.", ELL_ERROR); + return false; + } + + os::Printer::log("An unknown error occured while changing to fullscreen.", ELL_ERROR); + return false; +} + + +//! returns the win32 cursor control +CIrrDeviceWin32::CCursorControl* CIrrDeviceWin32::getWin32CursorControl() +{ + return Win32CursorControl; +} + + +//! \return Returns a pointer to a list with all video modes supported +//! by the gfx adapter. +video::IVideoModeList* CIrrDeviceWin32::getVideoModeList() +{ + if (!VideoModeList.getVideoModeCount()) + { + // enumerate video modes. + DWORD i=0; + DEVMODE mode; + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(mode); + + while (EnumDisplaySettings(NULL, i, &mode)) + { + VideoModeList.addMode(core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight), + mode.dmBitsPerPel); + + ++i; + } + + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode)) + VideoModeList.setDesktop(mode.dmBitsPerPel, core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight)); + } + + return &VideoModeList; +} + + +void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) +{ + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if(!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO*) &osvi))) + { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + return; + } + + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + if (osvi.dwMajorVersion <= 4) + out.append("Microsoft Windows NT "); + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + out.append("Microsoft Windows 2000 "); + if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) + out.append("Microsoft Windows XP "); + if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 ) + out.append("Microsoft Windows Vista "); + + if( bOsVersionInfoEx ) + { + #ifdef VER_SUITE_ENTERPRISE + if (osvi.wProductType == VER_NT_WORKSTATION) + { +#ifndef __BORLANDC__ + if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) + out.append("Personal "); + else + out.append("Professional "); +#endif + } + else if (osvi.wProductType == VER_NT_SERVER) + { + if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) + out.append("DataCenter Server "); + else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + out.append("Advanced Server "); + else + out.append("Server "); + } + #endif + } + else + { + HKEY hKey; + char szProductType[80]; + DWORD dwBufLen; + + RegOpenKeyEx( HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", + 0, KEY_QUERY_VALUE, &hKey ); + RegQueryValueEx( hKey, "ProductType", NULL, NULL, + (LPBYTE) szProductType, &dwBufLen); + RegCloseKey( hKey ); + + if (lstrcmpi( "WINNT", szProductType) == 0 ) + out.append("Professional "); + if ( lstrcmpi( "LANMANNT", szProductType) == 0 ) + out.append("Server " ); + if ( lstrcmpi( "SERVERNT", szProductType) == 0 ) + out.append("Advanced Server "); + } + + // Display version, service pack (if any), and build number. + + char tmp[255]; + + if (osvi.dwMajorVersion <= 4 ) + { + sprintf (tmp, "version %ld.%ld %s (Build %ld)", + osvi.dwMajorVersion, + osvi.dwMinorVersion, + osvi.szCSDVersion, + osvi.dwBuildNumber & 0xFFFF); + } + else + { + sprintf (tmp, "%s (Build %ld)", osvi.szCSDVersion, + osvi.dwBuildNumber & 0xFFFF); + } + + out.append(tmp); + break; + + case VER_PLATFORM_WIN32_WINDOWS: + + IsNonNTWindows = true; + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) + { + out.append("Microsoft Windows 95 "); + if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) + out.append("OSR2 " ); + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) + { + out.append("Microsoft Windows 98 "); + if ( osvi.szCSDVersion[1] == 'A' ) + out.append( "SE " ); + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) + out.append("Microsoft Windows Me "); + + break; + + case VER_PLATFORM_WIN32s: + + IsNonNTWindows = true; + out.append("Microsoft Win32s "); + break; + } +} + +//! Notifies the device, that it has been resized +void CIrrDeviceWin32::OnResized() +{ + Resized = true; +} + +//! Sets if the window should be resizeable in windowed mode. +void CIrrDeviceWin32::setResizeAble(bool resize) +{ + if (ExternalWindow || !getVideoDriver() || FullScreen) + return; + + LONG style = WS_POPUP; + + if (!resize) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + else + style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX; + + if (!SetWindowLong(HWnd, GWL_STYLE, style)) + os::Printer::log("Could not change window style."); + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = getVideoDriver()->getScreenSize().Width; + clientSize.bottom = getVideoDriver()->getScreenSize().Height; + + AdjustWindowRect(&clientSize, style, FALSE); + + s32 realWidth = clientSize.right - clientSize.left; + s32 realHeight = clientSize.bottom - clientSize.top; + + s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW); +} + + +IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx( + const SIrrlichtCreationParameters& parameters) +{ + CIrrDeviceWin32* dev = new CIrrDeviceWin32( + parameters.DriverType, + parameters.WindowSize, + parameters.Bits, + parameters.Fullscreen, + parameters.Stencilbuffer, + parameters.Vsync, + parameters.AntiAlias, + parameters.HighPrecisionFPU, + parameters.EventReceiver, + reinterpret_cast(parameters.WindowId), + parameters.SDK_version_do_not_use); + + if (dev && !dev->getVideoDriver() && parameters.DriverType != video::EDT_NULL) + { + dev->closeDevice(); // destroy window + dev->run(); // consume quit message + dev->drop(); + dev = 0; + } + + return dev; +} + + +} // end namespace + +#endif // _IRR_USE_WINDOWS_DEVICE_ + diff --git a/src/dep/src/irrlicht/CIrrDeviceWin32.h b/src/dep/src/irrlicht/CIrrDeviceWin32.h new file mode 100644 index 0000000..5bf59ba --- /dev/null +++ b/src/dep/src/irrlicht/CIrrDeviceWin32.h @@ -0,0 +1,261 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_WIN32_H_INCLUDED__ +#define __C_IRR_DEVICE_WIN32_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_USE_WINDOWS_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" + +#define WIN32_LEAN_AND_MEAN +#include + +namespace irr +{ + class CIrrDeviceWin32 : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceWin32(video::E_DRIVER_TYPE deviceType, + core::dimension2d windowSize, u32 bits, + bool fullscreen, bool stencilbuffer, bool vsync, + bool antiAlias, bool highPrecisionFPU, + IEventReceiver* receiver, + HWND window, + const char* version); + + //! destructor + virtual ~CIrrDeviceWin32(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! presents a surface in the client area + virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); + + //! Notifies the device, that it has been resized + void OnResized(); + + //! Sets if the window should be resizeable in windowed mode. + virtual void setResizeAble(bool resize=false); + + //! Implementation of the win32 cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(const core::dimension2d& wsize, HWND hwnd, bool fullscreen) + : WindowSize(wsize), InvWindowSize(0.0f, 0.0f), IsVisible(true), + HWnd(hwnd), BorderX(0), BorderY(0), UseReferenceRect(false) + { + if (WindowSize.Width!=0) + InvWindowSize.Width = 1.0f / WindowSize.Width; + + if (WindowSize.Height!=0) + InvWindowSize.Height = 1.0f / WindowSize.Height; + + if (!fullscreen) + { + BorderX = GetSystemMetrics(SM_CXDLGFRAME); + BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME); + } + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + if (!UseReferenceRect) + setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); + else + setPosition((s32)(x*ReferenceRect.getWidth()), (s32)(y*ReferenceRect.getHeight())); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + RECT rect; + + if (UseReferenceRect) + { + SetCursorPos(ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + } + else + { + if (GetWindowRect(HWnd, &rect)) + SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY); + } + + CursorPos.X = x; + CursorPos.Y = y; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getPosition() + { + updateInternalCursorPosition(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateInternalCursorPosition(); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + private: + + //! Updates the internal cursor position + void updateInternalCursorPosition() + { + POINT p; + GetCursorPos(&p); + RECT rect; + + if (UseReferenceRect) + { + CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X; + CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y; + } + else + { + if (GetWindowRect(HWnd, &rect)) + { + CursorPos.X = p.x-rect.left-BorderX; + CursorPos.Y = p.y-rect.top-BorderY; + } + else + { + // window seems not to be existent, so set cursor to + // a negative value + CursorPos.X = -1; + CursorPos.Y = -1; + } + } + } + + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + bool IsVisible; + HWND HWnd; + + s32 BorderX, BorderY; + bool UseReferenceRect; + core::rect ReferenceRect; + }; + + + //! returns the win32 cursor control + CCursorControl* getWin32CursorControl(); + + private: + + //! create the driver + void createDriver(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, u32 bits, bool fullscreen, + bool stencilbuffer, bool vsync, bool antiAlias, bool highPrecisionFPU); + + //! switchs to fullscreen + bool switchToFullScreen(s32 width, s32 height, s32 bits); + + void getWindowsVersion(core::stringc& version); + + void resizeIfNecessary(); + + HWND HWnd; + + bool ChangedToFullScreen; + bool FullScreen; + bool IsNonNTWindows; + bool Resized; + bool ExternalWindow; + CCursorControl* Win32CursorControl; + }; + + +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/CIrrMeshFileLoader.cpp b/src/dep/src/irrlicht/CIrrMeshFileLoader.cpp new file mode 100644 index 0000000..b7c6bcc --- /dev/null +++ b/src/dep/src/irrlicht/CIrrMeshFileLoader.cpp @@ -0,0 +1,585 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + +#include "CIrrMeshFileLoader.h" +#include "os.h" +#include "IXMLReader.h" +#include "SAnimatedMesh.h" +#include "fast_atof.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "IMeshSceneNode.h" +#include "SMeshBufferLightMap.h" + +namespace irr +{ +namespace scene +{ + + +//! Constructor +CIrrMeshFileLoader::CIrrMeshFileLoader(video::IVideoDriver* driver, + scene::ISceneManager* smgr, io::IFileSystem* fs) + : Driver(driver), SceneManager(smgr), FileSystem(fs) +{ +} + + +//! destructor +CIrrMeshFileLoader::~CIrrMeshFileLoader() +{ +} + + +//! Returns true if the file maybe is able to be loaded by this class. +/** This decision should be based only on the file extension (e.g. ".cob") */ +bool CIrrMeshFileLoader::isALoadableFileExtension(const c8* fileName) const +{ + return strstr(fileName, ".xml") || + strstr(fileName, ".irrmesh"); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CIrrMeshFileLoader::createMesh(io::IReadFile* file) +{ + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + return 0; + + // read until mesh section, skip other parts + + const core::stringc meshTagName = "mesh"; + IAnimatedMesh* mesh = 0; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (meshTagName == reader->getNodeName()) + { + mesh = readMesh(reader); + break; + } + else + skipSection(reader, true); // unknown section + } + } + + reader->drop(); + + return mesh; +} + + +//! reads a mesh sections and creates a mesh from it +IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) +{ + SAnimatedMesh* animatedmesh = new SAnimatedMesh(); + SMesh* mesh = new SMesh(); + + animatedmesh->addMesh(mesh); + mesh->drop(); + + core::stringc bbSectionName = "boundingBox"; + core::stringc bufferSectionName = "buffer"; + core::stringc meshSectionName = "mesh"; + + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const wchar_t* nodeName = reader->getNodeName(); + if (bbSectionName == nodeName) + { + // inside a bounding box, ignore it for now because + // we are calculating this anyway ourselves later. + } + else + if (bufferSectionName == nodeName) + { + // we've got a mesh buffer + + IMeshBuffer* buffer = readMeshBuffer(reader); + if (buffer) + { + mesh->addMeshBuffer(buffer); + buffer->drop(); + } + } + else + skipSection(reader, true); // unknown section + + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (meshSectionName == reader->getNodeName()) + { + // end of mesh section reached, cancel out + break; + } + } + } // end while reader->read(); + + mesh->recalculateBoundingBox(); + animatedmesh->recalculateBoundingBox(); + + return animatedmesh; +} + + +//! reads a mesh sections and creates a mesh buffer from it +IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) +{ + IMeshBuffer* buffer = 0; + SMeshBuffer* sbuffer1 = 0; + SMeshBufferLightMap* sbuffer2 = 0; + SMeshBufferTangents* sbuffer3 = 0; + + core::stringc verticesSectionName = "vertices"; + core::stringc bbSectionName = "boundingBox"; + core::stringc materialSectionName = "material"; + core::stringc indicesSectionName = "indices"; + core::stringc bufferSectionName = "buffer"; + + bool insideVertexSection = false; + bool insideIndexSection = false; + + int vertexCount = 0; + int indexCount = 0; + + video::SMaterial material; + + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const wchar_t* nodeName = reader->getNodeName(); + if (bbSectionName == nodeName) + { + // inside a bounding box, ignore it for now because + // we are calculating this anyway ourselves later. + } + else + if (materialSectionName == nodeName) + { + //we've got a material + + io::IAttributes* attributes = FileSystem->createEmptyAttributes(Driver); + attributes->read(reader, true, L"material"); + + Driver->fillMaterialStructureFromAttributes(material, attributes); + attributes->drop(); + } + else + if (verticesSectionName == nodeName) + { + // vertices section + + core::stringc vertexTypeName1 = "standard"; + core::stringc vertexTypeName2 = "2tcoords"; + core::stringc vertexTypeName3 = "tangents"; + + const wchar_t* vertexType = reader->getAttributeValue(L"type"); + vertexCount = reader->getAttributeValueAsInt(L"vertexCount"); + + insideVertexSection = true; + + if (vertexTypeName1 == vertexType) + { + sbuffer1 = new SMeshBuffer(); + sbuffer1->Vertices.reallocate(vertexCount); + sbuffer1->Material = material; + buffer = sbuffer1; + } + else + if (vertexTypeName2 == vertexType) + { + sbuffer2 = new SMeshBufferLightMap(); + sbuffer2->Vertices.reallocate(vertexCount); + sbuffer2->Material = material; + buffer = sbuffer2; + } + else + if (vertexTypeName3 == vertexType) + { + sbuffer3 = new SMeshBufferTangents(); + sbuffer3->Vertices.reallocate(vertexCount); + sbuffer3->Material = material; + buffer = sbuffer3; + } + } + else + if (indicesSectionName == nodeName) + { + // indices section + + indexCount = reader->getAttributeValueAsInt(L"indexCount"); + insideIndexSection = true; + } + + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_TEXT) + { + // read vertex data + if (insideVertexSection) + { + if (sbuffer1) + readMeshBuffer(reader, vertexCount, sbuffer1); + else + if (sbuffer2) + readMeshBuffer(reader, vertexCount, sbuffer2); + else + if (sbuffer3) + readMeshBuffer(reader, vertexCount, sbuffer3); + + insideVertexSection = false; + + } // end reading vertex array + else + if (insideIndexSection) + { + if (sbuffer1) + readIndices(reader, indexCount, sbuffer1->Indices); + else + if (sbuffer2) + readIndices(reader, indexCount, sbuffer2->Indices); + else + if (sbuffer2) + readIndices(reader, indexCount, sbuffer3->Indices); + + insideIndexSection = false; + } + + } // end if node type is text + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (bufferSectionName == reader->getNodeName()) + { + // end of buffer section reached, cancel out + break; + } + } + } // end while reader->read(); + + if (buffer) + buffer->recalculateBoundingBox(); + + return buffer; +} + + +//! read indices +void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, core::array& indices) +{ + indices.reallocate(indexCount); + + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (int i=0; igetNodeData(); + const c8* p = &data[0]; + + if (sbuffer) + { + video::S3DVertex vtx; + + for (int i=0; iVertices.push_back(vtx); + } + } +} + + +void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferLightMap* sbuffer) +{ + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + if (sbuffer) + { + video::S3DVertex2TCoords vtx; + + for (int i=0; iVertices.push_back(vtx); + } + } +} + + +void CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferTangents* sbuffer) +{ + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + if (sbuffer) + { + video::S3DVertexTangents vtx; + + for (int i=0; iVertices.push_back(vtx); + } + } +} + + +//! skips an (unknown) section in the irrmesh document +void CIrrMeshFileLoader::skipSection(io::IXMLReader* reader, bool reportSkipping) +{ +#ifdef _DEBUG + os::Printer::log("irrMesh skipping section", core::stringc(reader->getNodeName()).c_str()); +#endif + + // skip if this element is empty anyway. + if (reader->isEmptyElement()) + return; + + // read until we've reached the last element in this section + u32 tagCounter = 1; + + while(tagCounter && reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + !reader->isEmptyElement()) + { + #ifdef _DEBUG + if (reportSkipping) + os::Printer::log("irrMesh unknown element:", core::stringc(reader->getNodeName()).c_str()); + #endif + + ++tagCounter; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + --tagCounter; + } +} + + +//! parses a float from a char pointer and moves the pointer +//! to the end of the parsed float +inline f32 CIrrMeshFileLoader::readFloat(const c8** p) +{ + f32 ftmp; + *p = core::fast_atof_move(*p, ftmp); + return ftmp; +} + + +//! parses an int from a char pointer and moves the pointer to +//! the end of the parsed float +inline s32 CIrrMeshFileLoader::readInt(const c8** p) +{ + return (s32)readFloat(p); +} + + +//! places pointer to next begin of a token +void CIrrMeshFileLoader::skipCurrentNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && !(*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + +//! places pointer to next begin of a token +void CIrrMeshFileLoader::findNextNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + + +//! reads floats from inside of xml element until end of xml element +void CIrrMeshFileLoader::readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count) +{ + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + // TODO: check for comments inside the element + // and ignore them. + + if (reader->getNodeType() == io::EXN_TEXT) + { + // parse float data + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + break; // end parsing text + } +} + + + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_IRR_MESH_LOADER_ diff --git a/src/dep/src/irrlicht/CIrrMeshFileLoader.h b/src/dep/src/irrlicht/CIrrMeshFileLoader.h new file mode 100644 index 0000000..c242569 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrMeshFileLoader.h @@ -0,0 +1,96 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_IRR_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + + +//! Meshloader capable of loading .irrmesh meshes, the Irrlicht Engine mesh format for static meshes +class CIrrMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CIrrMeshFileLoader(video::IVideoDriver* driver, + scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~CIrrMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + //! reads a mesh sections and creates a mesh from it + IAnimatedMesh* readMesh(io::IXMLReader* reader); + + //! reads a mesh sections and creates a mesh buffer from it + IMeshBuffer* readMeshBuffer(io::IXMLReader* reader); + + //! skips an (unknown) section in the irrmesh file + void skipSection(io::IXMLReader* reader, bool reportSkipping); + + //! reads a element and stores it in the material section + void readMaterial(io::IXMLReader* reader); + + //! parses a float from a char pointer and moves the pointer to + //! the end of the parsed float + inline f32 readFloat(const c8** p); + + //! parses an int from a char pointer and moves the pointer to + //! the end of the parsed float + inline s32 readInt(const c8** p); + + //! places pointer to next begin of a token + void findNextNoneWhiteSpace(const c8** p); + + //! places pointer to next begin of a token + void skipCurrentNoneWhiteSpace(const c8** p); + + //! reads floats from inside of xml element until end of xml element + void readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count); + + //! read all 3 types of mesh buffers + void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBuffer* sbuffer); + void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferLightMap* sbuffer); + void readMeshBuffer(io::IXMLReader* reader, int vertexCount, SMeshBufferTangents* sbuffer); + + //! read indices + void readIndices(io::IXMLReader* reader, int indexCount, core::array& indices); + + + // member variables + + video::IVideoDriver* Driver; + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CIrrMeshWriter.cpp b/src/dep/src/irrlicht/CIrrMeshWriter.cpp new file mode 100644 index 0000000..9a6399e --- /dev/null +++ b/src/dep/src/irrlicht/CIrrMeshWriter.cpp @@ -0,0 +1,289 @@ +#include "CIrrMeshWriter.h" +#include "os.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" +#include "IMesh.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + + +CIrrMeshWriter::CIrrMeshWriter(video::IVideoDriver* driver, + io::IFileSystem* fs) + : FileSystem(fs), VideoDriver(driver), Writer(0) +{ + if (VideoDriver) + VideoDriver->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +CIrrMeshWriter::~CIrrMeshWriter() +{ + if (VideoDriver) + VideoDriver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CIrrMeshWriter::getType() const +{ + return EMWT_IRR_MESH; +} + + +//! writes a mesh +bool CIrrMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + Writer = FileSystem->createXMLWriter(file); + + if (!Writer) + { + os::Printer::log("Could not write file", file->getFileName()); + return false; + } + + os::Printer::log("Writing mesh", file->getFileName()); + + // write IRR MESH header + + Writer->writeXMLHeader(); + + Writer->writeElement(L"mesh", false, + L"xmlns", L"http://irrlicht.sourceforge.net/IRRMESH_09_2007", + L"version", L"1.0"); + Writer->writeLineBreak(); + + // add some informational comment. Add a space after and before the comment + // tags so that some braindead xml parsers (AS anyone?) are able to parse this too. + + core::stringw infoComment = L" This file contains a static mesh in the Irrlicht Engine format with "; + infoComment += core::stringw(mesh->getMeshBufferCount()); + infoComment += L" materials."; + + Writer->writeComment(infoComment.c_str()); + Writer->writeLineBreak(); + + // write mesh bounding box + + writeBoundingBox(mesh->getBoundingBox()); + Writer->writeLineBreak(); + + // write mesh buffers + + for (int i=0; i<(int)mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + writeMeshBuffer(buffer); + Writer->writeLineBreak(); + } + } + + Writer->writeClosingTag(L"mesh"); + + Writer->drop(); + return true; +} + + +void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box) +{ + Writer->writeElement(L"boundingBox", true, + L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(), + L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str() ); +} + + +core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector3df& v) const +{ + core::stringw str; + + str = core::stringw(v.X); + str += L" "; + str += core::stringw(v.Y); + str += L" "; + str += core::stringw(v.Z); + + return str; +} + + +core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector2df& v) const +{ + core::stringw str; + + str = core::stringw(v.X); + str += L" "; + str += core::stringw(v.Y); + + return str; +} + + +void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer) +{ + Writer->writeElement(L"buffer", false); + Writer->writeLineBreak(); + + // write bounding box + + writeBoundingBox(buffer->getBoundingBox()); + Writer->writeLineBreak(); + + // write material + + writeMaterial(buffer->getMaterial()); + + // write vertices + + const core::stringw vertexTypeStr = video::sBuiltInVertexTypeNames[buffer->getVertexType()]; + + Writer->writeElement(L"vertices", false, + L"type", vertexTypeStr.c_str(), + L"vertexCount", core::stringw(buffer->getVertexCount()).c_str()); + + Writer->writeLineBreak(); + + u32 vertexCount = buffer->getVertexCount(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + } + + Writer->writeClosingTag(L"vertices"); + Writer->writeLineBreak(); + + // write indices + + Writer->writeElement(L"indices", false, + L"indexCount", core::stringw(buffer->getIndexCount()).c_str()); + + Writer->writeLineBreak(); + + int indexCount = (int)buffer->getIndexCount(); + const u16* idx = buffer->getIndices(); + const int maxIndicesPerLine = 25; + + for (int i=0; iwriteText(str.c_str()); + + if (i % maxIndicesPerLine != maxIndicesPerLine) + { + if (i % maxIndicesPerLine == maxIndicesPerLine-1) + Writer->writeLineBreak(); + else + Writer->writeText(L" "); + } + } + + if ((indexCount-1) % maxIndicesPerLine != maxIndicesPerLine-1) + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"indices"); + Writer->writeLineBreak(); + + // close buffer tag + + Writer->writeClosingTag(L"buffer"); +} + + +void CIrrMeshWriter::writeMaterial(const video::SMaterial& material) +{ + // simply use irrlichts built-in attribute serialization capabilities here: + + io::IAttributes* attributes = + VideoDriver->createAttributesFromMaterial(material); + + if (attributes) + { + attributes->write(Writer, false, L"material"); + attributes->drop(); + } +} + + +} // end namespace +} // end namespace + diff --git a/src/dep/src/irrlicht/CIrrMeshWriter.h b/src/dep/src/irrlicht/CIrrMeshWriter.h new file mode 100644 index 0000000..e3336b4 --- /dev/null +++ b/src/dep/src/irrlicht/CIrrMeshWriter.h @@ -0,0 +1,59 @@ +#ifndef __IRR_IRR_MESH_WRITER_H_INCLUDED__ +#define __IRR_IRR_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; +} +namespace scene +{ + class IMeshBuffer; + + + //! class to write meshes, implementing a IrrMesh (.irrmesh, .xml) writer + /** This writer implementation has been originally developed for irrEdit and then + merged out to the Irrlicht Engine */ + class CIrrMeshWriter : public IMeshWriter + { + public: + + CIrrMeshWriter(video::IVideoDriver* driver, io::IFileSystem* fs); + virtual ~CIrrMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + protected: + + void writeBoundingBox(const core::aabbox3df& box); + + void writeMeshBuffer(const scene::IMeshBuffer* buffer); + + void writeMaterial(const video::SMaterial& material); + + core::stringw getVectorAsStringLine(const core::vector3df& v) const; + + core::stringw getVectorAsStringLine(const core::vector2df& v) const; + + // member variables: + + io::IFileSystem* FileSystem; + video::IVideoDriver* VideoDriver; + io::IXMLWriter* Writer; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CLMTSMeshFileLoader.cpp b/src/dep/src/irrlicht/CLMTSMeshFileLoader.cpp new file mode 100644 index 0000000..da073a0 --- /dev/null +++ b/src/dep/src/irrlicht/CLMTSMeshFileLoader.cpp @@ -0,0 +1,325 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// This file was written by Jonas Petersen and modified by Nikolaus Gebhardt. +// See CLMTSMeshFileLoder.h for details. +/* + +CLMTSMeshFileLoader.cpp + +LMTSMeshFileLoader +Written by Jonas Petersen (a.k.a. jox) + +Version 1.5 - 15 March 2005 + +Get the latest version here: http://development.mindfloaters.de/ + +This is an addon class for the Irrlicht engine by Nikolaus Gebhardt (http://irrlicht.sourceforge.net). +With this release the Irrlicht engine is at version 0.6 + +This class allows loading meshes with lightmaps (*.lmts + *.tga files) that were created +using Pulsar LMTools by Lord Trancos (http://www.geocities.com/dxlab/index_en.html) + +Notes: +- This version does not recognice/support user data in the *.lmts files. +- The lightmap TGA's generated by LMTools doesn't work in Irrlicht for some reason (the + lightmaps look messed up). Opening and resaving them in a graphics app will solve + the problem (tested only with Photoshop). + + +License: +-------- + +It's free. You are encouraged to give me credit if you use it in your software. + +Version History: +---------------- + +Version 1.5 - 15 March 2005 +- Did a better cleanup. No memory leaks in case of an loading error. +- Added "#include " for sprintf. + +Version 1.4 - 12 March 2005 +- Fixed bug in texture and subset loading code that would possibly cause crash. +- Fixed memory cleanup to avoid leak when loading more then one mesh +- Used the irrlicht Logger instead of cerr to output warnings and errors. + For this I had to change the constructor + from: + CLMTSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) + to: + CLMTSMeshFileLoader(IrrlichtDevice* device) + +Version 1.3 - 15 February 2005 +- Fixed bug that prevented loading more than one different lmts files. +- Removed unnecessary "#include ". +- Added "std::" in front of "cerr". This was necessary for Visual Studio .NET, + I hope it's not disturbing other compilers. +- Added warning message when a texture can not be loaded. +- Changed the documentation a bit (minor). + +Version 1.2 +- To avoid confusion I skipped version 1.2 because the website was offering +version 1.2 even though it was only version 1.1. Sorry about that. + +Version 1.1 - 29 July 2004 +- Added setTexturePath() function +- Minor improvements + +Version 1.0 - 29 July 2004 +- Initial release + + +*/ +////////////////////////////////////////////////////////////////////// + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ + +#include "SMeshBufferLightMap.h" +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "irrString.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "ISceneManager.h" +#include "CLMTSMeshFileLoader.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +CLMTSMeshFileLoader::CLMTSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver, + io::IAttributes* parameters) + : Textures(0), Subsets(0), Triangles(0), + Parameters(parameters), Driver(driver), FileSystem(fs) +{ + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +CLMTSMeshFileLoader::~CLMTSMeshFileLoader() +{ + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + +void CLMTSMeshFileLoader::cleanup() +{ + delete [] Textures; + delete [] Subsets; + delete [] Triangles; +} + + +bool CLMTSMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".lmts") != 0; +} + + +IAnimatedMesh* CLMTSMeshFileLoader::createMesh(io::IReadFile* file) +{ + u32 i; + u32 id; + + // HEADER + + file->read(&Header, sizeof(SLMTSHeader)); + if (Header.MagicID != 0x53544D4C) { // "LMTS" + os::Printer::log("LMTS ERROR: wrong header magic id!", ELL_ERROR); + return 0; + } + + // TEXTURES + + file->read(&id, sizeof(u32)); + if (id != 0x54584554) { // "TEXT" + os::Printer::log("LMTS ERROR: wrong texture magic id!", ELL_ERROR); + return 0; + } + + Textures = new SLMTSTextureInfoEntry[Header.TextureCount]; + core::array textureIDs; + textureIDs.reallocate(Header.TextureCount); + + u32 numLightMaps = 0; + u32 numTextures = 0; + + for (i=0; iread(&Textures[i], sizeof(SLMTSTextureInfoEntry)); + if (Textures[i].Flags & 1) + textureIDs.push_back(numLightMaps++); + else + textureIDs.push_back(numTextures++); + } + + // SUBSETS + + file->read(&id, sizeof(u32)); + if (id != 0x53425553) // "SUBS" + { + os::Printer::log("LMTS ERROR: wrong subset magic id!", ELL_ERROR); + cleanup(); + return 0; + } + + Subsets = new SLMTSSubsetInfoEntry[Header.SubsetCount]; + + for (i=0; iread(&Subsets[i], sizeof(SLMTSSubsetInfoEntry)); + + // TRIANGLES + + file->read(&id, sizeof(u32)); + if (id != 0x53495254) // "TRIS" + { + os::Printer::log("LMTS ERROR: wrong triangle magic id!", ELL_ERROR); + cleanup(); + return 0; + } + + Triangles = new SLMTSTriangleDataEntry[(Header.TriangleCount*3)]; + + for (i=0; i<(Header.TriangleCount*3); ++i) + file->read(&Triangles[i], sizeof(SLMTSTriangleDataEntry)); + + ///////////////////////////////////////////////////////////////// + + SMesh* mesh = new SMesh(); + + constructMesh(mesh); + + loadTextures(mesh, numLightMaps, numTextures, textureIDs); + + cleanup(); + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_LMTS; // not unknown to irrlicht anymore + + am->addMesh(mesh); + am->recalculateBoundingBox(); + mesh->drop(); + return am; +} + + +void CLMTSMeshFileLoader::constructMesh(SMesh* mesh) +{ + for (s32 i=0; iMaterial.MaterialType = video::EMT_LIGHTMAP; // EMT_LIGHTMAP_M2/EMT_LIGHTMAP_M4 also possible + meshBuffer->Material.Wireframe = false; + meshBuffer->Material.Lighting = false; + + mesh->addMeshBuffer(meshBuffer); + + const u32 offs = Subsets[i].Offset * 3; + + for (u32 sc=0; scgetVertexCount(); + + for (u32 vu=0; vu<3; ++vu) + { + const SLMTSTriangleDataEntry& v = Triangles[offs+(3*sc)+vu]; + meshBuffer->Vertices.push_back( + video::S3DVertex2TCoords( + v.X, v.Y, v.Z, + video::SColor(255,255,255,255), + v.U1, v.V1, v.U2, v.V2)); + } + const core::vector3df normal = core::plane3df( + meshBuffer->Vertices[idx].Pos, + meshBuffer->Vertices[idx+1].Pos, + meshBuffer->Vertices[idx+2].Pos).Normal; + + meshBuffer->Vertices[idx].Normal = normal; + meshBuffer->Vertices[idx+1].Normal = normal; + meshBuffer->Vertices[idx+2].Normal = normal; + + meshBuffer->Indices.push_back(idx); + meshBuffer->Indices.push_back(idx+1); + meshBuffer->Indices.push_back(idx+2); + } + meshBuffer->drop(); + } + + for (u32 j=0; jMeshBuffers.size(); ++j) + mesh->MeshBuffers[j]->recalculateBoundingBox(); + + mesh->recalculateBoundingBox(); +} + + +void CLMTSMeshFileLoader::loadTextures(SMesh* mesh, u32 numTextures, u32 numLightMaps, const core::array& textureIDs) +{ + if (!Driver || !FileSystem) + return; + + core::stringc s; + + // load textures + + core::array tex; + tex.set_used(numTextures); + + core::array lig; + lig.set_used(numLightMaps); + + s32 tx_count = 0; + s32 lm_count = 0; + const core::stringc Path = Parameters->getAttributeAsString(LMTS_TEXTURE_PATH); + + for (s32 t=0; texistFile(s.c_str())) + tmptex = Driver->getTexture(s.c_str()); + else + { + char buf[512]; // filenames may be 256 bytes long + sprintf(buf, "LMTS WARNING: Texture does not exist: %s", s.c_str()); + os::Printer::log(buf, ELL_WARNING); + } + + if (Textures[t].Flags & 1) + lig[lm_count++] = tmptex; + else + tex[tx_count++] = tmptex; + } + + // attach textures to materials. + + for (s32 i=0; igetMeshBuffer(i)->getMaterial().setTexture(0, tex[textureIDs[Subsets[i].TextID1]]); + if (Subsets[i].TextID2 < Header.TextureCount) + mesh->getMeshBuffer(i)->getMaterial().setTexture(1, lig[textureIDs[Subsets[i].TextID2]]); + + if (!mesh->getMeshBuffer(i)->getMaterial().getTexture(1)) + mesh->getMeshBuffer(i)->getMaterial().MaterialType = video::EMT_SOLID; + } +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_LMTS_LOADER_ + diff --git a/src/dep/src/irrlicht/CLMTSMeshFileLoader.h b/src/dep/src/irrlicht/CLMTSMeshFileLoader.h new file mode 100644 index 0000000..dcbe85d --- /dev/null +++ b/src/dep/src/irrlicht/CLMTSMeshFileLoader.h @@ -0,0 +1,125 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// I (Nikolaus Gebhardt) did some few changes to Jonas Petersen's original loader: +// - removed setTexturePath() and replaced with the ISceneManager::getStringParameter()-stuff. +// - added EAMT_LMTS enumeration value +// Thanks a lot to Jonas Petersen for his work +// on this and that he gave me his permission to add it into Irrlicht. +/* + +CLMTSMeshFileLoader.h + +LMTSMeshFileLoader +Written by Jonas Petersen (a.k.a. jox) + +Version 1.5 - 15 March 2005 + +*/ + +#if !defined(__C_LMTS_MESH_FILE_LOADER_H_INCLUDED__) +#define __C_LMTS_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "SMesh.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + +class CLMTSMeshFileLoader : public IMeshLoader +{ +public: + + CLMTSMeshFileLoader(io::IFileSystem* fs, + video::IVideoDriver* driver, io::IAttributes* parameters); + + virtual ~CLMTSMeshFileLoader(); + + virtual bool isALoadableFileExtension(const c8* fileName) const; + + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + void constructMesh(SMesh* mesh); + void loadTextures(SMesh* mesh, u32 numTextures, u32 numLightMaps, const core::array& textureIDs); + void cleanup(); + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + struct SLMTSMagigID { + u32 ID; + } PACK_STRUCT; + + struct SLMTSHeader + { + u32 MagicID; + u32 Version; + u32 HeaderSize; + u16 TextureCount; + u16 SubsetCount; + u32 TriangleCount; + u16 SubsetSize; + u16 VertexSize; + } PACK_STRUCT; + + struct SLMTSTextureInfoEntry + { + c8 Filename[256]; + u16 Flags; + } PACK_STRUCT; + + struct SLMTSSubsetInfoEntry + { + u32 Offset; + u32 Count; + u16 TextID1; + u16 TextID2; + } PACK_STRUCT; + + struct SLMTSTriangleDataEntry + { + f32 X; + f32 Y; + f32 Z; + f32 U1; + f32 V1; + f32 U2; + f32 V2; + } PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + SLMTSHeader Header; + SLMTSTextureInfoEntry* Textures; + SLMTSSubsetInfoEntry* Subsets; + SLMTSTriangleDataEntry* Triangles; + + io::IAttributes* Parameters; + video::IVideoDriver* Driver; + io::IFileSystem* FileSystem; +}; + +} // end namespace scene +} // end namespace irr + +#endif // !defined(__C_LMTS_MESH_FILE_LOADER_H_INCLUDED__) + diff --git a/src/dep/src/irrlicht/CLightSceneNode.cpp b/src/dep/src/irrlicht/CLightSceneNode.cpp new file mode 100644 index 0000000..98d5b06 --- /dev/null +++ b/src/dep/src/irrlicht/CLightSceneNode.cpp @@ -0,0 +1,192 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLightSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" + +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, video::SColorf color,f32 radius) +: ILightSceneNode(parent, mgr, id, position) +{ + #ifdef _DEBUG + setDebugName("CLightSceneNode"); + #endif + + LightData.Radius = radius; + LightData.DiffuseColor = color; + + // set some useful specular color + LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.7f); + + doLightRecalc(); +} + + +//! pre render event +void CLightSceneNode::OnRegisterSceneNode() +{ + doLightRecalc(); + + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_LIGHT); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! render +void CLightSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if (!driver) + return; + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + + switch ( LightData.Type ) + { + case video::ELT_POINT: + case video::ELT_SPOT: + driver->draw3DBox(BBox, LightData.DiffuseColor.toSColor()); + break; + + case video::ELT_DIRECTIONAL: + driver->draw3DLine(core::vector3df(0.f, 0.f, 0.f), + LightData.Direction * LightData.Radius, + LightData.DiffuseColor.toSColor()); + break; + } + } + driver->addDynamicLight(LightData); +} + + +//! sets the light data +void CLightSceneNode::setLightData(const video::SLight& light) +{ + LightData = light; +} + + +//! \return Returns the light data. +const video::SLight& CLightSceneNode::getLightData() const +{ + return LightData; +} + + +//! \return Returns the light data. +video::SLight& CLightSceneNode::getLightData() +{ + return LightData; +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CLightSceneNode::getBoundingBox() const +{ + return BBox; +} + + +void CLightSceneNode::doLightRecalc() +{ + if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL)) + { + LightData.Direction = core::vector3df(.0f,.0f,1.0f); + getAbsoluteTransformation().rotateVect(LightData.Direction); + LightData.Direction.normalize(); + } + if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT)) + { + const f32 r = LightData.Radius * LightData.Radius * 0.5f; + BBox.MaxEdge.set( r, r, r ); + BBox.MinEdge.set( -r, -r, -r ); + setAutomaticCulling( scene::EAC_BOX ); + LightData.Position = getAbsolutePosition(); + } + if (LightData.Type == video::ELT_DIRECTIONAL) + { + BBox.reset( 0, 0, 0 ); + setAutomaticCulling( scene::EAC_OFF ); + } +} + + +//! Writes attributes of the scene node. +void CLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ILightSceneNode::serializeAttributes(out, options); + + out->addColorf ("AmbientColor", LightData.AmbientColor); + out->addColorf ("DiffuseColor", LightData.DiffuseColor); + out->addColorf ("SpecularColor", LightData.SpecularColor); + out->addVector3d("Attenuation", LightData.Attenuation); + out->addFloat ("Radius", LightData.Radius); + out->addFloat ("OuterCone", LightData.OuterCone); + out->addFloat ("InnerCone", LightData.InnerCone); + out->addFloat ("Falloff", LightData.Falloff); + out->addBool ("CastShadows", LightData.CastShadows); + out->addEnum ("LightType", LightData.Type, video::LightTypeNames); +} + +//! Reads attributes of the scene node. +void CLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + LightData.AmbientColor = in->getAttributeAsColorf("AmbientColor"); + LightData.DiffuseColor = in->getAttributeAsColorf("DiffuseColor"); + LightData.SpecularColor = in->getAttributeAsColorf("SpecularColor"); + if (in->existsAttribute("Attenuation")) // might not exist in older files + LightData.Attenuation = in->getAttributeAsVector3d("Attenuation"); + if (in->existsAttribute("OuterCone")) // might not exist in older files + LightData.OuterCone = in->getAttributeAsFloat("OuterCone"); + if (in->existsAttribute("InnerCone")) // might not exist in older files + LightData.InnerCone = in->getAttributeAsFloat("InnerCone"); + if (in->existsAttribute("Falloff")) // might not exist in older files + LightData.Falloff = in->getAttributeAsFloat("Falloff"); + LightData.Radius = in->getAttributeAsFloat("Radius"); + LightData.CastShadows = in->getAttributeAsBool("CastShadows"); + LightData.Type = (video::E_LIGHT_TYPE)in->getAttributeAsEnumeration("LightType", video::LightTypeNames); + + ILightSceneNode::deserializeAttributes(in, options); +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CLightSceneNode* nb = new CLightSceneNode(newParent, + newManager, ID, RelativeTranslation, LightData.DiffuseColor, LightData.Radius); + + nb->cloneMembers(this, newManager); + nb->LightData = LightData; + nb->BBox = BBox; + + nb->drop(); + return nb; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CLightSceneNode.h b/src/dep/src/irrlicht/CLightSceneNode.h new file mode 100644 index 0000000..7fa23e1 --- /dev/null +++ b/src/dep/src/irrlicht/CLightSceneNode.h @@ -0,0 +1,69 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __C_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "ILightSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a dynamic light. You can switch the light on and off by +//! making it visible or not, and let it be animated by ordinary scene node animators. +class CLightSceneNode : public ILightSceneNode +{ +public: + + //! constructor + CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, video::SColorf color, f32 range); + + virtual ~CLightSceneNode() { } + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! set node light data from light info + virtual void setLightData(const video::SLight& light); + + //! \return Returns the light data. + virtual const video::SLight& getLightData() const; + + //! \return Returns the light data. + virtual video::SLight& getLightData(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_LIGHT; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + +private: + + video::SLight LightData; + core::aabbox3d BBox; + void doLightRecalc(); +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CLimitReadFile.cpp b/src/dep/src/irrlicht/CLimitReadFile.cpp new file mode 100644 index 0000000..b82107d --- /dev/null +++ b/src/dep/src/irrlicht/CLimitReadFile.cpp @@ -0,0 +1,117 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLimitReadFile.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + +CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long areaSize, const c8* name) +: Filename(name), AreaSize(areaSize), AreaStart(0), AreaEnd(0), File(alreadyOpenedFile) +{ + #ifdef _DEBUG + setDebugName("CLimitReadFile"); + #endif + + if (File) + File->grab(); + + init(); +} + + +void CLimitReadFile::init() +{ + if (!File) + return; + + AreaStart = File->getPos(); + AreaEnd = AreaStart + AreaSize; +} + + + +CLimitReadFile::~CLimitReadFile() +{ + if (File) + File->drop(); +} + + + +//! returns how much was read +s32 CLimitReadFile::read(void* buffer, u32 sizeToRead) +{ + const long pos = File->getPos(); + + if (pos >= AreaEnd) + return 0; + + if (pos + (long)sizeToRead >= AreaEnd) + sizeToRead = AreaEnd - pos; + + return File->read(buffer, sizeToRead); +} + + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CLimitReadFile::seek(long finalPos, bool relativeMovement) +{ + const long pos = File->getPos(); + + if (relativeMovement) + { + if (pos + finalPos > AreaEnd) + finalPos = AreaEnd - pos; + } + else + { + finalPos += AreaStart; + if (finalPos > AreaEnd) + return false; + } + + return File->seek(finalPos, relativeMovement); +} + + +//! returns size of file +long CLimitReadFile::getSize() const +{ + return AreaSize; +} + + + +//! returns where in the file we are. +long CLimitReadFile::getPos() const +{ + return File->getPos() - AreaStart; +} + + + +//! returns name of file +const c8* CLimitReadFile::getFileName() const +{ + return Filename.c_str(); +} + + +IReadFile* createLimitReadFile(const c8* fileName, IReadFile* alreadyOpenedFile, long areaSize) +{ + return new CLimitReadFile(alreadyOpenedFile, areaSize, fileName); +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CLimitReadFile.h b/src/dep/src/irrlicht/CLimitReadFile.h new file mode 100644 index 0000000..947e6d7 --- /dev/null +++ b/src/dep/src/irrlicht/CLimitReadFile.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LIMIT_READ_FILE_H_INCLUDED__ +#define __C_LIMIT_READ_FILE_H_INCLUDED__ + +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ + class CUnicodeConverter; + +namespace io +{ + + /*! this is a read file, which is limited to some boundaries, + so that it may only start from a certain file position + and may only read until a certain file position. + This can be useful, for example for reading uncompressed files + in an archive (zip). + !*/ + class CLimitReadFile : public IReadFile + { + public: + + CLimitReadFile(IReadFile* alreadyOpenedFile, long areaSize, const c8* name); + + virtual ~CLimitReadFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! changes position in file, returns true if successful + //! if relativeMovement==true, the pos is changed relative to current pos, + //! otherwise from begin of file + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const c8* getFileName() const; + + private: + + void init(); + + core::stringc Filename; + long AreaSize; + long AreaStart; + long AreaEnd; + IReadFile* File; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CLogger.cpp b/src/dep/src/irrlicht/CLogger.cpp new file mode 100644 index 0000000..4d4eb68 --- /dev/null +++ b/src/dep/src/irrlicht/CLogger.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLogger.h" + +namespace irr +{ + + CLogger::CLogger(IEventReceiver* r) + : LogLevel(ELL_INFORMATION), Receiver(r) + { + } + + //! Returns the current set log level. + ELOG_LEVEL CLogger::getLogLevel() const + { + return LogLevel; + } + + //! Sets a new log level. + void CLogger::setLogLevel(ELOG_LEVEL ll) + { + LogLevel = ll; + } + + //! Prints out a text into the log + void CLogger::log(const c8* text, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + if (Receiver) + { + SEvent event; + event.EventType = EET_LOG_TEXT_EVENT; + event.LogEvent.Text = text; + event.LogEvent.Level = ll; + if (Receiver->OnEvent(event)) + return; + } + + os::Printer::print(text); + } + + + //! Prints out a text into the log + void CLogger::log(const c8* text, const c8* hint, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s = text; + s += ": "; + s += hint; + log (s.c_str(), ll); + } + + //! Prints out a text into the log + void CLogger::log(const wchar_t* text, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s = text; + log(s.c_str(), ll); + } + + + //! Prints out a text into the log + void CLogger::log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s1 = text; + core::stringc s2 = hint; + log(s1.c_str(), s2.c_str(), ll); + } + + //! Sets a new event receiver + void CLogger::setReceiver(IEventReceiver* r) + { + Receiver = r; + } + + +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CLogger.h b/src/dep/src/irrlicht/CLogger.h new file mode 100644 index 0000000..fc1c63b --- /dev/null +++ b/src/dep/src/irrlicht/CLogger.h @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LOGGER_H_INCLUDED__ +#define __C_LOGGER_H_INCLUDED__ + +#include "ILogger.h" +#include "os.h" +#include "irrString.h" +#include "IEventReceiver.h" + +namespace irr +{ + +//! Class for logging messages, warnings and errors to stdout +class CLogger : public ILogger +{ +public: + + CLogger(IEventReceiver* r); + + //! Returns the current set log level. + virtual ELOG_LEVEL getLogLevel() const; + + //! Sets a new log level. virtual void setLogLevel(ELOG_LEVEL ll); + virtual void setLogLevel(ELOG_LEVEL ll); + + //! Prints out a text into the log + virtual void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Sets a new event receiver + void setReceiver(IEventReceiver* r); + +private: + + ELOG_LEVEL LogLevel; + IEventReceiver* Receiver; +}; + +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CMD2MeshFileLoader.cpp b/src/dep/src/irrlicht/CMD2MeshFileLoader.cpp new file mode 100644 index 0000000..4e07a34 --- /dev/null +++ b/src/dep/src/irrlicht/CMD2MeshFileLoader.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + +#include "CMD2MeshFileLoader.h" +#include "CAnimatedMeshMD2.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CMD2MeshFileLoader::CMD2MeshFileLoader() +{ +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMD2MeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".md2")!=0; +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CMD2MeshFileLoader::createMesh(io::IReadFile* file) +{ + IAnimatedMesh* msh = new CAnimatedMeshMD2(); + if (msh) + { + if (((CAnimatedMeshMD2*)msh)->loadFile(file)) + return msh; + + msh->drop(); + } + + return 0; +} + +} // end namespace scene +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_MD2_LOADER_ + diff --git a/src/dep/src/irrlicht/CMD2MeshFileLoader.h b/src/dep/src/irrlicht/CMD2MeshFileLoader.h new file mode 100644 index 0000000..4bca556 --- /dev/null +++ b/src/dep/src/irrlicht/CMD2MeshFileLoader.h @@ -0,0 +1,39 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MD2_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MD2_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading MD2 files +class CMD2MeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMD2MeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +}; + +} // end namespace scene +} // end namespace irr + +#endif // __C_MD2_MESH_LOADER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CMD3MeshFileLoader.cpp b/src/dep/src/irrlicht/CMD3MeshFileLoader.cpp new file mode 100644 index 0000000..c408000 --- /dev/null +++ b/src/dep/src/irrlicht/CMD3MeshFileLoader.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + +#include "CMD3MeshFileLoader.h" +#include "CAnimatedMeshMD3.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CMD3MeshFileLoader::CMD3MeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) +{ +} + + +//! destructor +CMD3MeshFileLoader::~CMD3MeshFileLoader() +{ +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMD3MeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".md3") != 0; +} + + +IAnimatedMesh* CMD3MeshFileLoader::createMesh(io::IReadFile* file) +{ + CAnimatedMeshMD3 * mesh = new CAnimatedMeshMD3(); + + if ( mesh->loadModelFile ( 0, file ) ) + return mesh; + + mesh->drop (); + return 0; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD3_LOADER_ + diff --git a/src/dep/src/irrlicht/CMD3MeshFileLoader.h b/src/dep/src/irrlicht/CMD3MeshFileLoader.h new file mode 100644 index 0000000..a32faf4 --- /dev/null +++ b/src/dep/src/irrlicht/CMD3MeshFileLoader.h @@ -0,0 +1,48 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MD3_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MD3_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "IAnimatedMeshMD3.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading md3 files. +class CMD3MeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMD3MeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver); + + //! destructor + virtual ~CMD3MeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CMS3DMeshFileLoader.cpp b/src/dep/src/irrlicht/CMS3DMeshFileLoader.cpp new file mode 100644 index 0000000..c8bb517 --- /dev/null +++ b/src/dep/src/irrlicht/CMS3DMeshFileLoader.cpp @@ -0,0 +1,610 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CMS3DMeshFileLoader.h" +#include "CSkinnedMesh.h" + + + +namespace irr +{ +namespace scene +{ + +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + +// File header +struct MS3DHeader +{ + c8 ID[10]; + s32 Version; +} PACK_STRUCT; + +// Vertex information +struct MS3DVertex +{ + u8 Flags; + f32 Vertex[3]; + s8 BoneID; + u8 RefCount; +} PACK_STRUCT; + +// Triangle information +struct MS3DTriangle +{ + u16 Flags; + u16 VertexIndices[3]; + f32 VertexNormals[3][3]; + f32 S[3], T[3]; + u8 SmoothingGroup; + u8 GroupIndex; +} PACK_STRUCT; + +// Material information +struct MS3DMaterial +{ + s8 Name[32]; + f32 Ambient[4]; + f32 Diffuse[4]; + f32 Specular[4]; + f32 Emissive[4]; + f32 Shininess; // 0.0f - 128.0f + f32 Transparency; // 0.0f - 1.0f + u8 Mode; // 0, 1, 2 is unused now + s8 Texture[128]; + s8 Alphamap[128]; +} PACK_STRUCT; + +// Joint information +struct MS3DJoint +{ + u8 Flags; + s8 Name[32]; + s8 ParentName[32]; + f32 Rotation[3]; + f32 Translation[3]; + u16 NumRotationKeyframes; + u16 NumTranslationKeyframes; +} PACK_STRUCT; + +// Keyframe data +struct MS3DKeyframe +{ + f32 Time; + f32 Parameter[3]; +} PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + +//! Constructor +CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver) +: Driver(driver), AnimatedMesh(0) +{ +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMS3DMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".ms3d")!=0; +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CMS3DMeshFileLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + AnimatedMesh = new CSkinnedMesh(); + + if ( load(file) ) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } + + return AnimatedMesh; +} + + +//! loads an md2 file +bool CMS3DMeshFileLoader::load(io::IReadFile* file) +{ + if (!file) + return false; + + // find file size + const long fileSize = file->getSize(); + + // read whole file + + u8* buffer = new u8[fileSize]; + s32 read = file->read(buffer, fileSize); + if (read != fileSize) + { + delete [] buffer; + os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } + + // read header + + const u8 *pPtr = (u8*)((void*)buffer); + MS3DHeader *pHeader = (MS3DHeader*)pPtr; + pPtr += sizeof(MS3DHeader); + + if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 ) + { + delete [] buffer; + os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + pHeader->Version = os::Byteswap::byteswap(pHeader->Version); +#endif + if ( pHeader->Version < 3 || pHeader->Version > 4 ) + { + delete [] buffer; + os::Printer::log("Only Milkshape3D version 3 and 4 (1.3 to 1.8) is supported. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } + + if ( pHeader->Version == 4 ) + { + os::Printer::log("Milkshape3D version 4 (1.8) is not fully supported. Some features may not be available.", file->getFileName(), ELL_WARNING); + } + + // get pointers to data + + // vertices + u16 numVertices = *(u16*)pPtr; +#ifdef __BIG_ENDIAN__ + numVertices = os::Byteswap::byteswap(numVertices); +#endif + pPtr += sizeof(u16); + MS3DVertex *vertices = (MS3DVertex*)pPtr; + pPtr += sizeof(MS3DVertex) * numVertices; +#ifdef __BIG_ENDIAN__ + for (u16 tmp=0; tmpcreateBuffer(); + + } + + for (i=0; iAmbient[j] = os::Byteswap::byteswap(material->Ambient[j]); + for (u16 j=0; j<4; ++j) + material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]); + for (u16 j=0; j<4; ++j) + material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]); + for (u16 j=0; j<4; ++j) + material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]); + material->Shininess = os::Byteswap::byteswap(material->Shininess); + material->Transparency = os::Byteswap::byteswap(material->Transparency); +#endif + pPtr += sizeof(MS3DMaterial); + + + scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->createBuffer(); + + tmpBuffer->Material.MaterialType = video::EMT_SOLID; + + tmpBuffer->Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor (); + tmpBuffer->Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor (); + tmpBuffer->Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor (); + tmpBuffer->Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor (); + tmpBuffer->Material.Shininess = material->Shininess; + + core::stringc TexturePath=(const c8*)material->Texture; + TexturePath.trim(); + if (TexturePath!="") + { + TexturePath=stripPathFromString(file->getFileName(),true) + stripPathFromString(TexturePath,false); + tmpBuffer->Material.setTexture(0, Driver->getTexture(TexturePath.c_str()) ); + } + + core::stringc AlphamapPath=(const c8*)material->Alphamap; + AlphamapPath.trim(); + if (AlphamapPath!="") + { + AlphamapPath=stripPathFromString(file->getFileName(),true) + stripPathFromString(AlphamapPath,false); + tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath.c_str()) ); + } + + } + + // animation time + f32 framesPerSecond = *(f32*)pPtr; +#ifdef __BIG_ENDIAN__ + framesPerSecond = os::Byteswap::byteswap(framesPerSecond); +#endif + pPtr += sizeof(f32) * 2; // fps and current time + + + if (framesPerSecond==0) + framesPerSecond=1; + + s32 frameCount = *(s32*)pPtr; +#ifdef __BIG_ENDIAN__ + frameCount = os::Byteswap::byteswap(frameCount); +#endif + pPtr += sizeof(s32); + + + u16 jointCount = *(u16*)pPtr; +#ifdef __BIG_ENDIAN__ + jointCount = os::Byteswap::byteswap(jointCount); +#endif + pPtr += sizeof(u16); + + + core::array ParentNames; + + // load joints + for (i=0; iRotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]); + for (j=0; j<3; ++j) + pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]); + pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes); + pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes); +#endif + pPtr += sizeof(MS3DJoint); + + + + ISkinnedMesh::SJoint *jnt = AnimatedMesh->createJoint(); + + /* + jnt.Name = pJoint->Name; + jnt.Index = i; + jnt.Rotation.X = pJoint->Rotation[0]; + jnt.Rotation.Y = pJoint->Rotation[1]; + jnt.Rotation.Z = pJoint->Rotation[2]; + jnt.Translation.X = pJoint->Translation[0]; + jnt.Translation.Y = pJoint->Translation[1]; + jnt.Translation.Z = pJoint->Translation[2]; + jnt.ParentName = pJoint->ParentName; + jnt.Parent = -1; + */ + + jnt->Name = pJoint->Name; + + jnt->LocalMatrix.makeIdentity(); + + + jnt->LocalMatrix.setRotationRadians( + core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) ); + + jnt->LocalMatrix.setTranslation( + core::vector3df(pJoint->Translation[0], pJoint->Translation[1], pJoint->Translation[2]) ); + + + ParentNames.push_back( (c8*)pJoint->ParentName ); + + /*if (pJoint->NumRotationKeyframes || + pJoint->NumTranslationKeyframes) + HasAnimation = true;*/ + + + + + // get rotation keyframes + for (j=0; j < pJoint->NumRotationKeyframes; ++j) + { + MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; +#ifdef __BIG_ENDIAN__ + kf->Time = os::Byteswap::byteswap(kf->Time); + for (u32 l=0; l<3; ++l) + kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); +#endif + pPtr += sizeof(MS3DKeyframe); + + ISkinnedMesh::SRotationKey *k=AnimatedMesh->createRotationKey(jnt); + k->frame = kf->Time * framesPerSecond; + + core::matrix4 tmpMatrix; + + tmpMatrix.setRotationRadians( + core::vector3df(kf->Parameter[0], kf->Parameter[1], kf->Parameter[2]) ); + + tmpMatrix=jnt->LocalMatrix*tmpMatrix; + + k->rotation = core::quaternion(tmpMatrix); + + //fix + //k->rotation = core::vector3df + // (kf->Parameter[0],//+pJoint->Rotation[0]*core::RADTODEG, + // kf->Parameter[1],//+pJoint->Rotation[1]*core::RADTODEG, + // kf->Parameter[2]);//+pJoint->Rotation[2]*core::RADTODEG); + + } + + // get translation keyframes + for (j=0; jNumTranslationKeyframes; ++j) + { + MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; +#ifdef __BIG_ENDIAN__ + kf->Time = os::Byteswap::byteswap(kf->Time); + for (u32 l=0; l<3; ++l) + kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); +#endif + pPtr += sizeof(MS3DKeyframe); + + ISkinnedMesh::SPositionKey *k=AnimatedMesh->createPositionKey(jnt); + k->frame = kf->Time * framesPerSecond; + + k->position = core::vector3df + (kf->Parameter[0]+pJoint->Translation[0], + kf->Parameter[1]+pJoint->Translation[1], + kf->Parameter[2]+pJoint->Translation[2]); + + + } + } + + //find parent of every joint + for (u32 jointnum=0; jointnumgetAllJoints().size(); ++jointnum) + { + for (u32 j2=0; j2getAllJoints().size(); ++j2) + { + if (jointnum != j2 && ParentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name ) + { + AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]); + break; + } + } + } + /*if (Joints[jointnum].Parent == -1) + os::Printer::log("Found joint in model without parent.", ELL_WARNING);*/ + + + // create vertices and indices, attach them to the joints. + video::S3DVertex v; + core::array *Vertices; + core::array Indices; + + for (i=0; igetMeshBuffers()[tmp]->Vertices_Standard; + + for (u16 j = 0; j<3; ++j) + { + v.TCoords.X = triangles[i].S[j]; + v.TCoords.Y = triangles[i].T[j]; + + v.Normal.X = triangles[i].VertexNormals[j][0]; + v.Normal.Y = triangles[i].VertexNormals[j][1]; + v.Normal.Z = triangles[i].VertexNormals[j][2]; + + if(triangles[i].GroupIndex < Groups.size() && Groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size()) + v.Color = AnimatedMesh->getMeshBuffers()[Groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor; + else + v.Color.set(255,255,255,255); + v.Pos.X = vertices[triangles[i].VertexIndices[j]].Vertex[0]; + v.Pos.Y = vertices[triangles[i].VertexIndices[j]].Vertex[1]; + v.Pos.Z = vertices[triangles[i].VertexIndices[j]].Vertex[2]; + + // check if we already have this vertex in our vertex array + s32 index = -1; + for (u32 iV = 0; iV < Vertices->size(); ++iV) + { + if (v == (*Vertices)[iV]) + { + index = (s32)iV; + break; + } + } + if (index == -1) + { + s32 boneid = vertices[triangles[i].VertexIndices[j]].BoneID; + if (boneid>=0 && boneid<(s32)AnimatedMesh->getAllJoints().size()) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->createWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = Groups[triangles[i].GroupIndex].MaterialIdx; + w->strength = 1.0f; + w->vertex_id = Vertices->size(); + //Joints[boneid]->VertexIds.push_back(Vertices.size()); + + + } + + Vertices->push_back(v); + index = Vertices->size() - 1; + } + Indices.push_back(index); + } + } + + //create groups + s32 iIndex = -1; + for (i=0; i= AnimatedMesh->getMeshBuffers().size()) + grp.MaterialIdx = 0; + + core::array& indices = AnimatedMesh->getMeshBuffers()[grp.MaterialIdx]->Indices; + + for (u32 k=0; k < grp.VertexIds.size(); ++k) + for (u32 l=0; l<3; ++l) + indices.push_back(Indices[++iIndex]); + } + + // calculate bounding box +/* + // inverse translate and rotate all vertices for making animation easier + if (HasAnimation) + for (i=0; islashIndex) slashIndex=backSlash; + + if (slashIndex==-1)//no slashes found + if (returnPath) + return core::stringc(); //no path to return + else + return string; + + if (returnPath) + return string.subString(0, slashIndex + 1); + else + return string.subString(slashIndex+1, string.size() - (slashIndex+1)); +} + + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/src/dep/src/irrlicht/CMS3DMeshFileLoader.h b/src/dep/src/irrlicht/CMS3DMeshFileLoader.h new file mode 100644 index 0000000..06a108e --- /dev/null +++ b/src/dep/src/irrlicht/CMS3DMeshFileLoader.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IVideoDriver.h" +#include "CSkinnedMesh.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading Milkshape 3D files +class CMS3DMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMS3DMeshFileLoader(video::IVideoDriver* driver); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + core::stringc stripPathFromString(core::stringc string, bool returnPath); + + bool load(io::IReadFile* file); + video::IVideoDriver* Driver; + CSkinnedMesh* AnimatedMesh; + + struct SGroup + { + core::stringc Name; + core::array VertexIds; + u16 MaterialIdx; + }; + + core::array Groups; + +}; + +} // end namespace scene +} // end namespace irr + +#endif + + diff --git a/src/dep/src/irrlicht/CMY3DHelper.h b/src/dep/src/irrlicht/CMY3DHelper.h new file mode 100644 index 0000000..4b9f164 --- /dev/null +++ b/src/dep/src/irrlicht/CMY3DHelper.h @@ -0,0 +1,335 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by ZDimitor. + +//---------------------------------------------------------------------- +// somefuncs.h - part of the My3D Tools +// +// This tool was created by Zhuck Dmitry (ZDimitor). +// Everyone can use it as wants ( i'll be happy if it helps to someone :) ). +//---------------------------------------------------------------------- + +//********************************************************************** +// some useful functions +//********************************************************************** + +#ifndef __C_MY3D_HELPER_H_INCLUDED__ +#define __C_MY3D_HELPER_H_INCLUDED__ + +//-------------------------------------------------------------------------------- +namespace irr +{ +namespace core +{ + +//-----------------RLE stuff----------------------------------------- + +int rle_encode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ); +unsigned long process_comp( + unsigned char *buf, int buf_size, + unsigned char *out_buf, int out_buf_size + ); +void process_uncomp( + unsigned char, unsigned char *out_buf, int out_buf_size + ); +void flush_outbuf( + unsigned char *out_buf, int out_buf_size + ); +unsigned long get_byte ( + unsigned char *ch, + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ); +void put_byte( + unsigned char ch, unsigned char *out_buf, int out_buf_size + ); +//----------------------------------------------------------- +const unsigned long LIMIT = 1; // was #define LIMIT 1 +const unsigned long NON_MATCH = 2; // was: #define NON_MATCH 2 +const unsigned long EOD_FOUND = 3; // was: #define EOD_FOUND 3 +const unsigned long EOD = 0x00454f44; // was: #define EOD 'EOD' +//----------------------------------------------------------- +// number of decoded bytes +int nDecodedBytes=0; +// number of coded bytes +int nCodedBytes=0; +// number of read bytes +int nReadedBytes=0; +// table used to look for sequences of repeating bytes +unsigned char tmpbuf[4]; // we use subscripts 1 - 3 +int tmpbuf_cnt; +// output buffer for non-compressed output data +unsigned char outbuf[128]; +int outbuf_cnt; + + +//----------------------------------------------------------- +int rle_encode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + unsigned long ret_code; + + unsigned char ch; + + nCodedBytes=0; + nReadedBytes=0; + + tmpbuf_cnt = 0; // no. of char's in tmpbuf + outbuf_cnt = 0; // no. of char's in outbuf + while (1) + { + if (get_byte(&ch, in_buf, in_buf_size, + out_buf, out_buf_size) == (int)EOD) // read next byte into ch + break; + + tmpbuf[++tmpbuf_cnt] = (unsigned char) ch; + if (tmpbuf_cnt == 3) + { + // see if all 3 match each other + if ((tmpbuf[1] == tmpbuf[2]) && (tmpbuf[2] == tmpbuf[3])) + { + // they do - add compression + // this will process all bytes in input file until + // a non-match occurs, or 128 bytes are processed, + // or we find eod */ + ret_code = process_comp(in_buf, in_buf_size, out_buf, out_buf_size); + if (ret_code == (int)EOD_FOUND) + break; // stop compressing + if (ret_code == (int)NON_MATCH) + tmpbuf_cnt=1; /* save the char that didn't match */ + else + // we just compressed the max. of 128 bytes + tmpbuf_cnt=0; /* start over for next chunk */ + } + else + { + // we know the first byte doesn't match 2 or more + // others, so just send it out as uncompressed. */ + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + + // see if the last 2 bytes in the buffer match + if (tmpbuf[2] == tmpbuf[3]) + { + // move byte 3 to position 1 and pretend we just + // have 2 bytes -- note that the first byte was + // already sent to output */ + tmpbuf[1]=tmpbuf[3]; + tmpbuf_cnt=2; + } + else + { + // send byte 2 and keep byte 3 - it may match the + // next byte. Move byte 3 to position 1 and set + // count to 1. Note that the first byte was + // already sent to output + process_uncomp(tmpbuf[2], out_buf, out_buf_size); + tmpbuf[1]=tmpbuf[3]; + tmpbuf_cnt=1; + } + } + } + } // end while + flush_outbuf(out_buf, out_buf_size); + + return nCodedBytes; +} + + +//------------------------------------------------------------------ +// This flushes any non-compressed data not yet sent, then it processes +// repeating bytes until > 128, or EOD, or non-match. +// return values: LIMIT, EOD_FOUND, NON_MATCH +// Prior to ANY return, it writes out the 2 byte compressed code. +// If a NON_MATCH was found, this returns with the non-matching char +// residing in tmpbuf[0]. +// Inputs: tmpbuf[0], input file +// Outputs: tmpbuf[0] (sometimes), output file, and return code +//------------------------------------------------------------------ +unsigned long process_comp( + unsigned char *buf, int buf_size, + unsigned char *out_buf, int out_buf_size) +{ + // we start out with 3 repeating bytes + register int len = 3; + + unsigned char ch; + + // we're starting a repeating chunk - end the non-repeaters + flush_outbuf(out_buf, out_buf_size); + + while (get_byte(&ch, buf, buf_size, out_buf, out_buf_size) != (int)EOD) + { + if (ch != tmpbuf[1]) + { + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + /* save the non-matching character just read */ + tmpbuf[1]=(unsigned char) ch; + return NON_MATCH; + } + /* we know the new byte is part of the repeating seq */ + len++; + if (len == 128) + { + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + return LIMIT; + } + } // end while + + // if flow comes here, we just read an EOD + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + return EOD_FOUND; +} + + +//---------------------------------------------------------------- +// This adds 1 non-repeating byte to outbuf. If outbuf becomes full +// with 128 bytes, it flushes outbuf. +// There are no return codes and no bytes are read from the input. +//---------------------------------------------------------------- +void process_uncomp( + unsigned char char1, unsigned char *out_buf, int out_buf_size + ) +{ + outbuf[outbuf_cnt++] = char1; + if (outbuf_cnt == 128) + flush_outbuf(out_buf, out_buf_size); +} +//----------------------------------------------------------- +// This flushes any non-compressed data not yet sent. +// On exit, outbuf_cnt will equal zero. +//----------------------------------------------------------- +void flush_outbuf(unsigned char *out_buf, int out_buf_size) +{ + register int pos=0; + + if(!outbuf_cnt) + return; // nothing to do */ + + // send no. of unencoded bytes to be sent + put_byte((unsigned char)(outbuf_cnt - 1), out_buf, out_buf_size); + + for ( ; outbuf_cnt; outbuf_cnt--) + put_byte((unsigned char)outbuf[pos++], out_buf, out_buf_size); +} +//--------------------------------------------------- +void put_byte(unsigned char ch, unsigned char *out_buf, int out_buf_size) +{ + if (nCodedBytes<=(out_buf_size-1)) + { out_buf[nCodedBytes++]=ch; + out_buf[nCodedBytes]=0; + } +} +//--------------------------------------------------- +// This reads the next byte into ch. It returns EOD +// at end-of-data +//--------------------------------------------------- +unsigned long get_byte( + unsigned char *ch, + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + if (nReadedBytes>=in_buf_size) + { + // there are either 0, 1, or 2 char's to write before we quit + if (tmpbuf_cnt == 1) + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + else + { + if (tmpbuf_cnt == 2) + { + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + process_uncomp(tmpbuf[2], out_buf, out_buf_size); + } + } + nReadedBytes =0; + + return EOD; + } + + (*ch) = (unsigned char)in_buf[nReadedBytes++]; + + return 0; +} +//----------------------------------------------------------- +int rle_decode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + nDecodedBytes=0; + nReadedBytes=0; + + int ch, i; + while (1) + { + + if (nReadedBytes>=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + if (ch > 127) + { + i = ch - 127; // i is the number of repetitions + // get the byte to be repeated + if (nReadedBytes>=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + // uncompress a chunk + for ( ; i ; i--) + { + if (nDecodedBytes=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + if (nDecodedBytesgrab(); + + if (FileSystem) + FileSystem->grab(); +} + + + +CMY3DMeshFileLoader::~CMY3DMeshFileLoader() +{ + if (Mesh) + Mesh->drop(); + + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + + +bool CMY3DMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".my3d") != 0; +} + + +IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file) +{ + MaterialEntry.clear(); + MeshBufferEntry.clear(); + ChildNodes.clear(); + + core::stringc file_name = file->getFileName(); + + // working directory (from which we load the scene) + core::stringc filepath = FileSystem->getFileDir(file_name); + filepath.append("/"); + + core::stringc msg=""; + + // read file into memory + SMyFileHeader fileHeader; + file->read(&fileHeader, sizeof(SMyFileHeader)); + + if (fileHeader.MyId!=MY_ID || fileHeader.Ver!=MY_VER) + { + os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR); + return 0; + } + + u16 id; + + file->read(&id, sizeof(id)); + + if (id!=MY_SCENE_HEADER_ID) + { + os::Printer::log("Cannot find MY_SCENE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMySceneHeader sceneHeader; + file->read(&sceneHeader, sizeof(SMySceneHeader)); + + SceneBackgrColor = video::SColor( + sceneHeader.BackgrColor.R, sceneHeader.BackgrColor.G, + sceneHeader.BackgrColor.B, sceneHeader.BackgrColor.A); + + SceneAmbientColor = video::SColor( + sceneHeader.AmbientColor.R, sceneHeader.AmbientColor.G, + sceneHeader.AmbientColor.B, sceneHeader.AmbientColor.A); + + file->read(&id, sizeof(id)); + + if (id!=MY_MAT_LIST_ID) + { + os::Printer::log("Can not find MY_MAT_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + core::stringc texturePath = + SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH); + + file->read(&id, sizeof(id)); + + s32 texCount=0, matCount=0; + c8 name[256]; + for (s32 m=0; mread(&materialHeader, sizeof(SMyMaterialHeader)); + + SMyMaterialEntry me; + me.Header = materialHeader; + + // read next identificator + file->read(&id, sizeof(id)); + + bool GetLightMap=false, GetMainMap=false; + static int LightMapIndex=0; + + for (int t=0; tread(name, 256); + else + { + file->read(&id, sizeof(id)); + if (id!=MY_TEXDATA_HEADER_ID) + { + os::Printer::log("Can not find MY_TEXDATA_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMyTexDataHeader texDataHeader; + + file->read(&texDataHeader, sizeof(SMyTexDataHeader)); + + strcpy(texDataHeader.Name, name); + + char LightMapName[255]; + sprintf(LightMapName,"My3D.Lightmap.%d",++LightMapIndex); + + core::stringc pixFormatStr; + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_24) + pixFormatStr = "24bit,"; + else + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_16) + pixFormatStr = "16bit,"; + else + { + msg="Unknown format of image data ("; + msg.append(LightMapName); + msg.append("), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + if (texDataHeader.ComprMode != MY_TEXDATA_COMPR_NONE_ID && + texDataHeader.ComprMode != MY_TEXDATA_COMPR_RLE_ID && + texDataHeader.ComprMode != MY_TEXDATA_COMPR_SIMPLE_ID ) + { + os::Printer::log("Unknown method of compression image data, loading failed!", ELL_ERROR); + return 0; + } + + u32 num_pixels = texDataHeader.Width*texDataHeader.Height; + + void* data = 0; + + if (texDataHeader.ComprMode==MY_TEXDATA_COMPR_NONE_ID) + { + // none compressed image data + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_24) + { + data = (void*) new SMyPixelColor24[num_pixels]; + file->read(data, sizeof(SMyPixelColor24)*num_pixels); + } + else + { + data = (void*) new SMyPixelColor16[num_pixels]; + file->read(data, sizeof(SMyPixelColor16)*num_pixels); + } + } + else + if (texDataHeader.ComprMode==MY_TEXDATA_COMPR_RLE_ID) + { + // read RLE header identificator + file->read(&id, sizeof(id)); + if (id!=MY_TEXDATA_RLE_HEADER_ID) + { + os::Printer::log("Can not find MY_TEXDATA_RLE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + // read RLE header + SMyRLEHeader rleHeader; + file->read(&rleHeader, sizeof(SMyRLEHeader)); + + //allocate memory for input and output buffers + void *input_buffer = (void*) new unsigned char[rleHeader.nEncodedBytes]; + void *output_buffer = (void*) new unsigned char[rleHeader.nDecodedBytes]; + + // read encoded data + file->read(input_buffer, rleHeader.nEncodedBytes); + + // decode data + data = 0;//(void*) new unsigned char[rleHeader.nDecodedBytes]; + s32 decodedBytes = core::rle_decode( + (unsigned char*)input_buffer, rleHeader.nEncodedBytes, + (unsigned char*)output_buffer, rleHeader.nDecodedBytes); + + if (decodedBytes!=(s32)rleHeader.nDecodedBytes) + { + os::Printer::log("Error extracting data from RLE compression, loading failed!", ELL_ERROR); + return 0; + } + + // free input buffer + delete [] (unsigned char*)input_buffer; + + // here decoded data + data = output_buffer; + } + else if (texDataHeader.ComprMode==MY_TEXDATA_COMPR_SIMPLE_ID) + { + // simple compressed image data + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_24) + data = (void*) new SMyPixelColor24[num_pixels]; + else + data = (void*) new SMyPixelColor16[num_pixels]; + + u32 nReadedPixels=0, nToRead=0; + while (true) + { + file->read(&nToRead, sizeof(nToRead)); + + if ((nReadedPixels+nToRead) > num_pixels) + break; + + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_24) + { + SMyPixelColor24 col24; + file->read(&col24, sizeof(SMyPixelColor24)); + for (u32 p=0; pread(&col16, sizeof(SMyPixelColor16)); + for (u32 p=0; p= num_pixels) + break; + } + + if (nReadedPixels != num_pixels) + { + os::Printer::log("Image data seems to be corrupted, loading failed!", ELL_ERROR); + return 0; + } + } + + //! Creates a software image from a byte array. + video::IImage* light_img = 0; + + if (texDataHeader.PixelFormat == MY_PIXEL_FORMAT_24) + { + // 24 bit lightmap format + light_img = Driver->createImageFromData( + video::ECF_R8G8B8, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + else + { + // 16 bit lightmap format + light_img = Driver->createImageFromData( + video::ECF_A1R5G5B5, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + + const bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + me.Texture2 = Driver->addTexture(LightMapName, light_img); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + light_img->drop(); + GetLightMap = true; + } + + const core::stringc Name = name; + const s32 pos2 = Name.findLast('.'); + const core::stringc LightingMapStr = "LightingMap"; + const u32 ls = LightingMapStr.size(); + const bool isSubString = (LightingMapStr == Name.subString(core::max_(0u, (pos2 - ls)), ls)); + if ((isSubString || (Name[pos2-1]=='m' && + Name[pos2-2]=='l' && Name[pos2-3]=='_')) && + !GetLightMap) + { + const bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append("Lightmaps/"); + me.Texture2FileName.append(Name); + + if (Name.size()) + me.Texture2 = Driver->getTexture(me.Texture2FileName.c_str()); + + me.MaterialType = video::EMT_LIGHTMAP_M2; + GetLightMap = true; + + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + } + else + if (!GetLightMap&&GetMainMap) + { + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append(Name); + + if (Name.size()) + me.Texture2 = Driver->getTexture(me.Texture2FileName.c_str()); + + me.MaterialType = video::EMT_REFLECTION_2_LAYER; + } + else + if (!GetMainMap && !GetLightMap ) + { + me.Texture1FileName = filepath; + me.Texture1FileName.append(Name); + if (Name.size()) + { + me.Texture1 = Driver->getTexture(me.Texture1FileName.c_str()); + texCount++; + } + + GetMainMap = true; + me.MaterialType = video::EMT_SOLID; + } + else + if (GetLightMap) + { + me.MaterialType = video::EMT_LIGHTMAP_M2; + } + + file->read(&id, sizeof(id)); + } + + // override material types based on their names + if (!strncmp(me.Header.Name, "AlphaChannel-", 13)) + me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else + if (!strncmp(me.Header.Name, "SphereMap-", 10)) + me.MaterialType = video::EMT_SPHERE_MAP; + + MaterialEntry.push_back(me); + } + + // loading meshes + + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + + if (id!=MY_MESH_LIST_ID) + { + os::Printer::log("Can not find MY_MESH_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&id, sizeof(id)); + + for (s32 mesh_id=0; mesh_idread(&meshHeader, sizeof(SMyMeshHeader)); + + core::array Vertex; + core::array Face; + core::array TVertex1, TVertex2; + core::array TFace1, TFace2; + + s32 vertsNum=0; + s32 facesNum=0; + + // vertices + file->read(&id, sizeof(id)); + if (id!=MY_VERTS_ID) + { + os::Printer::log("Can not find MY_VERTS_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&vertsNum, sizeof(vertsNum)); + Vertex.reallocate(vertsNum); + file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum); + Vertex.set_used(vertsNum); + + // faces + file->read(&id, sizeof(id)); + if (id!=MY_FACES_ID) + { + os::Printer::log("Can not find MY_FACES_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&facesNum, sizeof(facesNum)); + Face.reallocate(facesNum); + file->read(Face.pointer(), sizeof(SMyFace)*facesNum); + Face.set_used(facesNum); + + // reading texture channels + for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++) + { + // Max 2 texture channels allowed (but in format .my3d can be more) + s32 tVertsNum=0, tFacesNum=0; + + // reading texture coords + file->read(&id, sizeof(id)); + + if (id!=MY_TVERTS_ID) + { + msg="Can not find MY_TVERTS_ID ("; + msg.append(tex); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tVertsNum, sizeof(tVertsNum)); + + if (tex==0) + { + // 1st texture channel + TVertex1.reallocate(tVertsNum); + file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum); + TVertex1.set_used(tVertsNum); + } + else + if (tex==1) + { + // 2nd texture channel + TVertex2.reallocate(tVertsNum); + file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum); + TVertex2.set_used(tVertsNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum); + } + + // reading texture faces + file->read(&id, sizeof(id)); + + if (id!=MY_TFACES_ID) + { + msg="Can not find MY_TFACES_ID ("; + msg.append(tex); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tFacesNum, sizeof(tFacesNum)); + + if (tex==0) + { + // 1st texture channel + TFace1.reallocate(tFacesNum); + file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum); + TFace1.set_used(tFacesNum); + } + else if (tex==1) + { + // 2nd texture channel + TFace2.reallocate(tFacesNum); + file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum); + TFace2.set_used(tFacesNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum); + } + } + + // trying to find material + + SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex); + + // creating geometry for the mesh + + // trying to find mesh buffer for this material + SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex); + + if (!buffer || + (buffer->Vertices.size()+vertsNum) > Driver->getMaximalPrimitiveCount()) + { + // creating new mesh buffer for this material + buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible + buffer->Material.Wireframe = false; + buffer->Material.Lighting = false; + + if (matEnt) + { + buffer->Material.MaterialType = matEnt->MaterialType; + + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER) + { + buffer->Material.Lighting = true; + buffer->Material.setTexture(1, matEnt->Texture1); + buffer->Material.setTexture(0, matEnt->Texture2); + } + else + { + buffer->Material.setTexture(0, matEnt->Texture1); + buffer->Material.setTexture(1, matEnt->Texture2); + } + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + buffer->Material.BackfaceCulling = true; + buffer->Material.Lighting = true; + } + else + if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP) + { + buffer->Material.Lighting = true; + } + + buffer->Material.AmbientColor = video::SColor( + matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R, + matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B + ); + buffer->Material.DiffuseColor = video::SColor( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B + ); + buffer->Material.EmissiveColor = video::SColor( + matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R, + matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B + ); + buffer->Material.SpecularColor = video::SColor( + matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R, + matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B + ); + } + else + { + buffer->Material.setTexture(0, 0); + buffer->Material.setTexture(1, 0); + + buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255); + buffer->Material.DiffuseColor = video::SColor(255, 255, 255, 255); + buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0); + buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0); + } + + if (matEnt && matEnt->Header.Transparency!=0) + { + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER ) + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER; + buffer->Material.Lighting = true; + buffer->Material.BackfaceCulling = true; + } + else + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + buffer->Material.Lighting = false; + buffer->Material.BackfaceCulling = false; + } + } + else if ( + !buffer->Material.getTexture(1) && + buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL && + buffer->Material.MaterialType != video::EMT_SPHERE_MAP) + { + buffer->Material.MaterialType = video::EMT_SOLID; + buffer->Material.Lighting = true; + } + + MeshBufferEntry.push_back( + SMyMeshBufferEntry(meshHeader.MatIndex, buffer)); + } + + video::S3DVertex2TCoords VertexA, VertexB, VertexC; + video::SColor vert_color; + core::triangle3df face; + + for (int f=0; fMaterial.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA || + buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER)) + { + video::SColor color( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B); + + vert_color = color.getInterpolated(video::SColor(0,0,0,0), + 1-matEnt->Header.Transparency); + } + else + { + vert_color = buffer->Material.DiffuseColor; + } + + VertexA.Color = VertexB.Color = VertexC.Color = vert_color; + + // vertex A + + VertexA.Pos.X = Vertex[Face[f].C].Coord.X; + VertexA.Pos.Y = Vertex[Face[f].C].Coord.Y; + VertexA.Pos.Z = Vertex[Face[f].C].Coord.Z; + + VertexA.Normal.X = Vertex[Face[f].C].Normal.X; + VertexA.Normal.Y = Vertex[Face[f].C].Normal.Y; + VertexA.Normal.Z = Vertex[Face[f].C].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexA.TCoords.X = TVertex1[TFace1[f].C].TCoord.X; + VertexA.TCoords.Y = TVertex1[TFace1[f].C].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X; + VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y; + } + + // vertex B + + VertexB.Pos.X = Vertex[Face[f].B].Coord.X; + VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y; + VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z; + + VertexB.Normal.X = Vertex[Face[f].B].Normal.X; + VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y; + VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexB.TCoords.X = TVertex1[TFace1[f].B].TCoord.X; + VertexB.TCoords.Y = TVertex1[TFace1[f].B].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X; + VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y; + } + + // vertex C + + VertexC.Pos.X = Vertex[Face[f].A].Coord.X; + VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y; + VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z; + + VertexC.Normal.X = Vertex[Face[f].A].Normal.X; + VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y; + VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexC.TCoords.X = TVertex1[TFace1[f].A].TCoord.X; + VertexC.TCoords.Y = TVertex1[TFace1[f].A].TCoord.Y; + } + if (meshHeader.TChannelCnt>1) + { + VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X; + VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y; + } + + // store 3d data in mesh buffer + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + // For materials with alpha channel we duplicate all faces. + // This has be done for proper lighting calculation of the back faces. + // So you must remember this while you creating your models !!!!! + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z); + VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z); + VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + } + } + file->read(&id, sizeof(id)); + } + + // creating mesh + + for (u32 num=0; numaddMeshBuffer(buffer); + + buffer->recalculateBoundingBox(); + buffer->drop(); + } + + Mesh->recalculateBoundingBox(); + + //sprintf(ch, "Loaded: meshes (%d).", MeshBufferEntry.size()); + //os::Printer::log(ch, ELL_INFORMATION); + + if (id != MY_FILE_END_ID) + os::Printer::log("Loading finished, but can not find MY_FILE_END_ID token.", ELL_WARNING); + + SAnimatedMesh* am = new SAnimatedMesh(); + + // you have to add this type in IAnimatedMesh.h + //am->Type = EAMT_MY3D; + + am->addMesh(Mesh); + am->recalculateBoundingBox(); + + Mesh->drop(); + Mesh = 0; + + return am; +} + + +CMY3DMeshFileLoader::SMyMaterialEntry* CMY3DMeshFileLoader::getMaterialEntryByIndex(u32 matInd) +{ + for (u32 m=0; m& CMY3DMeshFileLoader::getChildNodes() +{ + return ChildNodes; +} + + +} // end namespace scnene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MY3D_LOADER_ diff --git a/src/dep/src/irrlicht/CMY3DMeshFileLoader.h b/src/dep/src/irrlicht/CMY3DMeshFileLoader.h new file mode 100644 index 0000000..0291acf --- /dev/null +++ b/src/dep/src/irrlicht/CMY3DMeshFileLoader.h @@ -0,0 +1,114 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by ZDimitor. +// I (Nikolaus Gebhardt) did some few changes to this: +// - replaced logging calls to their os:: counterparts +// - removed some logging calls +// - enabled image dropping of CImage again, because that bug has been fixed now +// - removed setTexture path and replaced it with the directory of the mesh +// - added EAMT_MY3D file type +// - fixed a memory leak when decompressing RLE data. +// - cleaned multi character constant problems with gcc +// - removed octree child scene node generation because irrlicht is now able to draw +// scene nodes with transparent and sold materials in them at the same time. (see changes.txt) +// Thanks a lot to ZDimitor for his work on this and that he gave me +// his permission to add it into Irrlicht. + +//-------------------------------------------------------------------------------- +// This tool created by ZDimitor everyone can use it as wants +//-------------------------------------------------------------------------------- + +#ifndef __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ +#define __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ + + +#ifdef _MSC_VER +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +#endif + + +#include "IMeshLoader.h" +#include "SMesh.h" +#include "SMeshBufferLightMap.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "ISceneManager.h" + +#include "CMY3DStuff.h" + +namespace irr +{ +namespace scene +{ + + +class CMY3DMeshFileLoader : public IMeshLoader +{ +public: + CMY3DMeshFileLoader( + io::IFileSystem* fs, video::IVideoDriver* driver, ISceneManager *scmgr); + virtual ~CMY3DMeshFileLoader(); + + virtual bool isALoadableFileExtension(const c8* fileName) const; + + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + //! getting access to the nodes (with transparent material), creating + //! while loading .my3d file + core::array& getChildNodes(); + +private: + + scene::SMesh* Mesh; + + video::IVideoDriver* Driver; + io::IFileSystem* FileSystem; + ISceneManager *SceneManager; + + video::SColor SceneBackgrColor; + video::SColor SceneAmbientColor; + + struct SMyMaterialEntry + { + SMyMaterialEntry () + : Texture1FileName("null"), Texture2FileName("null"), + Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {} + + SMyMaterialHeader Header; + core::stringc Texture1FileName; + core::stringc Texture2FileName; + video::ITexture *Texture1; + video::ITexture *Texture2; + video::E_MATERIAL_TYPE MaterialType; + }; + + struct SMyMeshBufferEntry + { + SMyMeshBufferEntry() : MaterialIndex(-1), MeshBuffer(0) {} + SMyMeshBufferEntry(s32 mi, SMeshBufferLightMap* mb) + : MaterialIndex(mi), MeshBuffer(mb) {} + + s32 MaterialIndex; + SMeshBufferLightMap* MeshBuffer; + }; + + SMyMaterialEntry* getMaterialEntryByIndex (u32 matInd); + SMeshBufferLightMap* getMeshBufferByMaterialIndex(u32 matInd); + + core::array MaterialEntry; + core::array MeshBufferEntry; + + core::array ChildNodes; +}; + + +} // end namespace scene +} // end namespace irr + + +#endif // __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ diff --git a/src/dep/src/irrlicht/CMY3DStuff.h b/src/dep/src/irrlicht/CMY3DStuff.h new file mode 100644 index 0000000..f562465 --- /dev/null +++ b/src/dep/src/irrlicht/CMY3DStuff.h @@ -0,0 +1,188 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by ZDimitor. + +//---------------------------------------------------------------------- +// my3d-stuff.h - part of the My3D Tools +// +// This tool was created by Zhuck Dmitry (ZDimitor). +// Everyone can use it as wants ( i'll be happy if it helps to someone :) ). +//---------------------------------------------------------------------- + +#ifndef __C_MY_3D_STUFF_H_INCLUDED__ +#define __C_MY_3D_STUFF_H_INCLUDED__ + +#include + +namespace irr +{ +namespace scene +{ + +//********************************************************************** +// MY3D stuff +//********************************************************************** + +const unsigned long MY_ID = 0x4d593344; // was: #define MY_ID 'MY3D' +#define MY_VER 0x0003 + +#define MY_SCENE_HEADER_ID 0x1000 + +#define MY_MAT_LIST_ID 0x2000 +#define MY_MAT_HEADER_ID 0x2100 +#define MY_TEX_FNAME_ID 0x2101 +#define MY_TEXDATA_ID 0x2500 +#define MY_TEXDATA_HEADER_ID 0x2501 +#define MY_TEXDATA_RLE_HEADER_ID 0x2502 + +#define MY_MESH_LIST_ID 0x3000 +#define MY_MESH_HEADER_ID 0x3100 +#define MY_VERTS_ID 0x3101 +#define MY_FACES_ID 0x3102 +#define MY_TVERTS_ID 0x3103 +#define MY_TFACES_ID 0x3104 + +#define MY_FILE_END_ID 0xFFFF + +const unsigned long MY_TEXDATA_COMPR_NONE_ID = 0x4e4f4e45; // was: MY_TEXDATA_COMPR_NONE_ID 'NONE' +const unsigned long MY_TEXDATA_COMPR_SIMPLE_ID = 0x53494d50; // was: #define MY_TEXDATA_COMPR_SIMPLE_ID 'SIMP' +const unsigned long MY_TEXDATA_COMPR_RLE_ID = 0x20524c45; // was: #define MY_TEXDATA_COMPR_RLE_ID ' RLE' + +const unsigned long MY_PIXEL_FORMAT_24 = 0x5f32345f; // was: #define MY_PIXEL_FORMAT_24 '_24_' +const unsigned long MY_PIXEL_FORMAT_16 = 0x5f31365f; // was: #define MY_PIXEL_FORMAT_16 '_16_' +//-------------------------------------------------------------------- +// byte-align structures +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif +//---------------------------------------------------------------------- +struct SMyColor +{ SMyColor () {;} + SMyColor (s32 __R, s32 __G, s32 __B, s32 __A) + : R(__R), G(__G), B(__B), A(__A) {} + s32 R, G, B, A; +} PACK_STRUCT; + +struct SMyVector3 +{ SMyVector3 () {;} + SMyVector3 (f32 __X, f32 __Y, f32 __Z) + : X(__X), Y(__Y), Z(__Z) {} + f32 X, Y, Z; +} PACK_STRUCT; + +struct SMyVector2 +{ SMyVector2 () {;} + SMyVector2(f32 __X, f32 __Y) + : X(__X), Y(__Y) {} + f32 X, Y; +} PACK_STRUCT; + +struct SMyVertex +{ SMyVertex () {;} + SMyVertex (SMyVector3 _Coord, SMyColor _Color, SMyVector3 _Normal) + :Coord(_Coord), Color(_Color), Normal(_Normal) {;} + SMyVector3 Coord; + SMyColor Color; + SMyVector3 Normal; +} PACK_STRUCT; + +struct SMyTVertex +{ SMyTVertex () {;} + SMyTVertex (SMyVector2 _TCoord) + : TCoord(_TCoord) {;} + SMyVector2 TCoord; +} PACK_STRUCT; + +struct SMyFace +{ SMyFace() {;} + SMyFace(u32 __A, u32 __B, u32 __C) + : A(__A), B(__B), C(__C) {} + u32 A, B, C; +} PACK_STRUCT; + +// file header (6 bytes) +struct SMyFileHeader +{ u32 MyId; // MY3D + u16 Ver; // Version +} PACK_STRUCT; + +// scene header +struct SMySceneHeader +{ SMyColor BackgrColor; // background color + SMyColor AmbientColor; // ambient color + s32 MaterialCount; // material count + s32 MeshCount; // mesh count +} PACK_STRUCT; + +// material header +struct SMyMaterialHeader +{ c8 Name[256]; // material name + u32 Index; + SMyColor AmbientColor; + SMyColor DiffuseColor; + SMyColor EmissiveColor; + SMyColor SpecularColor; + f32 Shininess; + f32 Transparency; + s32 TextureCount; // texture count +} PACK_STRUCT; + +// mesh header +struct SMyMeshHeader +{ c8 Name[256]; // material name + u32 MatIndex; // index of the mesh material + u32 TChannelCnt; // mesh mapping channels count +} PACK_STRUCT; + +// texture data header +struct SMyTexDataHeader +{ c8 Name[256]; // texture name + u32 ComprMode; //compression mode + u32 PixelFormat; + u32 Width; // image width + u32 Height; // image height +} PACK_STRUCT; + +// pixel color 24bit (R8G8B8) +struct SMyPixelColor24 +{ SMyPixelColor24() {;} + SMyPixelColor24(u8 __r, u8 __g, u8 __b) + : r(__r), g(__g), b(__b) {} + u8 r, g, b; +} PACK_STRUCT; + +// pixel color 16bit (A1R5G5B5) +struct SMyPixelColor16 +{ SMyPixelColor16() {;} + SMyPixelColor16(s16 _argb): argb(_argb) {;} + SMyPixelColor16(u8 r, u8 g, u8 b) + { argb = ((r&0x1F)<<10) | ((g&0x1F)<<5) | (b&0x1F); + } + s16 argb; +} PACK_STRUCT; + +// RLE Header +struct SMyRLEHeader +{ SMyRLEHeader() {} + u32 nEncodedBytes; + u32 nDecodedBytes; +} PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CMemoryReadFile.cpp b/src/dep/src/irrlicht/CMemoryReadFile.cpp new file mode 100644 index 0000000..2679b92 --- /dev/null +++ b/src/dep/src/irrlicht/CMemoryReadFile.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMemoryReadFile.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + +CMemoryReadFile::CMemoryReadFile(void* memory, long len, const c8* fileName, bool d) +: Buffer(memory), Len(len), Pos(0), deleteMemoryWhenDropped(d) +{ + #ifdef _DEBUG + setDebugName("CReadFile"); + #endif + + Filename = fileName; +} + + + +CMemoryReadFile::~CMemoryReadFile() +{ + if (deleteMemoryWhenDropped) + delete [] (c8*)Buffer; +} + + + +//! returns how much was read +s32 CMemoryReadFile::read(void* buffer, u32 sizeToRead) +{ + s32 amount = static_cast(sizeToRead); + if (Pos + amount > Len) + amount -= Pos + amount - Len; + + if (amount <= 0) + return 0; + + c8* p = (c8*)Buffer; + memcpy(buffer, p + Pos, amount); + + Pos += amount; + + return amount; +} + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CMemoryReadFile::seek(long finalPos, bool relativeMovement) +{ + if (relativeMovement) + { + if (Pos + finalPos > Len) + return false; + + Pos += finalPos; + } + else + { + if (finalPos > Len) + return false; + + Pos = finalPos; + } + + return true; +} + + + +//! returns size of file +long CMemoryReadFile::getSize() const +{ + return Len; +} + + + +//! returns where in the file we are. +long CMemoryReadFile::getPos() const +{ + return Pos; +} + + + +//! returns name of file +const c8* CMemoryReadFile::getFileName() const +{ + return Filename.c_str(); +} + + + +IReadFile* createMemoryReadFile(void* memory, long size, const c8* fileName, bool deleteMemoryWhenDropped) +{ + CMemoryReadFile* file = new CMemoryReadFile(memory, size, fileName, deleteMemoryWhenDropped); + return file; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CMemoryReadFile.h b/src/dep/src/irrlicht/CMemoryReadFile.h new file mode 100644 index 0000000..7c4503d --- /dev/null +++ b/src/dep/src/irrlicht/CMemoryReadFile.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MEMORY_READ_FILE_H_INCLUDED__ +#define __C_MEMORY_READ_FILE_H_INCLUDED__ + +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for reading from memory. + */ + class CMemoryReadFile : public IReadFile + { + public: + + CMemoryReadFile(void* memory, long len, const c8* fileName, bool deleteMemoryWhenDropped); + + virtual ~CMemoryReadFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! changes position in file, returns true if successful + //! if relativeMovement==true, the pos is changed relative to current pos, + //! otherwise from begin of file + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const c8* getFileName() const; + + private: + + core::stringc Filename; + void *Buffer; + long Len; + long Pos; + bool deleteMemoryWhenDropped; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CMeshCache.cpp b/src/dep/src/irrlicht/CMeshCache.cpp new file mode 100644 index 0000000..306cb2d --- /dev/null +++ b/src/dep/src/irrlicht/CMeshCache.cpp @@ -0,0 +1,239 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + + +CMeshCache::~CMeshCache() +{ + clear(); +} + + +//! adds a mesh to the list +void CMeshCache::addMesh(const c8* filename, IAnimatedMesh* mesh) +{ + mesh->grab(); + + MeshEntry e; + e.Mesh = mesh; + e.Name = filename; + e.Name.make_lower(); + + Meshes.push_back(e); +} + + +//! Removes a mesh from the cache. +void CMeshCache::removeMesh(const IAnimatedMesh* const mesh) +{ + if ( !mesh ) + return; + for (u32 i=0; idrop(); + Meshes.erase(i); + return; + } + } +} + + +//! Removes a mesh from the cache. +void CMeshCache::removeMesh(const IMesh* const mesh) +{ + if ( !mesh ) + return; + for (u32 i=0; igetMesh(0) == mesh) + { + Meshes[i].Mesh->drop(); + Meshes.erase(i); + return; + } + } +} + + +//! Returns amount of loaded meshes +u32 CMeshCache::getMeshCount() const +{ + return Meshes.size(); +} + + +//! Returns current number of the mesh +s32 CMeshCache::getMeshIndex(const IAnimatedMesh* const mesh) const +{ + for (u32 i=0; igetMesh(0) == mesh) + return (s32)i; + } + + return -1; +} + + +//! Returns a mesh based on its index number +IAnimatedMesh* CMeshCache::getMeshByIndex(u32 number) +{ + if (number >= Meshes.size()) + return 0; + + return Meshes[number].Mesh; +} + + +//! Returns a mesh based on its file name. +IAnimatedMesh* CMeshCache::getMeshByFilename(const c8* filename) +{ + MeshEntry e; + e.Name = filename; + e.Name.make_lower(); + s32 id = Meshes.binary_search(e); + return (id != -1) ? Meshes[id].Mesh : 0; +} + + +//! Returns name of a mesh based on its index number +const c8* CMeshCache::getMeshFilename(u32 number) const +{ + if (number >= Meshes.size()) + return 0; + + return Meshes[number].Name.c_str(); +} + + + +//! Returns the filename of a loaded mesh, if there is any. Returns 0 if there is none. +const c8* CMeshCache::getMeshFilename(const IAnimatedMesh* const mesh) const +{ + for (u32 i=0; igetMesh(0) == mesh) + return Meshes[i].Name.c_str(); + } + + return 0; +} + + + +//! Renames a loaded mesh, if possible. +bool CMeshCache::setMeshFilename(u32 index, const c8* filename) +{ + if (index >= Meshes.size()) + return false; + + Meshes[index].Name = filename; + Meshes.sort(); + return true; +} + + +//! Renames a loaded mesh, if possible. +bool CMeshCache::setMeshFilename(const IAnimatedMesh* const mesh, const c8* filename) +{ + for (u32 i=0; igetMesh(0) == mesh) + { + Meshes[i].Name = filename; + Meshes.sort(); + return true; + } + } + + return false; +} + + +//! returns if a mesh already was loaded +bool CMeshCache::isMeshLoaded(const c8* filename) +{ + return getMeshByFilename(filename) != 0; +} + + +//! Clears the whole mesh cache, removing all meshes. +void CMeshCache::clear() +{ + for (u32 i=0; idrop(); + + Meshes.clear(); +} + +//! Clears all meshes that are held in the mesh cache but not used anywhere else. +void CMeshCache::clearUnusedMeshes() +{ + for (u32 i=0; igetReferenceCount() == 1) + { + Meshes[i].Mesh->drop(); + Meshes.erase(i); + --i; + } + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CMeshCache.h b/src/dep/src/irrlicht/CMeshCache.h new file mode 100644 index 0000000..e73bb05 --- /dev/null +++ b/src/dep/src/irrlicht/CMeshCache.h @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_CACHE_H_INCLUDED__ +#define __C_MESH_CACHE_H_INCLUDED__ + +#include "IMeshCache.h" +#include "irrArray.h" + +namespace irr +{ + +namespace scene +{ + class CMeshCache : public IMeshCache + { + public: + + virtual ~CMeshCache(); + + //! Adds a mesh to the internal list of loaded meshes. + /** Usually, ISceneManager::getMesh() is called to load a mesh from file. + That method searches the list of loaded meshes if a mesh has already been loaded and + returns a pointer to if it is in that list and already in memory. Otherwise it loads + the mesh. With IMeshCache::addMesh(), it is possible to pretend that a mesh already + has been loaded. This method can be used for example by mesh loaders who need to + load more than one mesh with one call. They can add additional meshes with this + method to the scene manager. The COLLADA loader for example uses this method. + \param filename: Filename of the mesh. When called ISceneManager::getMesh() with this + parameter, the method will return the mesh parameter given with this method. + \param mesh: Pointer to a mesh which will now be referenced by this name. */ + virtual void addMesh(const c8* filename, IAnimatedMesh* mesh); + + //! Removes a mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be removed from the cache + using this method, freeing a lot of memory. */ + virtual void removeMesh(const IAnimatedMesh* const mesh); + + //! Removes a mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be removed from the cache + using this method, freeing a lot of memory. */ + virtual void removeMesh(const IMesh* const mesh); + + //! Returns amount of loaded meshes in the cache. + /** You can load new meshes into the cache using getMesh() and addMesh(). + If you ever need to access the internal mesh cache, you can do this using + removeMesh(), getMeshNumber(), getMeshByIndex() and getMeshFilename() */ + virtual u32 getMeshCount() const; + + //! Returns current index number of the mesh, and -1 if it is not in the cache. + virtual s32 getMeshIndex(const IAnimatedMesh* const mesh) const; + + //! Returns current index number of the mesh, and -1 if it is not in the cache. + virtual s32 getMeshIndex(const IMesh* const mesh) const; + + //! Returns a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + Note that this number is only valid until a new mesh is loaded or removed * + \return Returns pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByIndex(u32 index); + + //! Returns a mesh based on its file name. + /** \return Returns pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByFilename(const c8* filename); + + //! Returns name of a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + Note that this is only valid until a new mesh is loaded */ + virtual const c8* getMeshFilename(u32 index) const; + + //! Returns the filename of a loaded mesh, if there is any. + /** Returns 0 if there is none. */ + virtual const c8* getMeshFilename(const IAnimatedMesh* const mesh) const; + + //! Returns the filename of a loaded mesh, if there is any. + /* Returns 0 if there is none.*/ + virtual const c8* getMeshFilename(const IMesh* const mesh) const; + + //! Renames a loaded mesh, if possible. + virtual bool setMeshFilename(u32 index, const c8* filename); + + //! Renames a loaded mesh, if possible. + virtual bool setMeshFilename(const IAnimatedMesh* const mesh, const c8* filename); + + //! Renames a loaded mesh, if possible. + virtual bool setMeshFilename(const IMesh* const mesh, const c8* filename); + + //! returns if a mesh already was loaded + virtual bool isMeshLoaded(const c8* filename); + + //! Clears the whole mesh cache, removing all meshes. + virtual void clear(); + + //! Clears all meshes that are held in the mesh cache but not used anywhere else. + virtual void clearUnusedMeshes(); + + protected: + + struct MeshEntry + { + core::stringc Name; + IAnimatedMesh* Mesh; + + bool operator < (const MeshEntry& other) const + { + return (Name < other.Name); + } + }; + + //! loaded meshes + core::array Meshes; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CMeshManipulator.cpp b/src/dep/src/irrlicht/CMeshManipulator.cpp new file mode 100644 index 0000000..497b669 --- /dev/null +++ b/src/dep/src/irrlicht/CMeshManipulator.cpp @@ -0,0 +1,1128 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshManipulator.h" +#include "IMesh.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SMeshBufferLightMap.h" +#include "SMeshBufferTangents.h" +#include "IAnimatedMesh.h" +#include "SAnimatedMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! Recalculates the normals in vertex array. +//! This template function was a member of the CMeshManipulator class, but +//! visual studio 6.0 didn't like it. +template +inline void recalculateNormalsT_Flat(VTXTYPE* v, int vtxcnt, + u16* idx, int idxcnt) +{ + for (int i=0; i p(v[idx[i+0]].Pos, v[idx[i+1]].Pos, v[idx[i+2]].Pos); + v[idx[i+0]].Normal = p.Normal; + v[idx[i+1]].Normal = p.Normal; + v[idx[i+2]].Normal = p.Normal; + } +} + +template +inline void recalculateNormalsT_Smooth(VTXTYPE* v, int vtxcnt, + u16* idx, int idxcnt) +{ + s32 i; + + for ( i = 0; i!= vtxcnt; ++i ) + { + v[i].Normal.set ( 0.f, 0.f, 0.f ); + } + + for ( i=0; i p(v[idx[i+0]].Pos, v[idx[i+1]].Pos, v[idx[i+2]].Pos); + v[idx[i+0]].Normal += p.Normal; + v[idx[i+1]].Normal += p.Normal; + v[idx[i+2]].Normal += p.Normal; + } + + for ( i = 0; i!= vtxcnt; ++i ) + { + v[i].Normal.normalize (); + } +} + +//! Recalculates normals in a vertex array. +//! This template function was a member of the CMeshManipulator class, but +//! visual studio 6.0 didn't like it. +template +inline void makePlanarMappingT(VERTEXTYPE *v, + int vtxcnt, + u16* idx, int idxcnt, f32 resolution) +{ + for (int i=0; i p(v[idx[i+0]].Pos, v[idx[i+1]].Pos, v[idx[i+2]].Pos); + p.Normal.X = fabsf(p.Normal.X); + p.Normal.Y = fabsf(p.Normal.Y); + p.Normal.Z = fabsf(p.Normal.Z); + // calculate planar mapping worldspace coordinates + + if (p.Normal.X > p.Normal.Y && p.Normal.X > p.Normal.Z) + { + for (s32 o=0; o<3; ++o) + { + v[idx[i+o]].TCoords.X = v[idx[i+o]].Pos.Y * resolution; + v[idx[i+o]].TCoords.Y = v[idx[i+o]].Pos.Z * resolution; + } + } + else + if (p.Normal.Y > p.Normal.X && p.Normal.Y > p.Normal.Z) + { + for (s32 o=0; o<3; ++o) + { + v[idx[i+o]].TCoords.X = v[idx[i+o]].Pos.X * resolution; + v[idx[i+o]].TCoords.Y = v[idx[i+o]].Pos.Z * resolution; + } + } + else + { + for (s32 o=0; o<3; ++o) + { + v[idx[i+o]].TCoords.X = v[idx[i+o]].Pos.X * resolution; + v[idx[i+o]].TCoords.Y = v[idx[i+o]].Pos.Y * resolution; + } + } + } +} + + +//! Flips the direction of surfaces. Changes backfacing triangles to frontfacing +//! triangles and vice versa. +//! \param mesh: Mesh on which the operation is performed. +void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for (u32 b=0; bgetMeshBuffer(b); + const u32 idxcnt = buffer->getIndexCount(); + u16* idx = buffer->getIndices(); + s32 tmp; + + for (u32 i=0; igetMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b); + void* v = buffer->getVertices(); + u32 vtxcnt = buffer->getVertexCount(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + for ( i=0; igetMeshBufferCount(); + for (u32 b=0; bgetMeshBuffer(b); + void* v = buffer->getVertices(); + const u32 vtxcnt = buffer->getVertexCount(); + u32 i; + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + for ( i=0; igetVertexCount(); + u32 idxcnt = buffer->getIndexCount(); + u16* idx = buffer->getIndices(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = (video::S3DVertex*)buffer->getVertices(); + + if (!smooth) + recalculateNormalsT_Flat(v, vtxcnt, idx, idxcnt); + else + recalculateNormalsT_Smooth(v, vtxcnt, idx, idxcnt); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = (video::S3DVertex2TCoords*)buffer->getVertices(); + + if (!smooth) + recalculateNormalsT_Flat(v, vtxcnt, idx, idxcnt); + else + recalculateNormalsT_Smooth(v, vtxcnt, idx, idxcnt); + } + break; + case video::EVT_TANGENTS: + { + // TODO: recalculate tangent and binormal + video::S3DVertexTangents* v = (video::S3DVertexTangents*)buffer->getVertices(); + if (!smooth) + recalculateNormalsT_Flat(v, vtxcnt, idx, idxcnt); + else + recalculateNormalsT_Smooth(v, vtxcnt, idx, idxcnt); + } + } +} + + + +//! Recalculates all normals of the mesh. +//! \param mesh: Mesh on which the operation is performed. +void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b), smooth); +} + + +//! Applies a transformation +/** \param mesh: Mesh on which the operation is performed. + \param m: matrix. */ +void CMeshManipulator::transformMesh(scene::IMesh* mesh, const core::matrix4& m) const +{ + if (!mesh) + return; + + core::aabbox3df meshbox; + core::aabbox3df bufferbox; + u32 i; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b); + + const u32 vtxcnt = buffer->getVertexCount(); + const u32 vtxPitch = video::getVertexPitchFromType(buffer->getVertexType()); + + video::S3DVertex* v = (video::S3DVertex*) buffer->getVertices(); + + for ( i=0; i < 1; ++i) + { + m.transformVect ( v->Pos); + m.rotateVect ( v->Normal ); + v->Normal.normalize(); + + bufferbox.reset( v->Pos); + v = (video::S3DVertex*) ((u8*) v + vtxPitch); + } + + for ( ;i < vtxcnt; ++i) + { + m.transformVect ( v->Pos); + m.rotateVect ( v->Normal ); + v->Normal.normalize(); + + bufferbox.addInternalPoint( v->Pos); + v = (video::S3DVertex*) ((u8*) v + vtxPitch); + } + + buffer->setBoundingBox(bufferbox); + + if (b == 0) + meshbox.reset(buffer->getBoundingBox()); + else + meshbox.addInternalBox(buffer->getBoundingBox()); + } + + mesh->setBoundingBox( meshbox ); +} + + +//! Scales the whole mesh. +//! \param mesh: Mesh on which the operation is performed. +void CMeshManipulator::scaleMesh(scene::IMesh* mesh, const core::vector3df& scale) const +{ + if (!mesh) + return; + + core::aabbox3df meshbox; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b); + void* v = buffer->getVertices(); + const u32 vtxcnt = buffer->getVertexCount(); + core::aabbox3df bufferbox; + u32 i; + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + if (vtxcnt != 0) + bufferbox.reset(((video::S3DVertex*)v)[0].Pos * scale); + + for ( i=0; isetBoundingBox( bufferbox ); + + if (b == 0) + meshbox.reset(buffer->getBoundingBox()); + else + meshbox.addInternalBox(buffer->getBoundingBox()); + } + + mesh->setBoundingBox( meshbox ); +} + + + +//! Clones a static IMesh into a modifyable SMesh. +SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const +{ + if (!mesh) + return 0; + + SMesh* clone = new SMesh(); + + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for ( u32 b=0; bgetMeshBuffer(b)->getVertexCount(); + const u32 idxCnt = mesh->getMeshBuffer(b)->getIndexCount(); + const u16* idx = mesh->getMeshBuffer(b)->getIndices(); + u32 i; + + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(vtxCnt); + for (i=0; iVertices.push_back(v[i]); + + buffer->Indices.reallocate(idxCnt); + for (i=0; iIndices.push_back(idx[i]); + + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(vtxCnt); + for (i=0; iVertices.push_back(v[i]); + + buffer->Indices.reallocate(idxCnt); + for (i=0; iIndices.push_back(idx[i]); + + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(vtxCnt); + for (i=0; iVertices.push_back(v[i]); + + buffer->Indices.reallocate(idxCnt); + for (i=0; iIndices.push_back(idx[i]); + + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + }// end switch + + }// end for all mesh buffers + + clone->BoundingBox = mesh->getBoundingBox(); + return clone; +} + + + +//! Creates a planar texture mapping on the mesh +//! \param mesh: Mesh on which the operation is performed. +//! \param resolution: resolution of the planar mapping. This is the value +//! specifying which is the releation between world space and +//! texture coordinate space. +void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.01f) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b); + u32 vtxcnt = buffer->getVertexCount(); + u32 idxcnt = buffer->getIndexCount(); + u16* idx = buffer->getIndices(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = (video::S3DVertex*)buffer->getVertices(); + makePlanarMappingT(v, vtxcnt, idx, idxcnt, resolution); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = (video::S3DVertex2TCoords*)buffer->getVertices(); + makePlanarMappingT(v, vtxcnt, idx, idxcnt, resolution); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* v = (video::S3DVertexTangents*)buffer->getVertices(); + makePlanarMappingT(v, vtxcnt, idx, idxcnt, resolution); + } + break; + } + } +} + + + +//! Creates a copy of the mesh, which will only consist of unique primitives +IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const +{ + if (!mesh) + return 0; + + SMesh* clone = new SMesh(); + + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for ( u32 b=0; bgetMeshBuffer(b)->getIndexCount(); + const u16* idx = mesh->getMeshBuffer(b)->getIndices(); + + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + }// end switch + + }// end for all mesh buffers + + clone->BoundingBox = mesh->getBoundingBox(); + return clone; +} + +//! Creates a copy of a mesh, which will have identical vertices welded together +IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const +{ + SMesh* clone = new SMesh(); + clone->BoundingBox = mesh->getBoundingBox(); + + core::array redirects; + + for (u32 b=0; bgetMeshBufferCount(); ++b) + { + // reset redirect list + redirects.set_used(mesh->getMeshBuffer(b)->getVertexCount()); + + u16* indices = 0; + u32 indexCount = 0; + core::array* outIdx = 0; + + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->BoundingBox = mesh->getMeshBuffer(b)->getBoundingBox(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + u32 vertexCount = mesh->getMeshBuffer(b)->getVertexCount(); + + indices = mesh->getMeshBuffer(b)->getIndices(); + indexCount = mesh->getMeshBuffer(b)->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + + break; + } + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->BoundingBox = mesh->getMeshBuffer(b)->getBoundingBox(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + u32 vertexCount = mesh->getMeshBuffer(b)->getVertexCount(); + + indices = mesh->getMeshBuffer(b)->getIndices(); + indexCount = mesh->getMeshBuffer(b)->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + v[i].TCoords2.equals( v[j].TCoords2 ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + break; + } + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->BoundingBox = mesh->getMeshBuffer(b)->getBoundingBox(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + u32 vertexCount = mesh->getMeshBuffer(b)->getVertexCount(); + + indices = mesh->getMeshBuffer(b)->getIndices(); + indexCount = mesh->getMeshBuffer(b)->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + v[i].Tangent.equals( v[j].Tangent, tolerance ) && + v[i].Binormal.equals( v[j].Binormal, tolerance ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + break; + } + default: + os::Printer::log("Cannot create welded mesh, vertex type unsupported", ELL_ERROR); + break; + } + + // write the buffer's index list + core::array &Indices = *outIdx; + + Indices.set_used(indexCount); + for (u32 i=0; igetMeshBufferCount(); + u32 b; + + for (b=0; bgetMeshBuffer(b)->getIndexCount(); + const u16* idx = mesh->getMeshBuffer(b)->getIndices(); + + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + // copy vertices + + buffer->Vertices.reallocate(idxCnt); + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back( + video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords)); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back(video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords)); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back(v[idx[i]]); + } + break; + } + + // create new indices + + buffer->Indices.set_used(idxCnt); + for (s32 i=0; iIndices[i] = i; + + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->BoundingBox = mesh->getBoundingBox(); + + // now calculate tangents + for (b=0; bgetMeshBuffer(b)->getIndexCount(); + + u16* idx = clone->getMeshBuffer(b)->getIndices(); + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)clone->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; igetMeshBufferCount(); + u32 b; + + for (b=0; bgetMeshBuffer(b)->getIndexCount(); + const u16* idx = mesh->getMeshBuffer(b)->getIndices(); + + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + + // copy vertices + + buffer->Vertices.reallocate(idxCnt); + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back( + video::S3DVertex2TCoords( + v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back(v[idx[i]]); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + for (s32 i=0; iVertices.push_back(video::S3DVertex2TCoords( + v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); + } + break; + } + + // create new indices + + buffer->Indices.set_used(idxCnt); + for (s32 i=0; iIndices[i] = i; + + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->BoundingBox = mesh->getBoundingBox(); + + return clone; +} + + + +void CMeshManipulator::calculateTangents( + core::vector3df& normal, + core::vector3df& tangent, + core::vector3df& binormal, + const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices + const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords +{ + // choose one of them: + //#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers + #define USE_IRR_VERSION + +#ifdef USE_IRR_VERSION + + core::vector3df v1 = vt1 - vt2; + core::vector3df v2 = vt3 - vt1; + normal = v2.crossProduct(v1); + normal.normalize(); + + // binormal + + f32 deltaX1 = tc1.X - tc2.X; + f32 deltaX2 = tc3.X - tc1.X; + binormal = (v1 * deltaX2) - (v2 * deltaX1); + binormal.normalize(); + + // tangent + + f32 deltaY1 = tc1.Y - tc2.Y; + f32 deltaY2 = tc3.Y - tc1.Y; + tangent = (v1 * deltaY2) - (v2 * deltaY1); + tangent.normalize(); + + // adjust + + core::vector3df txb = tangent.crossProduct(binormal); + if (txb.dotProduct(normal) < 0.0f) + { + tangent *= -1.0f; + binormal *= -1.0f; + } + +#endif // USE_IRR_VERSION + +#ifdef USE_NVIDIA_GLH_VERSION + + tangent.set(0,0,0); + binormal.set(0,0,0); + + core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y); + core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y); + + core::vector3df txb = v1.crossProduct(v2); + if ( !core::iszero ( txb.X ) ) + { + tangent.X = -txb.Y / txb.X; + binormal.X = -txb.Z / txb.X; + } + + v1.X = vt2.Y - vt1.Y; + v2.X = vt3.Y - vt1.Y; + txb = v1.crossProduct(v2); + + if ( !core::iszero ( txb.X ) ) + { + tangent.Y = -txb.Y / txb.X; + binormal.Y = -txb.Z / txb.X; + } + + v1.X = vt2.Z - vt1.Z; + v2.X = vt3.Z - vt1.Z; + txb = v1.crossProduct(v2); + + if ( !core::iszero ( txb.X ) ) + { + tangent.Z = -txb.Y / txb.X; + binormal.Z = -txb.Z / txb.X; + } + + tangent.normalize(); + binormal.normalize(); + + normal = tangent.crossProduct(binormal); + normal.normalize(); + + binormal = tangent.crossProduct(normal); + binormal.normalize(); + + core::plane3d pl(vt1, vt2, vt3); + + if(normal.dotProduct(pl.Normal) < 0.0f ) + normal *= -1.0f; + +#endif // USE_NVIDIA_GLH_VERSION +} + + + +//! Returns amount of polygons in mesh. +s32 CMeshManipulator::getPolyCount(scene::IMesh* mesh) const +{ + if (!mesh) + return 0; + + s32 trianglecount = 0; + + for (u32 g=0; ggetMeshBufferCount(); ++g) + trianglecount += mesh->getMeshBuffer(g)->getIndexCount() / 3; + + return trianglecount; +} + + + +//! Returns amount of polygons in mesh. +s32 CMeshManipulator::getPolyCount(scene::IAnimatedMesh* mesh) const +{ + if (mesh && mesh->getFrameCount() != 0) + return getPolyCount(mesh->getMesh(0)); + + return 0; +} + +//! create a new AnimatedMesh and adds the mesh to it +IAnimatedMesh * CMeshManipulator::createAnimatedMesh(scene::IMesh* mesh, scene::E_ANIMATED_MESH_TYPE type) const +{ + return new SAnimatedMesh(mesh, type); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CMeshManipulator.h b/src/dep/src/irrlicht/CMeshManipulator.h new file mode 100644 index 0000000..352a90f --- /dev/null +++ b/src/dep/src/irrlicht/CMeshManipulator.h @@ -0,0 +1,107 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_MANIPULATOR_H_INCLUDED__ +#define __C_MESH_MANIPULATOR_H_INCLUDED__ + +#include "IMeshManipulator.h" + +namespace irr +{ +namespace scene +{ + +//! An interface for easy manipulation of meshes. +/** Scale, set alpha value, flip surfaces, and so on. This exists for fixing problems + with wrong imported or exported meshes quickly after loading. It is not intended for doing mesh + modifications and/or animations during runtime. +*/ +class CMeshManipulator : public IMeshManipulator +{ +public: + + //! destructor + virtual ~CMeshManipulator() {} + + //! Flips the direction of surfaces. Changes backfacing triangles to frontfacing + //! triangles and vice versa. + //! \param mesh: Mesh on which the operation is performed. + virtual void flipSurfaces(scene::IMesh* mesh) const; + + //! Sets the alpha vertex color value of the whole mesh to a new value + //! \param mesh: Mesh on which the operation is performed. + //! \param alpha: New alpha for the vertex color. + virtual void setVertexColorAlpha(scene::IMesh* mesh, s32 alpha) const; + + //! Sets the colors of all vertices to one color + virtual void setVertexColors(IMesh* mesh, video::SColor color) const; + + //! Recalculates all normals of the mesh. + /** \param mesh: Mesh on which the operation is performed. + \param smooth: Whether to use smoothed normals. */ + virtual void recalculateNormals(scene::IMesh* mesh, bool smooth = false) const; + + //! Recalculates all normals of the mesh buffer. + /** \param buffer: Mesh buffer on which the operation is performed. + \param smooth: Whether to use smoothed normals. */ + virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false) const; + + //! Scales the whole mesh. + //! \param mesh: Mesh on which the operation is performed. + //! \param scale: 3D Vector, defining the value, for each axis, to scale the mesh by. + virtual void scaleMesh(scene::IMesh* mesh, const core::vector3df& scale) const; + + //! Applies a transformation + /** \param mesh: Mesh on which the operation is performed. + \param m: transformation matrix. */ + virtual void transformMesh(scene::IMesh* mesh, const core::matrix4& m) const; + + //! Clones a static IMesh into a modifiable SMesh. + virtual SMesh* createMeshCopy(scene::IMesh* mesh) const; + + //! Creates a planar texture mapping on the mesh + //! \param mesh: Mesh on which the operation is performed. + //! \param resolution: resolution of the planar mapping. This is the value + //! specifying which is the relation between world space and + //! texture coordinate space. + virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const; + + //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. + //! This is useful if you want to draw tangent space normal mapped geometry because + //! it calculates the tangent and binormal data which is needed there. + //! \param mesh: Input mesh + //! \return Mesh consiting only of S3DVertexNormalMapped vertices. + //! If you no longer need the cloned mesh, you should call IMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IMesh* createMeshWithTangents(IMesh* mesh) const; + virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const; + + virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const; + + virtual IMesh* createMeshWelded(IMesh *mesh, f32 tolerance=core::ROUNDING_ERROR_32) const; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(scene::IMesh* mesh) const; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(scene::IAnimatedMesh* mesh) const; + + //! create a new AnimatedMesh and adds the mesh to it + virtual IAnimatedMesh * createAnimatedMesh(scene::IMesh* mesh,scene::E_ANIMATED_MESH_TYPE type) const; + +private: + + static void calculateTangents(core::vector3df& normal, + core::vector3df& tangent, + core::vector3df& binormal, + const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, + const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3); +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CMeshSceneNode.cpp b/src/dep/src/irrlicht/CMeshSceneNode.cpp new file mode 100644 index 0000000..9e510d0 --- /dev/null +++ b/src/dep/src/irrlicht/CMeshSceneNode.cpp @@ -0,0 +1,343 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "ICameraSceneNode.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace scene +{ + + + +//! constructor +CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) +: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), PassCount(0), + ReadOnlyMaterials(false) +{ + #ifdef _DEBUG + setDebugName("CMeshSceneNode"); + #endif + + setMesh(mesh); +} + + + +//! destructor +CMeshSceneNode::~CMeshSceneNode() +{ + if (Mesh) + Mesh->drop(); +} + + + +//! frame +void CMeshSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + int transparentCount = 0; + int solidCount = 0; + + // count transparent and solid materials in this scene node + if (ReadOnlyMaterials && Mesh) + { + // count mesh materials + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + video::IMaterialRenderer* rnd = mb ? driver->getMaterialRenderer(mb->getMaterial().MaterialType) : 0; + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + } + else + { + // count copied materials + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + } +} + + + +//! renders the node. +void CMeshSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!Mesh || !driver) + return; + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + + ++PassCount; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + Box = Mesh->getBoundingBox(); + + // for debug purposes only: + if ( DebugDataVisible && PassCount==1) + { + if ( DebugDataVisible & scene::EDS_BBOX ) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(Box, video::SColor(0,255,255,255)); + } + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + driver->draw3DBox( + Mesh->getMeshBuffer(g)->getBoundingBox(), + video::SColor(0,255,255,255)); + } + } + if ( DebugDataVisible & scene::EDS_NORMALS ) + { + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(g); + + u32 vSize; + u32 i; + vSize = video::getVertexPitchFromType(mb->getVertexType()); + + const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices(); + video::SColor c ( 255, 128 ,0, 0 ); + video::SColor c1 ( 255, 255 ,0, 0 ); + for ( i = 0; i != mb->getVertexCount(); ++i ) + { + core::vector3df h = v->Normal * 5.f; + core::vector3df h1 = h.crossProduct ( core::vector3df ( 0.f, 1.f, 0.f ) ); + + driver->draw3DLine ( v->Pos, v->Pos + h, c ); + driver->draw3DLine ( v->Pos + h, v->Pos + h + h1, c1 ); + v = (const video::S3DVertex*) ( (u8*) v + vSize ); + } + } + } + } + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (mb) + { + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(material); + driver->drawMeshBuffer(mb); + } + } + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CMeshSceneNode::getBoundingBox() const +{ + return Mesh ? Mesh->getBoundingBox() : Box; +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hierarchy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CMeshSceneNode::getMaterial(u32 i) +{ + if (Mesh && ReadOnlyMaterials && igetMeshBufferCount()) + { + tmpReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial(); + return tmpReadOnlyMaterial; + } + + if ( i >= Materials.size()) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + + + +//! returns amount of materials used by this scene node. +u32 CMeshSceneNode::getMaterialCount() const +{ + if (Mesh && ReadOnlyMaterials) + return Mesh->getMeshBufferCount(); + + return Materials.size(); +} + + + +//! Sets a new mesh +void CMeshSceneNode::setMesh(IMesh* mesh) +{ + if (!mesh) + return; // won't set null mesh + + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + copyMaterials(); + + if (Mesh) + Mesh->grab(); +} + + +void CMeshSceneNode::copyMaterials() +{ + Materials.clear(); + + if (Mesh) + { + video::SMaterial mat; + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (mb) + mat = mb->getMaterial(); + + Materials.push_back(mat); + } + } +} + + +//! Writes attributes of the scene node. +void CMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IMeshSceneNode::serializeAttributes(out, options); + + out->addString("Mesh", SceneManager->getMeshCache()->getMeshFilename(Mesh)); + out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); +} + +//! Reads attributes of the scene node. +void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh); + core::stringc newMeshStr = in->getAttributeAsString("Mesh"); + ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); + + if (newMeshStr != "" && oldMeshStr != newMeshStr) + { + IMesh* newMesh = 0; + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + newMesh = newAnimatedMesh->getMesh(0); + + if (newMesh) + setMesh(newMesh); + } + + IMeshSceneNode::deserializeAttributes(in, options); +} + +//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. +/* In this way it is possible to change the materials a mesh causing all mesh scene nodes +referencing this mesh to change too. */ +void CMeshSceneNode::setReadOnlyMaterials(bool readonly) +{ + ReadOnlyMaterials = readonly; +} + +//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style +bool CMeshSceneNode::isReadOnlyMaterials() const +{ + return ReadOnlyMaterials; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CMeshSceneNode* nb = new CMeshSceneNode(Mesh, newParent, + newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale); + + nb->cloneMembers(this, newManager); + nb->ReadOnlyMaterials = ReadOnlyMaterials; + nb->Materials = Materials; + + nb->drop(); + return nb; +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CMeshSceneNode.h b/src/dep/src/irrlicht/CMeshSceneNode.h new file mode 100644 index 0000000..5bff6b2 --- /dev/null +++ b/src/dep/src/irrlicht/CMeshSceneNode.h @@ -0,0 +1,92 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_SCENE_NODE_H_INCLUDED__ +#define __C_MESH_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + + class CMeshSceneNode : public IMeshSceneNode + { + public: + + //! constructor + CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CMeshSceneNode(); + + //! frame + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_MESH; } + + //! Sets a new mesh + virtual void setMesh(IMesh* mesh); + + //! Returns the current mesh + virtual IMesh* getMesh(void) { return Mesh; } + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly); + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const; + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + protected: + + void copyMaterials(); + + core::array Materials; + core::aabbox3d Box; + video::SMaterial tmpReadOnlyMaterial; + + IMesh* Mesh; + + s32 PassCount; + bool ReadOnlyMaterials; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CMetaTriangleSelector.cpp b/src/dep/src/irrlicht/CMetaTriangleSelector.cpp new file mode 100644 index 0000000..e444de3 --- /dev/null +++ b/src/dep/src/irrlicht/CMetaTriangleSelector.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMetaTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CMetaTriangleSelector::CMetaTriangleSelector() +{ + #ifdef _DEBUG + setDebugName("CMetaTriangleSelector"); + #endif +} + +//! destructor +CMetaTriangleSelector::~CMetaTriangleSelector() +{ + removeAllTriangleSelectors(); +} + + + +//! Returns amount of all available triangles in this selector +s32 CMetaTriangleSelector::getTriangleCount() const +{ + s32 count = 0; + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + count += TriangleSelectors[i]->getTriangleCount(); + + return count; +} + + + +//! Gets all triangles. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform) const +{ + s32 outWritten = 0; + + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + { + s32 t = 0; + TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t, transform); + outWritten += t; + } + + outTriangleCount = outWritten; +} + + + +//! Gets all triangles which lie within a specific bounding box. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d& box, + const core::matrix4* transform) const +{ + s32 outWritten = 0; + + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + { + s32 t = 0; + TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t, + box, transform); + outWritten += t; + } + + outTriangleCount = outWritten; +} + + + +//! Gets all triangles which have or may have contact with a 3d line. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform) const +{ + s32 outWritten = 0; + + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + { + s32 t = 0; + TriangleSelectors[i]->getTriangles(triangles + outWritten, arraySize - outWritten, t, + line, transform); + outWritten += t; + } + + outTriangleCount = outWritten; +} + + + +//! Adds a triangle selector to the collection of triangle selectors +//! in this metaTriangleSelector. +void CMetaTriangleSelector::addTriangleSelector(ITriangleSelector* toAdd) +{ + if (!toAdd) + return; + + TriangleSelectors.push_back(toAdd); + toAdd->grab(); +} + + + +//! Removes a specific triangle selector which was added before from the collection. +bool CMetaTriangleSelector::removeTriangleSelector(ITriangleSelector* toRemove) +{ + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + if (toRemove == TriangleSelectors[i]) + { + TriangleSelectors[i]->drop(); + TriangleSelectors.erase(i); + return true; + } + + return false; +} + + + +//! Removes all triangle selectors from the collection. +void CMetaTriangleSelector::removeAllTriangleSelectors() +{ + for (s32 i=0; i<(s32)TriangleSelectors.size(); ++i) + TriangleSelectors[i]->drop(); + + TriangleSelectors.clear(); +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CMetaTriangleSelector.h b/src/dep/src/irrlicht/CMetaTriangleSelector.h new file mode 100644 index 0000000..12ad0a3 --- /dev/null +++ b/src/dep/src/irrlicht/CMetaTriangleSelector.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_META_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_META_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "IMetaTriangleSelector.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! Interface for making multiple triangle selectors work as one big selector. +class CMetaTriangleSelector : public IMetaTriangleSelector +{ +public: + + //! constructor + CMetaTriangleSelector(); + + //! destructor + virtual ~CMetaTriangleSelector(); + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount() const; + + //! Gets all triangles. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform=0) const; + + //! Gets all triangles which lie within a specific bounding box. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d& box, + const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + + //! Adds a triangle selector to the collection of triangle selectors + //! in this metaTriangleSelector. + virtual void addTriangleSelector(ITriangleSelector* toAdd); + + //! Removes a specific triangle selector which was added before from the collection. + virtual bool removeTriangleSelector(ITriangleSelector* toRemove); + + //! Removes all triangle selectors from the collection. + virtual void removeAllTriangleSelectors(); + +private: + + core::array TriangleSelectors; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CNullDriver.cpp b/src/dep/src/irrlicht/CNullDriver.cpp new file mode 100644 index 0000000..c5332cb --- /dev/null +++ b/src/dep/src/irrlicht/CNullDriver.cpp @@ -0,0 +1,1753 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CNullDriver.h" +#include "CSoftwareTexture.h" +#include "os.h" +#include "CImage.h" +#include "CAttributes.h" +#include "IReadFile.h" +#include "IWriteFile.h" +#include "IImageLoader.h" +#include "IImageWriter.h" +#include "IMaterialRenderer.h" + + +namespace irr +{ +namespace video +{ + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderBMP(); + +//! creates a loader which is able to load jpeg images +IImageLoader* createImageLoaderJPG(); + +//! creates a loader which is able to load targa images +IImageLoader* createImageLoaderTGA(); + +//! creates a loader which is able to load psd images +IImageLoader* createImageLoaderPSD(); + +//! creates a loader which is able to load pcx images +IImageLoader* createImageLoaderPCX(); + +//! creates a loader which is able to load png images +IImageLoader* createImageLoaderPNG(); + +//! creates a loader which is able to load ppm/pgm/pbm images +IImageLoader* createImageLoaderPPM(); + +//! creates a loader which is able to load bmp images +IImageWriter* createImageWriterBMP(); + +//! creates a loader which is able to load jpg images +IImageWriter* createImageWriterJPG(); + +//! creates a loader which is able to load tga images +IImageWriter* createImageWriterTGA(); + +//! creates a loader which is able to load psd images +IImageWriter* createImageWriterPSD(); + +//! creates a loader which is able to load pcx images +IImageWriter* createImageWriterPCX(); + +//! creates a loader which is able to load png images +IImageWriter* createImageWriterPNG(); + +//! creates a loader which is able to load ppm images +IImageWriter* createImageWriterPPM(); + + + +//! constructor +CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize) +: FileSystem(io), ViewPort(0,0,0,0), ScreenSize(screenSize), + PrimitivesDrawn(0), TextureCreationFlags(0) +{ + #ifdef _DEBUG + setDebugName("CNullDriver"); + #endif + + setFog(); + + setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true); + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true); + + ViewPort = core::rect(core::position2d(0,0), screenSize); + + if (FileSystem) + FileSystem->grab(); + + // create surface loader + +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderBMP()); +#endif +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderJPG()); +#endif +#ifdef _IRR_COMPILE_WITH_TGA_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderTGA()); +#endif +#ifdef _IRR_COMPILE_WITH_PSD_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPSD()); +#endif +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPCX()); +#endif +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPNG()); +#endif +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPPM()); +#endif + +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + SurfaceWriter.push_back(video::createImageWriterBMP()); +#endif +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + SurfaceWriter.push_back(video::createImageWriterJPG()); +#endif +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + SurfaceWriter.push_back(video::createImageWriterTGA()); +#endif +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPSD()); +#endif +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPCX()); +#endif +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPNG()); +#endif +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPPM()); +#endif + + // set ExposedData to 0 + memset(&ExposedData, 0, sizeof(ExposedData)); +} + + + +//! destructor +CNullDriver::~CNullDriver() +{ + // delete file system + + if (FileSystem) + FileSystem->drop(); + + // delete textures + + deleteAllTextures(); + + // delete surface loader + + u32 i; + for (i=0; idrop(); + + // delete surface writer + + for (i=0; idrop(); + + deleteMaterialRenders(); +} + + +//! Adds an external surface loader to the engine. +void CNullDriver::addExternalImageLoader(IImageLoader* loader) +{ + if (!loader) + return; + + loader->grab(); + SurfaceLoader.push_back(loader); +} + + +//! Adds an external surface writer to the engine. +void CNullDriver::addExternalImageWriter(IImageWriter* writer) +{ + if (!writer) + return; + + writer->grab(); + SurfaceWriter.push_back(writer); +} + + +//! deletes all textures +void CNullDriver::deleteAllTextures() +{ + for (u32 i=0; idrop(); + + Textures.clear(); +} + + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + core::clearFPUException (); + PrimitivesDrawn = 0; + return true; +} + + + +//! applications must call this method after performing any rendering. returns false if failed. +bool CNullDriver::endScene( s32 windowId, core::rect* sourceRect ) +{ + FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn); + return true; +} + + + +//! queries the features of the driver, returns true if feature is available +bool CNullDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + return false; +} + + + +//! sets transformation +void CNullDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CNullDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return TransformationMatrix; +} + + + +//! sets a material +void CNullDriver::setMaterial(const SMaterial& material) +{ +} + + + +//! Removes a texture from the texture cache and deletes it, freeing lot of +//! memory. +void CNullDriver::removeTexture(ITexture* texture) +{ + if (!texture) + return; + + for (u32 i=0; idrop(); + Textures.erase(i); + } +} + + +//! Removes all texture from the texture cache and deletes them, freeing lot of +//! memory. +void CNullDriver::removeAllTextures() +{ + deleteAllTextures(); +} + + +//! Returns a texture by index +ITexture* CNullDriver::getTextureByIndex(u32 i) +{ + if ( i < Textures.size() ) + return Textures[i].Surface; + + return 0; +} + + +//! Returns amount of textures currently loaded +u32 CNullDriver::getTextureCount() const +{ + return Textures.size(); +} + + +//! Renames a texture +void CNullDriver::renameTexture(ITexture* texture, const c8* newName) +{ + // we can do a const_cast here safely, the name of the ITexture interface + // is just readonly to prevent the user changing the texture name without invoking + // this method, because the textures will need resorting afterwards + + core::stringc& name = const_cast(texture->getName()); + name = newName; + + Textures.sort(); +} + + +//! loads a Texture +ITexture* CNullDriver::getTexture(const c8* filename) +{ + ITexture* texture = findTexture(filename); + + if (texture) + return texture; + + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + bool errorReported = false; + + if (file) + { + texture = loadTextureFromFile(file, filename); + file->drop(); + + if (texture) + { + addTexture(texture); + texture->drop(); // drop it because we created it, one grab too much + } + } + else + { + errorReported = true; + os::Printer::log("Could not open file of texture", filename, ELL_ERROR); + } + + if (!texture && !errorReported) + os::Printer::log("Could not load texture", filename, ELL_ERROR); + + return texture; +} + + + +//! loads a Texture +ITexture* CNullDriver::getTexture(io::IReadFile* file) +{ + ITexture* texture = 0; + + if (file) + { + texture = findTexture(file->getFileName()); + + if (texture) + return texture; + + texture = loadTextureFromFile(file); + + if (texture) + { + addTexture(texture); + texture->drop(); // drop it because we created it, one grab too much + } + } + + if (!texture) + os::Printer::log("Could not load texture", file->getFileName(), ELL_ERROR); + + return texture; +} + + + +//! opens the file and loads it into the surface +video::ITexture* CNullDriver::loadTextureFromFile(io::IReadFile* file, const c8 *hashName ) +{ + ITexture* texture = 0; + IImage* image = createImageFromFile(file); + + if (image) + { + // create texture from surface + texture = createDeviceDependentTexture(image, hashName ? hashName : file->getFileName() ); + os::Printer::log("Loaded texture", file->getFileName()); + image->drop(); + } + + return texture; +} + + + +//! adds a surface, not loaded or created by the Irrlicht Engine +void CNullDriver::addTexture(video::ITexture* texture) +{ + if (texture) + { + SSurface s; + s.Surface = texture; + texture->grab(); + + Textures.push_back(s); + + // the new texture is now at the end of the texture list. when searching for + // the next new texture, the texture array will be sorted and the index of this texture + // will be changed. to let the order be more consistent to the user, sort + // the textures now already although this isn't necessary: + + Textures.sort(); + } +} + + + +//! looks if the image is already loaded +video::ITexture* CNullDriver::findTexture(const c8* filename) +{ + if (!filename) + filename = ""; + + SSurface s; + SDummyTexture dummy(filename); + s.Surface = &dummy; + + s32 index = Textures.binary_search(s); + if (index != -1) + return Textures[index].Surface; + + return 0; +} + + + +//! Creates a texture from a loaded IImage. +ITexture* CNullDriver::addTexture(const c8* name, IImage* image) +{ + if (!name || !image) + return 0; + + ITexture* t = createDeviceDependentTexture(image, name); + if (t) + { + addTexture(t); + t->drop(); + } + return t; +} + + + +//! creates a Texture +ITexture* CNullDriver::addTexture(const core::dimension2d& size, + const c8* name, ECOLOR_FORMAT format) +{ + if (!name) + return 0; + + IImage* image = new CImage(format, size); + ITexture* t = createDeviceDependentTexture(image, name); + image->drop(); + addTexture(t); + + if (t) + t->drop(); + + return t; +} + + + +//! returns a device dependent texture from a software surface (IImage) +//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES +ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const char* name) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CSoftwareTexture(surface, name); + #else + return 0; + #endif +} + + + +//! sets a render target +bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + return false; +} + + + +//! sets a viewport +void CNullDriver::setViewPort(const core::rect& area) +{ +} + + + +//! gets the area of the current viewport +const core::rect& CNullDriver::getViewPort() const +{ + return ViewPort; +} + + + +//! draws a vertex primitive list +void CNullDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + PrimitivesDrawn += primitiveCount; +} + + + +//! draws an indexed triangle list +inline void CNullDriver::drawIndexedTriangleList(const S3DVertex* vertices, u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_STANDARD, scene::EPT_TRIANGLES); +} + + + +//! draws an indexed triangle list +inline void CNullDriver::drawIndexedTriangleList(const S3DVertex2TCoords* vertices, u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_2TCOORDS, scene::EPT_TRIANGLES); +} + + +//! Draws an indexed triangle list. +inline void CNullDriver::drawIndexedTriangleList(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_TANGENTS, scene::EPT_TRIANGLES); +} + + + +//! Draws an indexed triangle fan. +inline void CNullDriver::drawIndexedTriangleFan(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_STANDARD, scene::EPT_TRIANGLE_FAN); +} + + + +//! Draws an indexed triangle fan. +inline void CNullDriver::drawIndexedTriangleFan(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_2TCOORDS, scene::EPT_TRIANGLE_FAN); +} + + + +//! Draws an indexed triangle fan. +inline void CNullDriver::drawIndexedTriangleFan(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount) +{ + drawVertexPrimitiveList(vertices, vertexCount, indexList, triangleCount, EVT_TANGENTS, scene::EPT_TRIANGLE_FAN); +} + + + +//! Draws a 3d line. +void CNullDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ +} + + + +//! Draws a 3d triangle. +void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color) +{ + draw3DLine(triangle.pointA, triangle.pointB, color); + draw3DLine(triangle.pointB, triangle.pointC, color); + draw3DLine(triangle.pointC, triangle.pointA, color); +} + + + +//! Draws a 3d axis aligned box. +void CNullDriver::draw3DBox(const core::aabbox3d& box, SColor color) +{ + core::vector3df edges[8]; + box.getEdges(edges); + + // TODO: optimize into one big drawIndexPrimitive call. + + draw3DLine(edges[5], edges[1], color); + draw3DLine(edges[1], edges[3], color); + draw3DLine(edges[3], edges[7], color); + draw3DLine(edges[7], edges[5], color); + draw3DLine(edges[0], edges[2], color); + draw3DLine(edges[2], edges[6], color); + draw3DLine(edges[6], edges[4], color); + draw3DLine(edges[4], edges[0], color); + draw3DLine(edges[1], edges[0], color); + draw3DLine(edges[3], edges[2], color); + draw3DLine(edges[7], edges[6], color); + draw3DLine(edges[5], edges[4], color); +} + + + +//! draws an 2d image +void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos) +{ + if (!texture) + return; + + draw2DImage(texture,destPos, core::rect(core::position2d(0,0), texture->getOriginalSize())); +} + + + +//! draws a set of 2d images, using a color and the alpha channel of the +//! texture if desired. The images are drawn beginning at pos and concatenated +//! in one line. All drawings are clipped against clipRect (if != 0). +//! The subtextures are defined by the array of sourceRects and are chosen +//! by the indices given. +void CNullDriver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + s32 kerningWidth, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + core::position2d target(pos); + + for (u32 i=0; i& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + video::SColor* colors, bool useAlphaChannelOfTexture) +{ +} + + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ +} + + + +//! draw an 2d rectangle +void CNullDriver::draw2DRectangle(SColor color, const core::rect& pos, const core::rect* clip) +{ + draw2DRectangle(pos, color, color, color, color, clip); +} + + + +//!Draws an 2d rectangle with a gradient. +void CNullDriver::draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ +} + + + +//! Draws a 2d line. +void CNullDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, SColor color) +{ +} + + + +//! Draws a non filled concyclic regular 2d polyon. +void CNullDriver::draw2DPolygon(core::position2d center, + f32 radius, video::SColor color, s32 count) +{ + if (count < 2) + return; + + core::position2d first; + core::position2d a,b; + + for (s32 j=0; j((s32)(sin(p)*radius), (s32)(cos(p)*radius)); + + if (j==0) + first = a; + else + draw2DLine(a, b, color); + } + + draw2DLine(a, first, color); +} + + + + +//! returns screen size +const core::dimension2d& CNullDriver::getScreenSize() const +{ + return ScreenSize; +} + +//! returns the current render target size, +//! or the screen size if render targets are not implemented +const core::dimension2d& CNullDriver::getCurrentRenderTargetSize() const +{ + return ScreenSize; +} + + +// returns current frames per second value +s32 CNullDriver::getFPS() const +{ + return FPSCounter.getFPS(); +} + + + +//! returns amount of primitives (mostly triangles) were drawn in the last frame. +//! very useful method for statistics. +u32 CNullDriver::getPrimitiveCountDrawn( u32 param ) const +{ + return (0 == param) ? FPSCounter.getPrimitive() : (1 == param) ? FPSCounter.getPrimitiveAverage() : FPSCounter.getPrimitiveTotal(); +} + + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CNullDriver::setAmbientLight(const SColorf& color) +{ +} + + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 +//! driver, it would return "Direct3D8". +const wchar_t* CNullDriver::getName() const +{ + return L"Irrlicht NullDevice"; +} + + + +//! 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 +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CNullDriver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail) +{ +} + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CNullDriver::drawStencilShadow(bool clearStencilBuffer, + video::SColor leftUpEdge, video::SColor rightUpEdge, + video::SColor leftDownEdge, video::SColor rightDownEdge) +{ +} + + +//! deletes all dynamic lights there are +void CNullDriver::deleteAllDynamicLights() +{ + Lights.set_used(0); +} + + +//! adds a dynamic light +void CNullDriver::addDynamicLight(const SLight& light) +{ + Lights.push_back(light); +} + + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CNullDriver::getMaximalDynamicLightAmount() const +{ + return 0; +} + + +//! Returns current amount of dynamic lights set +//! \return Current amount of dynamic lights set +u32 CNullDriver::getDynamicLightCount() const +{ + return Lights.size(); +} + + +//! Returns light data which was previously set by IVideoDriver::addDynamicLight(). +//! \param idx: Zero based index of the light. Must be greater than 0 and smaller +//! than IVideoDriver()::getDynamicLightCount. +//! \return Light data. +const SLight& CNullDriver::getDynamicLight(u32 idx) const +{ + if ( idx < Lights.size() ) + return Lights[idx]; + else + return *((SLight*)0); +} + + +//! Creates an 1bit alpha channel of the texture based of an color key. +void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor color) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); + return; + } + + if (texture->getColorFormat() == ECF_A1R5G5B5) + { + s16 *p = (s16*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + s32 pitch = texture->getPitch() / 2; + + // color with alpha enabled (color opaque) + s16 ref = (0x1<<15) | (0x7fff & color.toA1R5G5B5()); + + for (s32 y=0; yunlock(); + } + else + { + s32 *p = (s32*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + s32 pitch = texture->getPitch() / 4; + + // color with alpha enabled (color opaque) + s32 ref = 0xff000000 | (0x00ffffff & color.color); + + for (s32 y=0; yunlock(); + } +} + + + +//! Creates an 1bit alpha channel of the texture based of an color key position. +void CNullDriver::makeColorKeyTexture(video::ITexture* texture, + core::position2d colorKeyPixelPos) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); + return; + } + + if (texture->getColorFormat() == ECF_A1R5G5B5) + { + s16 *p = (s16*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + s32 pitch = texture->getPitch() / 2; + + s16 ref = (0x1<<15) | (0x7fff & p[colorKeyPixelPos.Y*dim.Width + colorKeyPixelPos.X]); + + for (s32 y=0; yunlock(); + } + else + { + s32 *p = (s32*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + s32 pitch = texture->getPitch() / 4; + + s32 ref = (0xff<<24) | (0x00ffffff & p[colorKeyPixelPos.Y*dim.Width + colorKeyPixelPos.X]); + + for (s32 y=0; yunlock(); + } +} + + + +//! Creates a normal map from a height map texture. +//! \param amplitude: Constant value by which the height information is multiplied. +void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + amplitude = amplitude / 255.0f; + f32 vh = dim.Height / (f32)dim.Width; + f32 hh = dim.Width / (f32)dim.Height; + + if (texture->getColorFormat() == ECF_A8R8G8B8) + { + // ECF_A8R8G8B8 version + + s32 *p = (s32*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); + return; + } + + // copy texture + + s32 pitch = texture->getPitch() / 4; + + s32* in = new s32[dim.Height * pitch]; + memcpy(in, p, dim.Height * pitch * 4); + + for (s32 x=0; xunlock(); + } + else + { + // ECF_A1R5G5B5 version + + s16 *p = (s16*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); + return; + } + + s32 pitch = texture->getPitch() / 2; + + // copy texture + + s16* in = new s16[dim.Height * pitch]; + memcpy(in, p, dim.Height * pitch * 2); + + for (s32 x=0; xunlock(); + } + + texture->regenerateMipMapLevels(); +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CNullDriver::getMaximalPrimitiveCount() const +{ + return 0xFFFFFFFF; +} + + +//! checks triangle count and print warning if wrong +bool CNullDriver::checkPrimitiveCount(u32 prmCount) const +{ + const u32 m = getMaximalPrimitiveCount(); + + if (prmCount > m) + { + char tmp[1024]; + sprintf(tmp,"Could not draw triangles, too many primitives(%u), maxium is %u.", prmCount, m); + os::Printer::log(tmp, ELL_ERROR); + return false; + } + + return true; +} + +//! Enables or disables a texture creation flag. +void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) +{ + if (enabled && ((flag == ETCF_ALWAYS_16_BIT) || (flag == ETCF_ALWAYS_32_BIT) + || (flag == ETCF_OPTIMIZED_FOR_QUALITY) || (flag == ETCF_OPTIMIZED_FOR_SPEED))) + { + // disable other formats + setTextureCreationFlag(ETCF_ALWAYS_16_BIT, false); + setTextureCreationFlag(ETCF_ALWAYS_32_BIT, false); + setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, false); + setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false); + } + + // set flag + TextureCreationFlags = (TextureCreationFlags & (~flag)) | + ((((u32)!enabled)-1) & flag); +} + + +//! Returns if a texture creation flag is enabled or disabled. +bool CNullDriver::getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const +{ + return (TextureCreationFlags & flag)!=0; +} + + +//! Creates a software image from a file. +IImage* CNullDriver::createImageFromFile(const char* filename) +{ + if (!filename) + return 0; + + IImage* image = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + image = createImageFromFile(file); + file->drop(); + } + else + os::Printer::log("Could not open file of image", filename, ELL_ERROR); + + return image; +} + + +//! Creates a software image from a file. +IImage* CNullDriver::createImageFromFile(io::IReadFile* file) +{ + if (!file) + return 0; + + IImage* image = 0; + + u32 i; + + // try to load file based on file extension + for (i=0; iisALoadableFileExtension(file->getFileName())) + { + // reset file position which might have changed due to previous loadImage calls + file->seek(0); + image = SurfaceLoader[i]->loadImage(file); + if (image) + return image; + } + } + + // try to load file based on what is in it + for (i=0; iseek(0); + if (SurfaceLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + image = SurfaceLoader[i]->loadImage(file); + if (image) + return image; + } + } + + return 0; // failed to load +} + + + +//! Writes the provided image to disk file +bool CNullDriver::writeImageToFile(IImage* image, const char* filename,u32 param) +{ + for (u32 i=0; iisAWriteableFileExtension(filename)) + { + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if (file) + { + bool written = SurfaceWriter[i]->writeImage(file, image, param); + file->drop(); + if (written) + return true; + } + } + } + return false; // failed to write +} + + + +//! Creates a software image from a byte array. +IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d& size, + void *data, bool ownForeignMemory, + bool deleteMemory) +{ + return new CImage(format, size, data, ownForeignMemory, deleteMemory); +} + + +//! Sets the fog mode. +void CNullDriver::setFog(SColor color, bool linearFog, f32 start, f32 end, f32 density, + bool pixelFog, bool rangeFog) +{ + FogColor = color; + LinearFog = linearFog; + FogStart = start; + FogEnd = end; + FogDensity = density; + PixelFog = pixelFog; + RangeFog = rangeFog; +} + + +//! Draws a mesh buffer +void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) +{ + if (!mb) + return; + + drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES); +} + + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CNullDriver::OnResize(const core::dimension2d& size) +{ + if (ViewPort.getWidth() == ScreenSize.Width && + ViewPort.getHeight() == ScreenSize.Height) + ViewPort = core::rect(core::position2d(0,0), size); + + ScreenSize = size; +} + +// adds a material renderer and drops it afterwards. To be used for internal creation +s32 CNullDriver::addAndDropMaterialRenderer(IMaterialRenderer* m) +{ + s32 i = addMaterialRenderer(m); + + if (m) + m->drop(); + + return i; +} + + +//! Adds a new material renderer to the video device. +s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* name) +{ + if (!renderer) + return -1; + + SMaterialRenderer r; + r.Renderer = renderer; + r.Name = name; + + if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 )) + { + // set name of built in renderer so that we don't have to implement name + // setting in all available renderers. + r.Name = sBuiltInMaterialTypeNames[MaterialRenderers.size()]; + } + + MaterialRenderers.push_back(r); + renderer->grab(); + + return MaterialRenderers.size()-1; +} + + +//! Sets the name of a material renderer. +void CNullDriver::setMaterialRendererName(s32 idx, const char* name) +{ + if (idx < s32(sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 || + idx >= (s32)MaterialRenderers.size()) + return; + + MaterialRenderers[idx].Name = name; +} + + +//! Creates material attributes list from a material, usable for serialization and more. +io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material) +{ + io::CAttributes* attr = new io::CAttributes(this); + + attr->addEnum("Type", material.MaterialType, sBuiltInMaterialTypeNames); + + attr->addColor("Ambient", material.AmbientColor); + attr->addColor("Diffuse", material.DiffuseColor); + attr->addColor("Emissive", material.EmissiveColor); + attr->addColor("Specular", material.SpecularColor); + + attr->addFloat("Shininess", material.Shininess); + attr->addFloat("Param1", material.MaterialTypeParam); + attr->addFloat("Param2", material.MaterialTypeParam2); + + core::stringc prefix="Texture"; + u32 i; + for (i=0; iaddTexture((prefix+(i+1)).c_str(), material.getTexture(i)); + + attr->addBool("Wireframe", material.Wireframe); + attr->addBool("GouraudShading", material.GouraudShading); + attr->addBool("Lighting", material.Lighting); + attr->addBool("ZWriteEnable", material.ZWriteEnable); + attr->addInt("ZBuffer", material.ZBuffer); + attr->addBool("BackfaceCulling", material.BackfaceCulling); + attr->addBool("FogEnable", material.FogEnable); + attr->addBool("NormalizeNormals", material.NormalizeNormals); + + prefix = "BilinearFilter"; + for (i=0; iaddBool((prefix+(i+1)).c_str(), material.TextureLayer[i].BilinearFilter); + prefix = "TrilinearFilter"; + for (i=0; iaddBool((prefix+(i+1)).c_str(), material.TextureLayer[i].TrilinearFilter); + prefix = "AnisotropicFilter"; + for (i=0; iaddBool((prefix+(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter); + prefix="TextureWrap"; + for (i=0; iaddEnum((prefix+(i+1)).c_str(), material.TextureLayer[i].TextureWrap, aTextureClampNames); + + return attr; +} + + +//! Fills an SMaterial structure from attributes. +void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attr) +{ + outMaterial.MaterialType = video::EMT_SOLID; + + core::stringc name = attr->getAttributeAsString("Type"); + + u32 i; + + for ( i=0; i < MaterialRenderers.size(); ++i) + if ( name == MaterialRenderers[i].Name ) + { + outMaterial.MaterialType = (video::E_MATERIAL_TYPE)i; + break; + } + + outMaterial.AmbientColor = attr->getAttributeAsColor("Ambient"); + outMaterial.DiffuseColor = attr->getAttributeAsColor("Diffuse"); + outMaterial.EmissiveColor = attr->getAttributeAsColor("Emissive"); + outMaterial.SpecularColor = attr->getAttributeAsColor("Specular"); + + outMaterial.Shininess = attr->getAttributeAsFloat("Shininess"); + outMaterial.MaterialTypeParam = attr->getAttributeAsFloat("Param1"); + outMaterial.MaterialTypeParam2 = attr->getAttributeAsFloat("Param2"); + + core::stringc prefix="Texture"; + for (i=0; igetAttributeAsTexture((prefix+(i+1)).c_str())); + + outMaterial.Wireframe = attr->getAttributeAsBool("Wireframe"); + outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading"); + outMaterial.Lighting = attr->getAttributeAsBool("Lighting"); + outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable"); + outMaterial.ZBuffer = attr->getAttributeAsInt("ZBuffer"); + outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling"); + outMaterial.FogEnable = attr->getAttributeAsBool("FogEnable"); + outMaterial.NormalizeNormals = attr->getAttributeAsBool("NormalizeNormals"); + prefix = "BilinearFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsBool((prefix+(i+1)).c_str()); + + prefix = "TrilinearFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_TRILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsBool((prefix+(i+1)).c_str()); + + prefix = "AnisotropicFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_ANISOTROPIC_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsBool((prefix+(i+1)).c_str()); + + prefix = "TextureWrap"; + for (i=0; igetAttributeAsEnumeration((prefix+(i+1)).c_str(), aTextureClampNames); +} + + +//! Returns driver and operating system specific data about the IVideoDriver. +const SExposedVideoData& CNullDriver::getExposedVideoData() +{ + return ExposedData; +} + + +//! Returns type of video driver +E_DRIVER_TYPE CNullDriver::getDriverType() const +{ + return EDT_NULL; +} + +//! deletes all material renderers +void CNullDriver::deleteMaterialRenders() +{ + // delete material renderers + for (int i=0; i<(int)MaterialRenderers.size(); ++i) + if (MaterialRenderers[i].Renderer) + MaterialRenderers[i].Renderer->drop(); + + MaterialRenderers.clear(); +} + +//! Returns pointer to material renderer or null +IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) +{ + if ( idx < MaterialRenderers.size() ) + return MaterialRenderers[idx].Renderer; + else + return 0; +} + + + +//! Returns amount of currently available material renderers. +u32 CNullDriver::getMaterialRendererCount() const +{ + return MaterialRenderers.size(); +} + + +//! Returns name of the material renderer +const char* CNullDriver::getMaterialRendererName(u32 idx) const +{ + if ( idx < MaterialRenderers.size() ) + return MaterialRenderers[idx].Name.c_str(); + + return 0; +} + + +//! Returns pointer to the IGPUProgrammingServices interface. +IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices() +{ + return 0; +} + +//! Adds a new material renderer to the VideoDriver, based on a high level shading +//! language. Currently only HLSL in D3D9 is supported. +s32 CNullDriver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + os::Printer::log("High level shader materials not available (yet) in this driver, sorry"); + return -1; +} + +//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), +//! but tries to load the programs from files. +s32 CNullDriver::addHighLevelShaderMaterialFromFiles( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + io::IReadFile* vsfile = 0; + io::IReadFile* psfile = 0; + + if (vertexShaderProgram) + { + vsfile = FileSystem->createAndOpenFile(vertexShaderProgram); + if (!vsfile) + { + os::Printer::log("Could not open vertex shader program file", + vertexShaderProgram, ELL_WARNING); + return -1; + } + } + + if (pixelShaderProgram) + { + psfile = FileSystem->createAndOpenFile(pixelShaderProgram); + if (!psfile) + { + os::Printer::log("Could not open pixel shader program file", + pixelShaderProgram, ELL_WARNING); + if (vsfile) + vsfile->drop(); + return -1; + } + } + + s32 result = addHighLevelShaderMaterialFromFiles( + vsfile, vertexShaderEntryPointName, vsCompileTarget, + psfile, pixelShaderEntryPointName, psCompileTarget, + callback, baseMaterial, userData); + + if (psfile) + psfile->drop(); + + if (vsfile) + vsfile->drop(); + + return result; +} + +//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), +//! but tries to load the programs from files. +s32 CNullDriver::addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + io::IReadFile* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + c8* vs = 0; + c8* ps = 0; + + if (vertexShaderProgram) + { + const long size = vertexShaderProgram->getSize(); + if (size) + { + vs = new c8[size+1]; + vertexShaderProgram->read(vs, size); + vs[size] = 0; + } + } + + if (pixelShaderProgram) + { + const long size = pixelShaderProgram->getSize(); + if (size) + { + ps = new c8[size+1]; + pixelShaderProgram->read(ps, size); + ps[size] = 0; + } + } + + s32 result = this->addHighLevelShaderMaterial( + vs, vertexShaderEntryPointName, vsCompileTarget, + ps, pixelShaderEntryPointName, psCompileTarget, + callback, baseMaterial, userData); + + delete [] vs; + delete [] ps; + + return result; +} + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CNullDriver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + os::Printer::log("Shader materials not implemented yet in this driver, sorry."); + return -1; +} + +//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the +//! programs from files. +s32 CNullDriver::addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, + io::IReadFile* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + c8* vs = 0; + c8* ps = 0; + + if (vertexShaderProgram) + { + const long size = vertexShaderProgram->getSize(); + if (size) + { + vs = new c8[size+1]; + vertexShaderProgram->read(vs, size); + vs[size] = 0; + } + } + + if (pixelShaderProgram) + { + const long size = pixelShaderProgram->getSize(); + if (size) + { + ps = new c8[size+1]; + pixelShaderProgram->read(ps, size); + ps[size] = 0; + } + } + + s32 result = addShaderMaterial(vs, ps, callback, baseMaterial, userData); + + delete [] vs; + delete [] ps; + + return result; +} + + + +//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the +//! programs from files. +s32 CNullDriver::addShaderMaterialFromFiles(const c8* vertexShaderProgramFileName, + const c8* pixelShaderProgramFileName, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + io::IReadFile* vsfile = 0; + io::IReadFile* psfile = 0; + + if (vertexShaderProgramFileName) + { + vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); + if (!vsfile) + { + os::Printer::log("Could not open vertex shader program file", + vertexShaderProgramFileName, ELL_WARNING); + return -1; + } + } + + if (pixelShaderProgramFileName) + { + psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); + if (!psfile) + { + os::Printer::log("Could not open pixel shader program file", + pixelShaderProgramFileName, ELL_WARNING); + if (vsfile) + vsfile->drop(); + return -1; + } + } + + s32 result = addShaderMaterialFromFiles(vsfile, psfile, callback, + baseMaterial, userData); + + if (psfile) + psfile->drop(); + + if (vsfile) + vsfile->drop(); + + return result; +} + +//! Creates a render target texture. +ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + return 0; +} + +//! Clears the ZBuffer. +void CNullDriver::clearZBuffer() +{ +} + +//! Returns an image created from the last rendered frame. +IImage* CNullDriver::createScreenShot() +{ + return 0; +} + +// prints renderer version +void CNullDriver::printVersion() +{ + core::stringw namePrint = L"Using renderer: "; + namePrint += getName(); + os::Printer::log(namePrint.c_str(), ELL_INFORMATION); +} + + +//! creates a video driver +IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize) +{ + return new CNullDriver(io, screenSize); +} + + +//! Set/unset a clipping plane. +//! There are at least 6 clipping planes available for the user to set at will. +//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. +//! \param plane: The plane itself. +//! \param enable: If true, enable the clipping plane else disable it. +bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + return false; +} + +//! Enable/disable a clipping plane. +//! There are at least 6 clipping planes available for the user to set at will. +//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. +//! \param enable: If true, enable the clipping plane else disable it. +void CNullDriver::enableClipPlane(u32 index, bool enable) +{ + // not necessary +} + + +} // end namespace +} // end namespace + diff --git a/src/dep/src/irrlicht/CNullDriver.h b/src/dep/src/irrlicht/CNullDriver.h new file mode 100644 index 0000000..ce08f73 --- /dev/null +++ b/src/dep/src/irrlicht/CNullDriver.h @@ -0,0 +1,529 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_NULL_H_INCLUDED__ +#define __C_VIDEO_NULL_H_INCLUDED__ + +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "IImagePresenter.h" +#include "IGPUProgrammingServices.h" +#include "irrArray.h" +#include "irrString.h" +#include "IAttributes.h" +#include "IMeshBuffer.h" +#include "CFPSCounter.h" +#include "S3DVertex.h" +#include "SLight.h" +#include "SExposedVideoData.h" + +namespace irr +{ +namespace io +{ + class IWriteFile; + class IReadFile; +} // end namespace io +namespace video +{ + class IImageLoader; + class IImageWriter; + + class CNullDriver : public IVideoDriver, public IGPUProgrammingServices + { + public: + + //! constructor + CNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize); + + //! destructor + virtual ~CNullDriver(); + + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + virtual bool endScene( s32 windowId = 0, core::rect* sourceRect=0 ); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! loads a Texture + virtual ITexture* getTexture(const c8* filename); + + //! loads a Texture + virtual ITexture* getTexture(io::IReadFile* file); + + //! Returns a texture by index + virtual ITexture* getTextureByIndex(u32 index); + + //! Returns amount of textures currently loaded + virtual u32 getTextureCount() const; + + //! Renames a texture + virtual void renameTexture(ITexture* texture, const c8* newName); + + //! creates a Texture + virtual ITexture* addTexture(const core::dimension2d& size, const c8* name, ECOLOR_FORMAT format = ECF_A8R8G8B8); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(const S3DVertex* vertices, u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(const S3DVertex2TCoords* vertices, u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! Draws an indexed triangle list. + virtual void drawIndexedTriangleList(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! Draws an indexed triangle fan. + virtual void drawIndexedTriangleFan(const S3DVertex* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! Draws an indexed triangle list. + virtual void drawIndexedTriangleFan(const S3DVertex2TCoords* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! Draws an indexed triangle fan. + inline void drawIndexedTriangleFan(const S3DVertexTangents* vertices, + u32 vertexCount, const u16* indexList, u32 triangleCount); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! Draws a 3d triangle. + virtual void draw3DTriangle(const core::triangle3df& triangle, + SColor color = SColor(255,255,255,255)); + + //! Draws a 3d axis aligned box. + virtual void draw3DBox(const core::aabbox3d& box, + SColor color = SColor(255,255,255,255)); + + //! draws an 2d image + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos); + + //! draws a set of 2d images, using a color and the alpha + /** channel of the texture if desired. The images are drawn + beginning at pos and concatenated in one line. All drawings + are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects + and are chosen by the indices given. + \param texture: Texture to be drawn. + \param pos: Upper left 2d destination position where the image will be drawn. + \param sourceRects: Source rectangles of the image. + \param indices: List of indices which choose the actual rectangle used each time. + \param kerningWidth: offset on position + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be 0. Then the image is not clipped. + \param color: Color with which the image is colored. + Note that the alpha component is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + s32 kerningWidth = 0, + const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a non filled concyclic reqular 2d polyon. + virtual void draw2DPolygon(core::position2d center, + f32 radius, video::SColor Color, s32 vertexCount); + + virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true, + f32 start=50.0f, f32 end=100.0f, + f32 density=0.01f, bool pixelFog=false, bool rangeFog=false); + + //! returns screen size + virtual const core::dimension2d& getScreenSize() const; + + //! returns screen size + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + // returns current frames per second value + virtual s32 getFPS() const; + + //! returns amount of primitives (mostly triangles) were drawn in the last frame. + //! very useful method for statistics. + virtual u32 getPrimitiveCountDrawn( u32 param = 0 ) const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light + virtual void addDynamicLight(const SLight& light); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Adds an external image loader to the engine. + virtual void addExternalImageLoader(IImageLoader* loader); + + //! Adds an external image writer to the engine. + virtual void addExternalImageWriter(IImageWriter* writer); + + //! 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 + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail=true); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns current amount of dynamic lights set + //! \return Current amount of dynamic lights set + virtual u32 getDynamicLightCount() const; + + //! Returns light data which was previously set with IVideDriver::addDynamicLight(). + //! \param idx: Zero based index of the light. Must be greater than 0 and smaller + //! than IVideoDriver()::getDynamicLightCount. + //! \return Light data. + virtual const SLight& getDynamicLight(u32 idx) const; + + //! Removes a texture from the texture cache and deletes it, freeing lot of + //! memory. + virtual void removeTexture(ITexture* texture); + + //! Removes all texture from the texture cache and deletes them, freeing lot of + //! memory. + virtual void removeAllTextures(); + + //! Creates a render target texture. + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + //! Creates an 1bit alpha channel of the texture based of an color key. + virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color) const; + + //! Creates an 1bit alpha channel of the texture based of an color key position. + virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d colorKeyPixelPos) const; + + //! Creates a normal map from a height map texture. + //! \param amplitude: Constant value by which the height information is multiplied. + virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const; + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Returns if a texture creation flag is enabled or disabled. + virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const; + + //! Creates a software image from a file. + virtual IImage* createImageFromFile(const char* filename); + + //! Creates a software image from a file. + virtual IImage* createImageFromFile(io::IReadFile* file); + + //! Creates a software image from a byte array. + //! \param useForeignMemory: If true, the image will use the data pointer + //! directly and own it from now on, which means it will also try to delete [] the + //! data when the image will be destructed. If false, the memory will by copied. + virtual IImage* createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d& size, void *data, + bool ownForeignMemory=true, bool deleteForeignMemory = true); + + //! Draws a mesh buffer + virtual void drawMeshBuffer(const scene::IMeshBuffer* mb); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Adds a new material renderer to the video device. + virtual s32 addMaterialRenderer(IMaterialRenderer* renderer, + const char* name = 0); + + //! Returns driver and operating system specific data about the IVideoDriver. + virtual const SExposedVideoData& getExposedVideoData(); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Returns pointer to the IGPUProgrammingServices interface. + virtual IGPUProgrammingServices* getGPUProgrammingServices(); + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0, + const c8* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram = 0, + io::IReadFile* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + virtual s32 addShaderMaterialFromFiles(const c8* vertexShaderProgramFileName = 0, + const c8* pixelShaderProgramFileName = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Returns pointer to material renderer or null + virtual IMaterialRenderer* getMaterialRenderer(u32 idx); + + //! Returns amount of currently available material renderers. + virtual u32 getMaterialRendererCount() const; + + //! Returns name of the material renderer + virtual const char* getMaterialRendererName(u32 idx) const; + + //! Adds a new material renderer to the VideoDriver, based on a high level shading + //! language. Currently only HLSL in D3D9 is supported. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = 0, + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = 0, + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), + //! but tries to load the programs from files. + virtual s32 addHighLevelShaderMaterialFromFiles( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), + //! but tries to load the programs from files. + virtual s32 addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + io::IReadFile* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! Writes the provided image to disk file + virtual bool writeImageToFile(IImage* image, const char* filename, u32 param = 0); + + //! Sets the name of a material renderer. + virtual void setMaterialRendererName(s32 idx, const char* name); + + //! Creates material attributes list from a material, usable for serialization and more. + virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material); + + //! Fills an SMaterial structure from attributes. + virtual void fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attributes); + + //! looks if the image is already loaded + virtual video::ITexture* findTexture(const c8* filename); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + protected: + + //! deletes all textures + void deleteAllTextures(); + + //! opens the file and loads it into the surface + video::ITexture* loadTextureFromFile(io::IReadFile* file, const c8* hashName = 0); + + //! adds a surface, not loaded or created by the Irrlicht Engine + void addTexture(video::ITexture* surface); + + //! Creates a texture from a loaded IImage. + virtual ITexture* addTexture(const c8* name, IImage* image); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name); + + //! checks triangle count and print warning if wrong + bool checkPrimitiveCount(u32 prmcnt) const; + + // adds a material renderer and drops it afterwards. To be used for internal creation + s32 addAndDropMaterialRenderer(IMaterialRenderer* m); + + //! deletes all material renderers + void deleteMaterialRenders(); + + // prints renderer version + void printVersion(); + + //! normal map lookup 32 bit version + inline f32 nml32(int x, int y, int pitch, int height, s32 *p) const + { + if (x < 0) x = pitch-1; if (x >= pitch) x = 0; + if (y < 0) y = height-1; if (y >= height) y = 0; + return (f32)(((p[(y * pitch) + x])>>16) & 0xff); + } + + //! normal map lookup 16 bit version + inline f32 nml16(int x, int y, int pitch, int height, s16 *p) const + { + if (x < 0) x = pitch-1; if (x >= pitch) x = 0; + if (y < 0) y = height-1; if (y >= height) y = 0; + + return (f32) getAverage ( p[(y * pitch) + x] ); + } + + struct SSurface + { + video::ITexture* Surface; + + bool operator < (const SSurface& other) const + { + return Surface->getName() < other.Surface->getName(); + } + }; + + struct SMaterialRenderer + { + core::stringc Name; + IMaterialRenderer* Renderer; + }; + + struct SDummyTexture : public ITexture + { + SDummyTexture(const char* name) : ITexture(name), size(0,0) {}; + + virtual void* lock() { return 0; }; + virtual void unlock(){} + virtual const core::dimension2d& getOriginalSize() const { return size; } + virtual const core::dimension2d& getSize() const { return size; } + virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; } + virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; }; + virtual u32 getPitch() const { return 0; } + virtual void regenerateMipMapLevels() {}; + core::dimension2d size; + }; + + core::array Textures; + core::array SurfaceLoader; + core::array SurfaceWriter; + core::array Lights; + core::array MaterialRenderers; + + io::IFileSystem* FileSystem; + + core::rect ViewPort; + core::dimension2d ScreenSize; + core::matrix4 TransformationMatrix; + + CFPSCounter FPSCounter; + + u32 PrimitivesDrawn; + + u32 TextureCreationFlags; + + bool LinearFog; + f32 FogStart; + f32 FogEnd; + f32 FogDensity; + bool PixelFog; + bool RangeFog; + SColor FogColor; + + SExposedVideoData ExposedData; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COBJMeshFileLoader.cpp b/src/dep/src/irrlicht/COBJMeshFileLoader.cpp new file mode 100644 index 0000000..6cc63c8 --- /dev/null +++ b/src/dep/src/irrlicht/COBJMeshFileLoader.cpp @@ -0,0 +1,778 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ + +#include "COBJMeshFileLoader.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "coreutil.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +COBJMeshFileLoader::COBJMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) +: FileSystem(fs), Driver(driver) +{ + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + + +//! destructor +COBJMeshFileLoader::~COBJMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COBJMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".obj")!=0; +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) +{ + const long filesize = file->getSize(); + if (!filesize) + return 0; + + const u32 WORD_BUFFER_LENGTH = 512; + + SMesh* mesh = new SMesh(); + + core::array vertexBuffer; + core::array textureCoordBuffer; + core::array normalsBuffer; + SObjMtl * currMtl = new SObjMtl(); + currMtl->name=""; + materials.push_back(currMtl); + u32 smoothingGroup=0; + + // ******************************************************************** + // Patch to locate the file in the same folder as the .obj. + // If you load the file as "data/some.obj" and mtllib contains + // "mtlname test.mtl" (as usual), the loading will fail. Instead it + // must look for data/test.tml. This patch does exactly that. + // + // patch by mandrav@codeblocks.org + // ******************************************************************** + core::stringc obj_fullname = file->getFileName(); + core::stringc obj_relpath = ""; + s32 pathend = obj_fullname.findLast('/'); + if (pathend == -1) + pathend = obj_fullname.findLast('\\'); + if (pathend != -1) + obj_relpath = obj_fullname.subString(0, pathend + 1); + // ******************************************************************** + // end of mtl folder patch + // ******************************************************************** + + c8* pBuf = new c8[filesize]; + memset(pBuf, 0, filesize); + file->read((void*)pBuf, filesize); + const c8* const pBufEnd = pBuf+filesize; + + // Process obj information + const c8* bufPtr = pBuf; + while(bufPtr != pBufEnd) + { + switch(bufPtr[0]) + { + case 'm': // mtllib (material) + { + c8 name[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(name, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + readMTL(name, obj_relpath); + } + break; + + case 'v': // v, vn, vt + switch(bufPtr[1]) + { + case ' ': // vertex + { + core::vector3df vec; + bufPtr = readVec3(bufPtr, vec, pBufEnd); + vertexBuffer.push_back(vec); + } + break; + + case 'n': // normal + { + core::vector3df vec; + bufPtr = readVec3(bufPtr, vec, pBufEnd); + normalsBuffer.push_back(vec); + } + break; + + case 't': // texcoord + { + core::vector2df vec; + bufPtr = readVec2(bufPtr, vec, pBufEnd); + textureCoordBuffer.push_back(vec); + } + break; + } + break; + + case 'g': // group names skipped + { + } + break; + + case 's': // smoothing can be a group or off (equiv. to 0) + { + c8 smooth[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(smooth, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (core::stringc("off")==smooth) + smoothingGroup=0; + else + smoothingGroup=core::strtol10(smooth, 0); + } + break; + + case 'u': // usemtl + // get name of material + { + c8 matName[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(matName, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + // retrieve the material + SObjMtl *pUseMtl = findMtl(matName); + // only change material if we found it + if (pUseMtl) + currMtl = pUseMtl; + } + break; + + case 'f': // face + { + c8 vertexWord[WORD_BUFFER_LENGTH]; // for retrieving vertex data + video::S3DVertex v; + u32 currentVertexCount = currMtl->Meshbuffer->Vertices.size(); + u32 facePointCount = 0; // number of vertices in this face + + // Assign vertex color from currently active material's diffuse colour + if (currMtl) + v.Color = currMtl->Meshbuffer->Material.DiffuseColor; + + // get all vertices data in this face (current line of obj file) + const core::stringc wordBuffer = copyLine(bufPtr, pBufEnd); + const c8* linePtr = wordBuffer.c_str(); + const c8* const endPtr = linePtr+wordBuffer.size(); + + // read in all vertices + linePtr = goNextWord(linePtr, endPtr); + while (0 != linePtr[0]) + { + // Array to communicate with retrieveVertexIndices() + // sends the buffer sizes and gets the actual indices + // if index not set returns -1 + s32 Idx[3]; + Idx[1] = Idx[2] = -1; + + // read in next vertex's data + u32 wlength = copyWord(vertexWord, linePtr, WORD_BUFFER_LENGTH, pBufEnd); + // this function will also convert obj's 1-based index to c++'s 0-based index + retrieveVertexIndices(vertexWord, Idx, vertexWord+wlength+1, vertexBuffer.size(), textureCoordBuffer.size(), normalsBuffer.size()); + v.Pos = vertexBuffer[Idx[0]]; + if ( -1 != Idx[1] ) + v.TCoords = textureCoordBuffer[Idx[1]]; + else + v.TCoords.set(0.0f,0.0f); + if ( -1 != Idx[2] ) + v.Normal = normalsBuffer[Idx[2]]; + else + v.Normal.set(0.0f,0.0f,0.0f); + currMtl->Meshbuffer->Vertices.push_back(v); + ++facePointCount; + + // go to next vertex + linePtr = goNextWord(linePtr, endPtr); + } + + // Add indices for first 3 vertices + currMtl->Meshbuffer->Indices.push_back( currentVertexCount ); + currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 1 ) + currentVertexCount ); + currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 2 ) + currentVertexCount ); + // Add indices for subsequent vertices + for ( u32 i = 0; i < facePointCount - 3; ++i ) + { + currMtl->Meshbuffer->Indices.push_back( currentVertexCount ); + currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 2 - i ) + currentVertexCount ); + currMtl->Meshbuffer->Indices.push_back( ( facePointCount - 3 - i ) + currentVertexCount ); + } + } + break; + + case '#': // comment + default: + break; + } // end switch(bufPtr[0]) + // eat up rest of line + bufPtr = goNextLine(bufPtr, pBufEnd); + } // end while(bufPtr && (bufPtr-pBufMeshbuffer->getIndexCount() > 0 ) + { + materials[m]->Meshbuffer->recalculateBoundingBox(); + mesh->addMeshBuffer( materials[m]->Meshbuffer ); + } + } + + // Create the Animated mesh if there's anything in the mesh + SAnimatedMesh* pAM = 0; + if ( 0 != mesh->getMeshBufferCount() ) + { + mesh->recalculateBoundingBox(); + pAM = new SAnimatedMesh(); + pAM->Type = EAMT_OBJ; + pAM->addMesh(mesh); + pAM->recalculateBoundingBox(); + } + + // Clean up the allocate obj file contents + delete [] pBuf; + // more cleaning up + cleanUp(); + mesh->drop(); + + return pAM; +} + + +void COBJMeshFileLoader::readMTL(const c8* pFileName, core::stringc relPath) +{ + const u32 WORD_BUFFER_LENGTH = 512; + + io::IReadFile * pMtlReader; + if (FileSystem->existFile(pFileName)) + pMtlReader = FileSystem->createAndOpenFile(pFileName); + else + // try to read in the relative path, the .obj is loaded from + pMtlReader = FileSystem->createAndOpenFile((relPath + pFileName).c_str()); + if (!pMtlReader) // fail to open and read file + return; + + const long filesize = pMtlReader->getSize(); + if (!filesize) + return; + + c8* pBuf = new c8[filesize]; + pMtlReader->read((void*)pBuf, filesize); + const c8* pBufEnd = pBuf+filesize; + + SObjMtl* pCurrMaterial = 0; + + const c8* bufPtr = pBuf; + while(bufPtr != pBufEnd) + { + switch(*bufPtr) + { + case 'n': // newmtl + { + // if there's an existing material, store it first + if ( pCurrMaterial ) + materials.push_back( pCurrMaterial ); + + // extract new material's name + c8 mtlNameBuf[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(mtlNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + + pCurrMaterial = new SObjMtl; + pCurrMaterial->name = mtlNameBuf; + } + break; + case 'i': // illum - illumination + if ( pCurrMaterial ) + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 illumStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(illumStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + pCurrMaterial->illumination = (c8)atol(illumStr); + } + break; + case 'N': // Ns - shininess + if ( pCurrMaterial ) + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 nsStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(nsStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + f32 shininessValue = core::fast_atof(nsStr); + + // wavefront shininess is from [0, 1000], so scale for OpenGL + shininessValue *= 0.128f; + pCurrMaterial->Meshbuffer->Material.Shininess = shininessValue; + } + break; + case 'K': + if ( pCurrMaterial ) + { + switch(bufPtr[1]) + { + case 'd': // Kd = diffuse + { + bufPtr = readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.DiffuseColor, pBufEnd); + + } + break; + + case 's': // Ks = specular + { + bufPtr = readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.SpecularColor, pBufEnd); + } + break; + + case 'a': // Ka = ambience + { + bufPtr=readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.AmbientColor, pBufEnd); + } + break; + case 'e': // Ke = emissive + { + bufPtr=readColor(bufPtr, pCurrMaterial->Meshbuffer->Material.EmissiveColor, pBufEnd); + } + break; + } // end switch(bufPtr[1]) + } // end case 'K': if ( 0 != pCurrMaterial )... + break; + case 'm': // texture maps + if (pCurrMaterial) + { + u8 type=0; // map_Kd - diffuse texture map + if (!strncmp(bufPtr,"map_bump",8)) + type=1; + else if (!strncmp(bufPtr,"map_d",5)) + type=2; + else if (!strncmp(bufPtr,"map_refl",8)) + type=3; + // extract new material's name + c8 textureNameBuf[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + // handle options + while (textureNameBuf[0]=='-') + { + if (!strncmp(bufPtr,"-blendu",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!strncmp(bufPtr,"-blendv",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!strncmp(bufPtr,"-cc",3)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!strncmp(bufPtr,"-clamp",6)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!strncmp(bufPtr,"-texres",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!strncmp(bufPtr,"-mm",3)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + } + if (!strncmp(bufPtr,"-o",2)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + if (!strncmp(bufPtr,"-s",2)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + if (!strncmp(bufPtr,"-t",2)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + // get next word + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + } + if (type==1) + { + pCurrMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf); + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + } + + video::ITexture * pTexture; + if (FileSystem->existFile(textureNameBuf)) + pTexture = Driver->getTexture( textureNameBuf ); + else + // try to read in the relative path, the .obj is loaded from + pTexture = Driver->getTexture( (relPath + textureNameBuf).c_str() ); + if ( pTexture ) + { + if (type==0) + pCurrMaterial->Meshbuffer->Material.setTexture(0, pTexture); + else if (type==1) + { + Driver->makeNormalMapTexture(pTexture); + pCurrMaterial->Meshbuffer->Material.setTexture(1, pTexture); + pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID; + } + else if (type==2) + { + pCurrMaterial->Meshbuffer->Material.setTexture(0, pTexture); + pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } + else if (type==3) + { +// pCurrMaterial->Meshbuffer->Material.Textures[1] = pTexture; +// pCurrMaterial->Meshbuffer->Material.MaterialType=video::EMT_REFLECTION_2_LAYER; + } + // Set diffuse material colour to white so as not to affect texture colour + // Because Maya set diffuse colour Kd to black when you use a diffuse colour map + // But is this the right thing to do? + pCurrMaterial->Meshbuffer->Material.DiffuseColor.set( + pCurrMaterial->Meshbuffer->Material.DiffuseColor.getAlpha(), 255, 255, 255 ); + } + } + break; + case 'd': // d - transparency + if ( pCurrMaterial ) + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 dStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(dStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + f32 dValue = core::fast_atof(dStr); + + pCurrMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(dValue * 255) ); + if (dValue<1.0f) + pCurrMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + break; + case 'T': + if ( pCurrMaterial ) + { + switch ( bufPtr[1] ) + { + case 'f': // Tf - Transmitivity + const u32 COLOR_BUFFER_LENGTH = 16; + c8 redStr[COLOR_BUFFER_LENGTH]; + c8 greenStr[COLOR_BUFFER_LENGTH]; + c8 blueStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(redStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + bufPtr = goAndCopyNextWord(greenStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + bufPtr = goAndCopyNextWord(blueStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + + f32 transparency = ( core::fast_atof(redStr) + core::fast_atof(greenStr) + core::fast_atof(blueStr) ) / 3; + + pCurrMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(transparency * 255) ); + if (transparency < 1.0f) + pCurrMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + } + break; + default: // comments or not recognised + break; + } // end switch(bufPtr[0]) + // go to next line + bufPtr = goNextLine(bufPtr, pBufEnd); + } // end while (bufPtr) + + // end of file. if there's an existing material, store it + if ( pCurrMaterial ) + { + materials.push_back( pCurrMaterial ); + pCurrMaterial = 0; + } + + delete [] pBuf; + pMtlReader->drop(); +} + +//! Read RGB color +const c8* COBJMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const c8* const pBufEnd) +{ + const u32 COLOR_BUFFER_LENGTH = 16; + c8 colStr[COLOR_BUFFER_LENGTH]; + + color.setAlpha(255); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + color.setRed((s32)(core::fast_atof(colStr) * 255.0f)); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + color.setGreen((s32)(core::fast_atof(colStr) * 255.0f)); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, pBufEnd); + color.setBlue((s32)(core::fast_atof(colStr) * 255.0f)); + return bufPtr; +} + + +//! Read 3d vector of floats +const c8* COBJMeshFileLoader::readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const pBufEnd) +{ + const u32 WORD_BUFFER_LENGTH = 256; + c8 wordBuffer[WORD_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + vec.X=-core::fast_atof(wordBuffer); // change handedness + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + vec.Y=core::fast_atof(wordBuffer); + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + vec.Z=core::fast_atof(wordBuffer); + return bufPtr; +} + + +//! Read 2d vector of floats +const c8* COBJMeshFileLoader::readVec2(const c8* bufPtr, core::vector2df& vec, const c8* const pBufEnd) +{ + const u32 WORD_BUFFER_LENGTH = 256; + c8 wordBuffer[WORD_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + vec.X=core::fast_atof(wordBuffer); + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, pBufEnd); + vec.Y=-core::fast_atof(wordBuffer); // change handedness + return bufPtr; +} + + +//! Read boolean value represented as 'on' or 'off' +const c8* COBJMeshFileLoader::readBool(const c8* bufPtr, bool& tf, const c8* const pBufEnd) +{ + const u32 BUFFER_LENGTH = 8; + c8 tfStr[BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(tfStr, bufPtr, BUFFER_LENGTH, pBufEnd); + tf = strcmp(tfStr, "off") != 0; + return bufPtr; +} + + +COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const c8* pMtlName) +{ + for (u32 i = 0; i < materials.size(); ++i) + { + if ( materials[i]->name == pMtlName ) + return materials[i]; + } + return 0; +} + + + +//! skip space characters and stop on first non-space +const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const pBufEnd) +{ + // skip space characters + while((buf != pBufEnd) && core::isspace(*buf)) + ++buf; + + return buf; +} + + +//! skip current word and stop at beginning of next one +const c8* COBJMeshFileLoader::goNextWord(const c8* buf, const c8* const pBufEnd) +{ + // skip current word + while(( buf != pBufEnd ) && !core::isspace(*buf)) + ++buf; + + return goFirstWord(buf, pBufEnd); +} + + +//! Read until line break is reached and stop at the next non-space character +const c8* COBJMeshFileLoader::goNextLine(const c8* buf, const c8* const pBufEnd) +{ + // look for newline characters + while(buf != pBufEnd) + { + // found it, so leave + if (*buf=='\n' || *buf=='\r') + break; + ++buf; + } + return goFirstWord(buf, pBufEnd); +} + + +u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLength, const c8* const pBufEnd) +{ + if (!outBufLength) + return 0; + if (!inBuf) + { + *outBuf = 0; + return 0; + } + + u32 i = 0; + while(inBuf[i]) + { + if (core::isspace(inBuf[i]) || &(inBuf[i]) == pBufEnd) + break; + ++i; + } + + u32 length = core::min_(i, outBufLength-1); + for (u32 j=0; j 2 ) + { + // error checking, shouldn't reach here unless file is wrong + idxType = 0; + } + } + else + { + // set all missing values to disable (=-1) + while (++idxType < 3) + pIdx[idxType]=-1; + ++pChar; + break; // while + } + } + + // go to the next char + ++pChar; + } + + return true; +} + + +void COBJMeshFileLoader::cleanUp() +{ + u32 i; + + for (i = 0; i < materials.size(); ++i ) + { + materials[i]->Meshbuffer->drop(); + delete materials[i]; + } + + materials.clear(); +} + + +} // end namespace scene +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_OBJ_LOADER_ diff --git a/src/dep/src/irrlicht/COBJMeshFileLoader.h b/src/dep/src/irrlicht/COBJMeshFileLoader.h new file mode 100644 index 0000000..6853eee --- /dev/null +++ b/src/dep/src/irrlicht/COBJMeshFileLoader.h @@ -0,0 +1,103 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading obj meshes. +class COBJMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + COBJMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver); + + //! destructor + virtual ~COBJMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".obj") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + struct SObjMtl + { + SObjMtl() : Meshbuffer(0), illumination(0) { + Meshbuffer = new SMeshBuffer(); + Meshbuffer->Material.Shininess = 0.0f; + Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor(); + Meshbuffer->Material.DiffuseColor = video::SColorf(0.8f, 0.8f, 0.8f, 1.0f).toSColor(); + Meshbuffer->Material.SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f).toSColor(); + } + + SObjMtl(SObjMtl& o) : Meshbuffer(o.Meshbuffer), name(o.name), illumination(o.illumination) { o.Meshbuffer->grab(); } + + scene::SMeshBuffer *Meshbuffer; + core::stringc name; + c8 illumination; + }; + + // returns a pointer to the first printable character available in the buffer + const c8* goFirstWord(const c8* buf, const c8* const pBufEnd); + // returns a pointer to the first printable character after the first non-printable + const c8* goNextWord(const c8* buf, const c8* const pBufEnd); + // returns a pointer to the next printable character after the first line break + const c8* goNextLine(const c8* buf, const c8* const pBufEnd); + // copies the current word from the inBuf to the outBuf + u32 copyWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); + // copies the current line from the inBuf to the outBuf + core::stringc copyLine(const c8* inBuf, const c8* const pBufEnd); + // combination of goNextWord followed by copyWord + const c8* goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); + + //! Read the material from the given file + void readMTL(const c8* pFileName, core::stringc relPath); + //! Find and return the material with the given name + SObjMtl * findMtl(const c8* pMtlName); + + //! Read RGB color + const c8* readColor(const c8* pBufPtr, video::SColor& color, const c8* const pBufEnd); + //! Read 3d vector of floats + const c8* readVec3(const c8* pBufPtr, core::vector3df& vec, const c8* const pBufEnd); + //! Read 2d vector of floats + const c8* readVec2(const c8* pBufPtr, core::vector2df& vec, const c8* const pBufEnd); + //! Read boolean value represented as 'on' or 'off' + const c8* readBool(const c8* pBufPtr, bool& tf, const c8* const pBufEnd); + + // reads and convert to integer the vertex indices in a line of obj file's face statement + // -1 for the index if it doesn't exist + // indices are changed to 0-based index instead of 1-based from the obj file + bool retrieveVertexIndices(c8* pVertexData, s32* Idx, const c8* pBufEnd, u32 vbsize, u32 vtsize, u32 vnsize); + + void cleanUp(); + + io::IFileSystem* FileSystem; + video::IVideoDriver* Driver; + + core::array materials; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/COCTLoader.cpp b/src/dep/src/irrlicht/COCTLoader.cpp new file mode 100644 index 0000000..145e8d6 --- /dev/null +++ b/src/dep/src/irrlicht/COCTLoader.cpp @@ -0,0 +1,375 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// originally written by Murphy McCauley, see COCTLoader.h for details. +// +// COCTLoader by Murphy McCauley (February 2005) +// An Irrlicht loader for OCT files +// +// See the header file for additional information including use and distribution rights. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OCT_LOADER_ + +#include "COCTLoader.h" +#include "ISceneManager.h" +#include "os.h" +#include "SAnimatedMesh.h" +#include "SMeshBufferLightMap.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +COCTLoader::COCTLoader(video::IVideoDriver* driver) +: Driver(driver) +{ + #ifdef _DEBUG + IReferenceCounted::setDebugName("COCTLoader"); + #endif + + if (Driver) + Driver->grab(); +} + + +//! destructor +COCTLoader::~COCTLoader() +{ + if (Driver) + Driver->drop(); +} + + + +// Doesn't really belong here, but it's jammed in for now. +void COCTLoader::OCTLoadLights(io::IReadFile* file, scene::ISceneManager * scene, scene::ISceneNode * parent, f32 radius, f32 intensityScale, bool rewind) +{ + if (rewind) + file->seek(0); + + octHeader header; + file->read(&header, sizeof(octHeader)); + + file->seek(sizeof(octVert)*header.numVerts, true); + file->seek(sizeof(octFace)*header.numFaces, true); + file->seek(sizeof(octTexture)*header.numTextures, true); + file->seek(sizeof(octLightmap)*header.numLightmaps, true); + + octLight * lights = new octLight[header.numLights]; + file->read(lights, header.numLights * sizeof(octLight)); + + //TODO: Skip past my extended data just for good form + + for (u32 i = 0; i < header.numLights; i++) + { + const f32 intensity = lights[i].intensity * intensityScale; + + scene->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]), + video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity, 1.0f), + radius); + } +} + + +//! given three points representing a face, return a face normal +core::vector3df COCTLoader::GetFaceNormal(f32 a[3], f32 b[3], f32 c[3]) { + return core::plane3df(core::vector3df(a[0],a[1],a[2]), core::vector3df(b[0],c[1],c[2]), core::vector3df(c[0],c[1],c[2])).Normal; +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + octHeader header; + file->read(&header, sizeof(octHeader)); + + octVert * verts = new octVert[header.numVerts]; + octFace * faces = new octFace[header.numFaces]; + octTexture * textures = new octTexture[header.numTextures]; + octLightmap * lightmaps = new octLightmap[header.numLightmaps]; + octLight * lights = new octLight[header.numLights]; + + file->read(verts, sizeof(octVert) * header.numVerts); + file->read(faces, sizeof(octFace) * header.numFaces); + //TODO: Make sure id is in the legal range for Textures and Lightmaps + + u32 i; + for (i = 0; i < header.numTextures; i++) { + octTexture t; + file->read(&t, sizeof(octTexture)); + textures[t.id] = t; + } + for (i = 0; i < header.numLightmaps; i++) { + octLightmap t; + file->read(&t, sizeof(octLightmap)); + lightmaps[t.id] = t; + } + file->read(lights, sizeof(octLight) * header.numLights); + + //TODO: Now read in my extended OCT header (flexible lightmaps and vertex normals) + + + // This is the method Nikolaus Gebhardt used in the Q3 loader -- create a + // meshbuffer for every possible combination of lightmap and texture including + // a "null" texture and "null" lightmap. Ones that end up with nothing in them + // will be removed later. + + SMesh * Mesh = new SMesh(); + for (i=0; i<(header.numTextures+1) * (header.numLightmaps+1); ++i) + { + scene::SMeshBufferLightMap* buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP; + buffer->Material.Lighting = false; + Mesh->addMeshBuffer(buffer); + buffer->drop(); + } + + + // Build the mesh buffers + for (i = 0; i < header.numFaces; i++) + { + if (faces[i].numVerts < 3) + continue; + + const core::vector3df normal = + GetFaceNormal(verts[faces[i].firstVert].pos, + verts[faces[i].firstVert+1].pos, + verts[faces[i].firstVert+2].pos); + + const u32 textureID = core::min_(s32(faces[i].textureID), s32(header.numTextures - 1)) + 1; + const u32 lightmapID = core::min_(s32(faces[i].lightmapID),s32(header.numLightmaps - 1)) + 1; + SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(lightmapID * (header.numTextures + 1) + textureID); + const u32 base = meshBuffer->Vertices.size(); + + // Add this face's verts + u32 v; + for (v = 0; v < faces[i].numVerts; ++v) + { + octVert * vv = &verts[faces[i].firstVert + v]; + video::S3DVertex2TCoords vert; + vert.Pos.set(vv->pos[0], vv->pos[1], vv->pos[2]); + vert.Color = video::SColor(0,255,255,255); + vert.Normal.set(normal); + + if (textureID == 0) + { + // No texture -- just a lightmap. Thus, use lightmap coords for texture 1. + // (the actual texture will be swapped later) + vert.TCoords.set(vv->lc[0], vv->lc[1]); + } + else + { + vert.TCoords.set(vv->tc[0], vv->tc[1]); + vert.TCoords2.set(vv->lc[0], vv->lc[1]); + } + + meshBuffer->Vertices.push_back(vert); + } + + // Now add the indices + // This weird loop turns convex polygons into triangle strips. + // I do it this way instead of a simple fan because it usually looks a lot better in wireframe, for example. + u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center + for (v = 0; v < faces[i].numVerts - 2; ++v) + { + if (v & 1) + c = h - 1; + else + c = l + 1; + + meshBuffer->Indices.push_back(base + h); + meshBuffer->Indices.push_back(base + l); + meshBuffer->Indices.push_back(base + c); + + if (v & 1) + --h; + else + ++l; + } + } + + + // load textures + core::array tex; + tex.set_used(header.numTextures + 1); + tex[0] = 0; + + for (i = 1; i < (header.numTextures + 1); i++) + { + tex[i] = Driver->getTexture(textures[i-1].fileName); + } + + + // prepare lightmaps + core::array lig; + lig.set_used(header.numLightmaps + 1); + + u32 lightmapWidth = 128, lightmapHeight = 128; + lig[0] = 0; + core::dimension2d lmapsize(lightmapWidth, lightmapHeight); + + bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + for (i = 1; i < (header.numLightmaps + 1); i++) + { + core::stringc lightmapname = file->getFileName(); + lightmapname += ".lightmap."; + lightmapname += (int)i; + lig[i] = Driver->addTexture(lmapsize, lightmapname.c_str()); + + if (lig[i]->getSize() != lmapsize) + os::Printer::log("OCTLoader: Created lightmap is not of the requested size", ELL_ERROR); + + if (lig[i]) + { + void* pp = lig[i]->lock(); + + if (pp) + { + video::ECOLOR_FORMAT format = lig[i]->getColorFormat(); + if (format == video::ECF_A1R5G5B5) + { + s16* p = (s16*)pp; + + octLightmap * lm; + lm = &lightmaps[i-1]; + + for (u32 x=0; xdata[x][y][2], + lm->data[x][y][1], + lm->data[x][y][0]); + } + } + else + if (format == video::ECF_A8R8G8B8) + { + s32* p = (s32*)pp; + + octLightmap* lm; + lm = &lightmaps[i-1]; + + for (u32 x=0; xdata[x][y][2], + lm->data[x][y][1], + lm->data[x][y][0]).color; + } + } + else + os::Printer::log( + "OCTLoader: Could not create lightmap, unsupported texture format.", ELL_ERROR); + } + + lig[i]->unlock(); + } + else + os::Printer::log("OCTLoader: Could not create lightmap, driver created no texture.", ELL_ERROR); + } + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + + // Free stuff + delete [] verts; + delete [] faces; + delete [] textures; + delete [] lightmaps; + delete [] lights; + + + // attach materials + for (i = 0; i < header.numLightmaps + 1; i++) + { + for (u32 j = 0; j < header.numTextures + 1; j++) + { + u32 mb = i * (header.numTextures + 1) + j; + SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(mb); + meshBuffer->Material.setTexture(0, tex[j]); + meshBuffer->Material.setTexture(1, lig[i]); + + if (meshBuffer->Material.getTexture(0) == 0) + { + // This material has no texture, so we'll just show the lightmap if there is one. + // We swapped the texture coordinates earlier. + meshBuffer->Material.setTexture(0, meshBuffer->Material.getTexture(1)); + meshBuffer->Material.setTexture(1, 0); + } + if (meshBuffer->Material.getTexture(1) == 0) + { + // If there is only one texture, it should be solid and lit. + // Among other things, this way you can preview OCT lights. + meshBuffer->Material.MaterialType = video::EMT_SOLID; + meshBuffer->Material.Lighting = true; + } + } + } + + + // delete all buffers without geometry in it. + i = 0; + while(i < Mesh->MeshBuffers.size()) + { + if (Mesh->MeshBuffers[i]->getVertexCount() == 0 || + Mesh->MeshBuffers[i]->getIndexCount() == 0 || + Mesh->MeshBuffers[i]->getMaterial().getTexture(0) == 0) + { + // Meshbuffer is empty -- drop it + Mesh->MeshBuffers[i]->drop(); + Mesh->MeshBuffers.erase(i); + } + else + { + ++i; + } + } + + + // create bounding box + for (i = 0; i < Mesh->MeshBuffers.size(); ++i) + { + Mesh->MeshBuffers[i]->recalculateBoundingBox(); + } + Mesh->recalculateBoundingBox(); + + + // Set up an animated mesh to hold the mesh + SAnimatedMesh* AMesh = new SAnimatedMesh(); + AMesh->Type = EAMT_OCT; + AMesh->addMesh(Mesh); + AMesh->recalculateBoundingBox(); + Mesh->drop(); + + return AMesh; +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COCTLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".oct")!=0; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OCT_LOADER_ + diff --git a/src/dep/src/irrlicht/COCTLoader.h b/src/dep/src/irrlicht/COCTLoader.h new file mode 100644 index 0000000..4b50436 --- /dev/null +++ b/src/dep/src/irrlicht/COCTLoader.h @@ -0,0 +1,136 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// Because I (Nikolaus Gebhardt) did some changes to Murphy McCauley's loader, +// I'm writing this down here: +// - Replaced all dependencies to STL and stdio with irr:: methods/constructs +// - Disabled logging define +// - Changed some minor things (Don't remember what exactly.) +// Thanks a lot to Murphy McCauley for writing this loader. + +// +// COCTLoader by Murphy McCauley (February 2005) +// An Irrlicht loader for OCT files +// +// OCT file format information comes from the sourcecode of the Fluid Studios +// Radiosity Processor by Paul Nettle. You can get that sourcecode from +// http://www.fluidstudios.com . +// +// Parts of this code are from Irrlicht's CQ3LevelMesh and C3DSMeshFileLoader, +// and are Copyright (C) 2002-2004 Nikolaus Gebhardt. +// +// Use of this code is subject to the following: +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, 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 notice may not be removed or altered from any source distribution. +// 4. You may not use this software to directly or indirectly cause harm to others. + + +#ifndef __C_OCT_LOADER_H_INCLUDED__ +#define __C_OCT_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IReadFile.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "irrString.h" + +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + + class COCTLoader : public IMeshLoader + { + public: + void OCTLoadLights(io::IReadFile* file, ISceneManager * scene, ISceneNode * parent = 0, f32 radius = 500.0f, f32 intensityScale = 0.0000001f*2.5, bool rewind = true); + + //! constructor + COCTLoader(video::IVideoDriver* driver); + + //! destructor + virtual ~COCTLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + private: + core::vector3df GetFaceNormal(f32 a[3], f32 b[3], f32 c[3]); + + struct octHeader { + u32 numVerts; + u32 numFaces; + u32 numTextures; + u32 numLightmaps; + u32 numLights; + }; + + struct octHeaderEx { + u32 magic; // 'OCTX' - 0x4F435458L + u32 numLightmaps; + u32 lightmapWidth; + u32 lightmapHeight; + u32 containsVertexNormals; + }; + + struct octFace { + u32 firstVert; + u32 numVerts; + u32 textureID; + u32 lightmapID; + f32 plane[4]; + }; + + struct octVert { + f32 tc[2]; + f32 lc[2]; + f32 pos[3]; + }; + + struct octTexture { + u32 id; + char fileName[64]; + }; + + struct octLightmap { + u32 id; + u8 data[128][128][3]; + }; + + struct octLight { + f32 pos[3]; + f32 color[3]; + u32 intensity; + }; + + video::IVideoDriver* Driver; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/COSOperator.cpp b/src/dep/src/irrlicht/COSOperator.cpp new file mode 100644 index 0000000..4f0e347 --- /dev/null +++ b/src/dep/src/irrlicht/COSOperator.cpp @@ -0,0 +1,183 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COSOperator.h" +#include "IrrCompileConfig.h" + +#ifdef _IRR_WINDOWS_API_ +#include +#else +#include +#include +#ifdef MACOSX +#include "OSXClipboard.h" +#include +#include +#endif +#endif + +namespace irr +{ + + +// constructor +COSOperator::COSOperator(const c8* osVersion) : OperatingSystem(osVersion) +{ } + + +//! returns the current operating system version as string. +const wchar_t* COSOperator::getOperationSystemVersion() const +{ + return OperatingSystem.c_str(); +} + + +//! copies text to the clipboard +void COSOperator::copyToClipboard(const c8* text) const +{ + if (strlen(text)==0) + return; + +// Windows version +#if defined(_IRR_WINDOWS_API_) + if (!OpenClipboard(NULL) || text == 0) + return; + + EmptyClipboard(); + + HGLOBAL clipbuffer; + char * buffer; + + clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1); + buffer = (char*)GlobalLock(clipbuffer); + + strcpy(buffer, text); + + GlobalUnlock(clipbuffer); + SetClipboardData(CF_TEXT, clipbuffer); + CloseClipboard(); + +// MacOSX version +#elif defined(MACOSX) + + OSXCopyToClipboard(text); + +// todo: Linux version +#endif +} + + +//! gets text from the clipboard +//! \return Returns 0 if no string is in there. +c8* COSOperator::getTextFromClipboard() const +{ +#if defined(_IRR_WINDOWS_API_) + if (!OpenClipboard(NULL)) + return 0; + + char * buffer = 0; + + HANDLE hData = GetClipboardData( CF_TEXT ); + buffer = (char*)GlobalLock( hData ); + GlobalUnlock( hData ); + CloseClipboard(); + return buffer; + +#elif defined(MACOSX) + return (OSXCopyFromClipboard()); +#else + +// todo: Linux version + + return 0; +#endif +} + + +bool COSOperator::getProcessorSpeedMHz(u32* MHz) const +{ +#if defined(_IRR_WINDOWS_API_) + LONG Error; + + HKEY Key; + Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + 0, KEY_READ, &Key); + + if(Error != ERROR_SUCCESS) + return false; + + DWORD Speed = 0; + DWORD Size = sizeof(Speed); + Error = RegQueryValueEx(Key, "~MHz", NULL, NULL, (LPBYTE)&Speed, &Size); + + RegCloseKey(Key); + + if (Error != ERROR_SUCCESS) + return false; + else if (MHz) + *MHz = Speed; + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + +#elif defined(MACOSX) + struct clockinfo CpuClock; + size_t Size = sizeof(clockinfo); + + if (!sysctlbyname("kern.clockrate", &CpuClock, &Size, NULL, 0)) + return false; + else if (MHz) + *MHz = CpuClock.hz; + return true; +#else + // could probably be read from "/proc/cpuinfo" or "/proc/cpufreq" + + return false; +#endif +} + +bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const +{ +#if defined(_IRR_WINDOWS_API_) + MEMORYSTATUS MemoryStatus; + MemoryStatus.dwLength = sizeof(MEMORYSTATUS); + + // cannot fail + GlobalMemoryStatus(&MemoryStatus); + + if (Total) + *Total = (u32)(MemoryStatus.dwTotalPhys>>10); + if (Avail) + *Avail = (u32)(MemoryStatus.dwAvailPhys>>10); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + +#elif defined(_IRR_POSIX_API_) +#if defined(_SC_PHYS_PAGES) && defined(_SC_AVPHYS_PAGES) + long ps = sysconf(_SC_PAGESIZE); + long pp = sysconf(_SC_PHYS_PAGES); + long ap = sysconf(_SC_AVPHYS_PAGES); + + if ((ps==-1)||(pp==-1)||(ap==-1)) + return false; + + if (Total) + *Total = ((ps*(long long)pp)>>10); + if (Avail) + *Avail = ((ps*(long long)ap)>>10); + return true; +#else + // TODO: implement for non-availablity of symbols/features + return false; +#endif +#else + // TODO: implement for OSX + return false; +#endif +} + + +} // end namespace + diff --git a/src/dep/src/irrlicht/COSOperator.h b/src/dep/src/irrlicht/COSOperator.h new file mode 100644 index 0000000..04cb00c --- /dev/null +++ b/src/dep/src/irrlicht/COSOperator.h @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OS_OPERATOR_H_INCLUDED__ +#define __C_OS_OPERATOR_H_INCLUDED__ + +#include "IOSOperator.h" +#include "irrString.h" + +namespace irr +{ + +//! The Operating system operator provides operation system specific methods and informations. +class COSOperator : public IOSOperator +{ +public: + + // constructor + COSOperator(const c8* osversion); + + //! returns the current operation system version as string. + virtual const wchar_t* getOperationSystemVersion() const; + + //! copies text to the clipboard + virtual void copyToClipboard(const c8* text) const; + + //! gets text from the clipboard + //! \return Returns 0 if no string is in there. + virtual c8* getTextFromClipboard() const; + + //! gets the processor speed in megahertz + //! \param Mhz: + //! \return Returns true if successful, false if not + virtual bool getProcessorSpeedMHz(u32* MHz) const; + + //! gets the total and available system RAM in kB + //! \param Total: will contain the total system memory + //! \param Avail: will contain the available memory + //! \return Returns true if successful, false if not + virtual bool getSystemMemory(u32* Total, u32* Avail) const; + +private: + + core::stringw OperatingSystem; +}; + +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/COctTreeSceneNode.cpp b/src/dep/src/irrlicht/COctTreeSceneNode.cpp new file mode 100644 index 0000000..2490782 --- /dev/null +++ b/src/dep/src/irrlicht/COctTreeSceneNode.cpp @@ -0,0 +1,421 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COctTreeSceneNode.h" +#include "OctTree.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMaterialRenderer.h" + +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +COctTreeSceneNode::COctTreeSceneNode(ISceneNode* parent, ISceneManager* mgr, + s32 id, s32 minimalPolysPerNode) +: ISceneNode(parent, mgr, id), StdOctTree(0), LightMapOctTree(0), + MinimalPolysPerNode(minimalPolysPerNode) + //,Mesh(0) +{ +#ifdef _DEBUG + setDebugName("COctTreeSceneNode"); +#endif + + vertexType = (video::E_VERTEX_TYPE)-1; +} + + + +//! destructor +COctTreeSceneNode::~COctTreeSceneNode() +{ + //if (Mesh) + // Mesh->drop(); + + deleteTree(); +} + + + +void COctTreeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + int transparentCount = 0; + int solidCount = 0; + + // count transparent and solid materials in this scene node + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + } +} + + + +//! renders the node. +void COctTreeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (vertexType == -1 || !driver) + return; + + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + if (!camera) + return; + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + ++PassCount; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + SViewFrustum frust = *camera->getViewFrustum(); + + //transform the frustum to the current absolute transformation + core::matrix4 invTrans(AbsoluteTransformation); + invTrans.makeInverse(); + /* + //frust.transform(invTrans); + //const core::aabbox3d &box = frust.getBoundingBox(); + */ + + frust.transform(invTrans); + + switch(vertexType) + { + case video::EVT_STANDARD: + { + //StdOctTree->calculatePolys(box); + StdOctTree->calculatePolys(frust); + + OctTree::SIndexData* d = StdOctTree->getIndexData(); + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(Materials[i]); + driver->drawIndexedTriangleList( + &StdMeshes[i].Vertices[0], StdMeshes[i].Vertices.size(), + d[i].Indices, d[i].CurrentSize / 3); + } + } + + // for debug purposes only + if ( DebugDataVisible && !Materials.empty() && PassCount==1) + { + const core::aabbox3d &box = frust.getBoundingBox(); + core::array< core::aabbox3d > boxes; + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + StdOctTree->renderBoundingBoxes(box, boxes); + for (u32 b=0; bdraw3DBox(boxes[b], video::SColor(0,255,255,255)); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box,video::SColor(0,255,0,0)); + } + break; + + } + case video::EVT_2TCOORDS: + { + //LightMapOctTree->calculatePolys(box); + LightMapOctTree->calculatePolys(frust); + + OctTree::SIndexData* d = LightMapOctTree->getIndexData(); + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(Materials[i]); + driver->drawIndexedTriangleList( + &LightMapMeshes[i].Vertices[0], LightMapMeshes[i].Vertices.size(), + d[i].Indices, d[i].CurrentSize / 3); + } + } + + // for debug purposes only + if (DebugDataVisible && !Materials.empty() && PassCount==1) + { + const core::aabbox3d &box = frust.getBoundingBox(); + core::array< core::aabbox3d > boxes; + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + LightMapOctTree->renderBoundingBoxes(box, boxes); + for (u32 b=0; bdraw3DBox(boxes[b], video::SColor(0,255,255,255)); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box,video::SColor(0,255,0,0)); + } + } + break; + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& COctTreeSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! creates the tree +bool COctTreeSceneNode::createTree(IMesh* mesh) +{ + if (!mesh) + return false; + + //if (Mesh) +// Mesh->drop(); + + MeshName = SceneManager->getMeshCache()->getMeshFilename( mesh ); +// Mesh = mesh; +// Mesh->grab(); + + deleteTree(); + + u32 beginTime = os::Timer::getRealTime(); + + u32 nodeCount = 0; + u32 polyCount = 0; + + Box = mesh->getBoundingBox(); + + if (mesh->getMeshBufferCount()) + { + vertexType = mesh->getMeshBuffer(0)->getVertexType(); + + switch(vertexType) + { + case video::EVT_STANDARD: + { + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* b = mesh->getMeshBuffer(i); + if (b->getVertexCount() && b->getIndexCount()) + { + Materials.push_back(b->getMaterial()); + + OctTree::SMeshChunk chunk; + chunk.MaterialId = Materials.size() - 1; + StdMeshes.push_back(chunk); + OctTree::SMeshChunk &nchunk = StdMeshes[StdMeshes.size()-1]; + + u32 v; + + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + + polyCount += b->getIndexCount(); + + for (v=0; vgetIndexCount(); ++v) + nchunk.Indices.push_back(b->getIndices()[v]); + } + } + + StdOctTree = new OctTree(StdMeshes, MinimalPolysPerNode); + nodeCount = StdOctTree->nodeCount; + } + break; + case video::EVT_2TCOORDS: + { + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* b = mesh->getMeshBuffer(i); + + if (b->getVertexCount() && b->getIndexCount()) + { + Materials.push_back(b->getMaterial()); + + OctTree::SMeshChunk chunk; + chunk.MaterialId = Materials.size() - 1; + LightMapMeshes.push_back(chunk); + OctTree::SMeshChunk& nchunk = + LightMapMeshes[LightMapMeshes.size()-1]; + + u32 v; + + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + + polyCount += b->getIndexCount(); + + for (v=0; vgetIndexCount(); ++v) + nchunk.Indices.push_back(b->getIndices()[v]); + } + } + + LightMapOctTree = new OctTree(LightMapMeshes, MinimalPolysPerNode); + nodeCount = LightMapOctTree->nodeCount; + } + break; + } + } + + u32 endTime = os::Timer::getRealTime(); + c8 tmp[255]; + sprintf(tmp, "Needed %ums to create OctTree SceneNode.(%u nodes, %u polys)", + endTime - beginTime, nodeCount, polyCount/3); + os::Printer::log(tmp, ELL_INFORMATION); + + return true; +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& COctTreeSceneNode::getMaterial(u32 i) +{ + if ( i >= Materials.size() ) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + +//! returns amount of materials used by this scene node. +u32 COctTreeSceneNode::getMaterialCount() const +{ + return Materials.size(); +} + + +//! Writes attributes of the scene node. +void COctTreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addInt ("MinimalPolysPerNode", MinimalPolysPerNode); + //out->addString("Mesh", SceneManager->getMeshCache()->getMeshFilename(Mesh)); + out->addString("Mesh", MeshName.c_str()); +} + +//! Reads attributes of the scene node. +void COctTreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + int oldMinimal = MinimalPolysPerNode; + //core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh); + core::stringc oldMeshStr = MeshName; + + MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode"); + core::stringc newMeshStr = in->getAttributeAsString("Mesh"); + + bool loadedNewMesh = false; + + IMesh* newMesh = 0; + + if (newMeshStr != "" && oldMeshStr != newMeshStr) + { + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + newMesh = newAnimatedMesh->getMesh(0); + + if (newMesh) + { + // if (Mesh) + // Mesh->drop(); + + // Mesh = newMesh; + // Mesh->grab(); + + loadedNewMesh = true; + } + } + + if (loadedNewMesh || MinimalPolysPerNode != oldMinimal) + { + // recalculate tree + //createTree(Mesh); + createTree ( newMesh ); + // newMesh->drop (); + } + + ISceneNode::deserializeAttributes(in, options); +} + + +void COctTreeSceneNode::deleteTree() +{ + delete StdOctTree; + StdOctTree = 0; + StdMeshes.clear(); + + delete LightMapOctTree; + LightMapOctTree = 0; + LightMapMeshes.clear(); + + Materials.clear(); +} + +} // end namespace scene +} // end namespace irr diff --git a/src/dep/src/irrlicht/COctTreeSceneNode.h b/src/dep/src/irrlicht/COctTreeSceneNode.h new file mode 100644 index 0000000..87f6718 --- /dev/null +++ b/src/dep/src/irrlicht/COctTreeSceneNode.h @@ -0,0 +1,83 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCT_TREE_SCENE_NODE_H_INCLUDED__ +#define __C_OCT_TREE_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IMesh.h" +#include "OctTree.h" + +namespace irr +{ +namespace scene +{ + //! implementation of the IBspTreeSceneNode + class COctTreeSceneNode : public ISceneNode + { + public: + + //! constructor + COctTreeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + s32 minimalPolysPerNode=128); + + //! destructor + virtual ~COctTreeSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! creates the tree + bool createTree(IMesh* mesh); + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_OCT_TREE; } + + private: + + void deleteTree(); + + core::aabbox3d Box; + + OctTree* StdOctTree; + core::array< OctTree::SMeshChunk > StdMeshes; + + OctTree* LightMapOctTree; + core::array< OctTree::SMeshChunk > LightMapMeshes; + + video::E_VERTEX_TYPE vertexType; + core::array< video::SMaterial > Materials; + + //IMesh* Mesh; + core::stringc MeshName; + s32 MinimalPolysPerNode; + s32 PassCount; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/COctTreeTriangleSelector.cpp b/src/dep/src/irrlicht/COctTreeTriangleSelector.cpp new file mode 100644 index 0000000..1e75c45 --- /dev/null +++ b/src/dep/src/irrlicht/COctTreeTriangleSelector.cpp @@ -0,0 +1,192 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COctTreeTriangleSelector.h" +#include "ISceneNode.h" + +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +COctTreeTriangleSelector::COctTreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode) + : CTriangleSelector(mesh, node), Root(0), NodeCount(0), + MinimalPolysPerNode(minimalPolysPerNode) +{ + #ifdef _DEBUG + setDebugName("COctTreeTriangleSelector"); + #endif + + if (!Triangles.empty()) + { + u32 start = os::Timer::getRealTime(); + + // create the triangle octtree + Root = new SOctTreeNode(); + Root->Triangles = Triangles; + constructOctTree(Root); + + u32 end = os::Timer::getRealTime(); + c8 tmp[255]; + sprintf(tmp, "Needed %ums to create OctTreeTriangleSelector.(%d nodes, %u polys)", + end - start, NodeCount, Triangles.size()); + os::Printer::log(tmp, ELL_INFORMATION); + } +} + + +//! destructor +COctTreeTriangleSelector::~COctTreeTriangleSelector() +{ + delete Root; +} + + +void COctTreeTriangleSelector::constructOctTree(SOctTreeNode* node) +{ + ++NodeCount; + + node->Box.reset(node->Triangles[0].pointA); + + // get bounding box + const u32 cnt = node->Triangles.size(); + for (u32 i=0; iBox.addInternalPoint(node->Triangles[i].pointA); + node->Box.addInternalPoint(node->Triangles[i].pointB); + node->Box.addInternalPoint(node->Triangles[i].pointC); + } + + const core::vector3df& middle = node->Box.getCenter(); + core::vector3df edges[8]; + node->Box.getEdges(edges); + + core::aabbox3d box; + core::array keepTriangles; + + // calculate children + + if (!node->Box.isEmpty() && (s32)node->Triangles.size() > MinimalPolysPerNode) + for (s32 ch=0; ch<8; ++ch) + { + box.reset(middle); + box.addInternalPoint(edges[ch]); + node->Child[ch] = new SOctTreeNode(); + + for (s32 i=0; i<(s32)node->Triangles.size(); ++i) + { + if (node->Triangles[i].isTotalInsideBox(box)) + { + node->Child[ch]->Triangles.push_back(node->Triangles[i]); + //node->Triangles.erase(i); + //--i; + } + else + { + keepTriangles.push_back(node->Triangles[i]); + } + } + memcpy(node->Triangles.pointer(), keepTriangles.pointer(), + sizeof(core::triangle3df)*keepTriangles.size()); + + node->Triangles.set_used(keepTriangles.size()); + keepTriangles.set_used(0); + + if (node->Child[ch]->Triangles.empty()) + { + delete node->Child[ch]; + node->Child[ch] = 0; + } + else + constructOctTree(node->Child[ch]); + } +} + + + +//! Gets all triangles which lie within a specific bounding box. +void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, + const core::matrix4* transform) const +{ + core::matrix4 mat; + core::aabbox3d invbox = box; + + if (SceneNode) + { + mat = SceneNode->getAbsoluteTransformation(); + mat.makeInverse(); + mat.transformBox(invbox); + } + + mat.makeIdentity(); + + if (transform) + mat = *transform; + + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + s32 trianglesWritten = 0; + + if (Root) + getTrianglesFromOctTree(Root, trianglesWritten, + arraySize, invbox, &mat, triangles); + + outTriangleCount = trianglesWritten; +} + + +void COctTreeTriangleSelector::getTrianglesFromOctTree( + SOctTreeNode* node, s32& trianglesWritten, + s32 maximumSize, const core::aabbox3d& box, + const core::matrix4* mat, core::triangle3df* triangles) const +{ + if (!box.intersectsWithBox(node->Box)) + return; + + s32 cnt = node->Triangles.size(); + if (cnt + trianglesWritten > maximumSize) + cnt -= cnt + trianglesWritten - maximumSize; + + s32 i; + + for (i=0; iTriangles[i]; + mat->transformVect(triangles[trianglesWritten].pointA); + mat->transformVect(triangles[trianglesWritten].pointB); + mat->transformVect(triangles[trianglesWritten].pointC); + ++trianglesWritten; + } + + for (i=0; i<8; ++i) + if (node->Child[i]) + getTrianglesFromOctTree(node->Child[i], trianglesWritten, + maximumSize, box, mat, triangles); +} + + +//! Gets all triangles which have or may have contact with a 3d line. +void COctTreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform) const +{ + core::aabbox3d box(line.start); + box.addInternalPoint(line.end); + + // TODO: Could be optimized for line a little bit more. + COctTreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, + box, transform); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/COctTreeTriangleSelector.h b/src/dep/src/irrlicht/COctTreeTriangleSelector.h new file mode 100644 index 0000000..42f5954 --- /dev/null +++ b/src/dep/src/irrlicht/COctTreeTriangleSelector.h @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCT_TREE_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_OCT_TREE_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "CTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +class ISceneNode; + +//! Stupid triangle selector without optimization +class COctTreeTriangleSelector : public CTriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + COctTreeTriangleSelector(IMesh* mesh, ISceneNode* node, s32 minimalPolysPerNode); + + ~COctTreeTriangleSelector(); + + //! Gets all triangles which lie within a specific bounding box. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + +private: + + struct SOctTreeNode + { + SOctTreeNode() + { + for (s32 i=0; i<8; ++i) + Child[i] = 0; + } + + ~SOctTreeNode() + { + for (s32 i=0; i<8; ++i) + delete Child[i]; + } + + core::array Triangles; + SOctTreeNode* Child[8]; + core::aabbox3d Box; + }; + + + void constructOctTree(SOctTreeNode* node); + void deleteEmptyNodes(SOctTreeNode* node); + void getTrianglesFromOctTree(SOctTreeNode* node, s32& trianglesWritten, s32 maximumSize, + const core::aabbox3d& box, const core::matrix4* transform, + core::triangle3df* triangles) const; + + SOctTreeNode* Root; + s32 NodeCount; + s32 MinimalPolysPerNode; + +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COgreMeshFileLoader.cpp b/src/dep/src/irrlicht/COgreMeshFileLoader.cpp new file mode 100644 index 0000000..1933672 --- /dev/null +++ b/src/dep/src/irrlicht/COgreMeshFileLoader.cpp @@ -0,0 +1,1038 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// orginally written by Christian Stehno, modified by Nikolaus Gebhardt + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ + +#include "COgreMeshFileLoader.h" +#include "os.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "coreutil.h" + +namespace irr +{ +namespace scene +{ + +// Main Chunks +const u16 COGRE_HEADER= 0x1000; +const u16 COGRE_MESH= 0x3000; + +// sub chunks of COGRE_MESH +const u16 COGRE_SUBMESH= 0x4000; +const u16 COGRE_GEOMETRY= 0x5000; +const u16 COGRE_SKELETON_LINK= 0x6000; +const u16 COGRE_BONE_ASSIGNMENT= 0x7000; +const u16 COGRE_MESH_LOD= 0x8000; +const u16 COGRE_MESH_BOUNDS= 0x9000; +const u16 COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000; +const u16 COGRE_MESH_EDGE_LISTS= 0xB000; + +// sub chunks of COGRE_GEOMETRY +const u16 COGRE_GEOMETRY_VERTEX_DECLARATION= 0x5100; +const u16 COGRE_GEOMETRY_VERTEX_ELEMENT= 0x5110; +const u16 COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200; +const u16 COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210; + +// sub chunks of COGRE_SUBMESH +const u16 COGRE_SUBMESH_OPERATION= 0x4010; +const u16 COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100; +const u16 COGRE_SUBMESH_TEXTURE_ALIAS= 0x4200; + +//! Constructor +COgreMeshFileLoader::COgreMeshFileLoader(IMeshManipulator* manip,io::IFileSystem* fs, video::IVideoDriver* driver) +: FileSystem(fs), Driver(driver), SwapEndian(false), Mesh(0), Manipulator(manip), NumUV(0) +{ + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + + +//! destructor +COgreMeshFileLoader::~COgreMeshFileLoader() +{ + clearMeshes(); + + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); + + if (Mesh) + Mesh->drop(); +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COgreMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".mesh")!=0; +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file) +{ + s16 id; + + file->read(&id, 2); + + if (id == COGRE_HEADER) + SwapEndian=false; + else if (id == 0x0010) + SwapEndian=true; + else + return 0; + ChunkData data; + readString(file, data, Version); + if ((Version != "[MeshSerializer_v1.30]") && (Version != "[MeshSerializer_v1.40]")) + return 0; + + clearMeshes(); + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + setCurrentlyLoadingPath(file); + loadMaterials(file); + + if (readChunk(file)) + { + // success + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + + for (u32 i=0; igetMeshBufferCount(); ++i) + ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox(); + + Mesh->recalculateBoundingBox(); + + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + return am; + } + + Mesh->drop(); + Mesh = 0; + + return 0; +} + + +bool COgreMeshFileLoader::readChunk(io::IReadFile* file) +{ + while(file->getPos() < file->getSize()) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_MESH: + { + Meshes.push_back(OgreMesh()); + readObjectChunk(file, data, Meshes.getLast()); + composeObject(); + } + break; + default: + return true; + } + } + + return true; +} + + +bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh) +{ + readBool(file, parent, mesh.SkeletalAnimation); + while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize())) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY: + { + readGeometry(file, data, mesh.Geometry); + } + break; + case COGRE_SUBMESH: + mesh.SubMeshes.push_back(OgreSubMesh()); + readSubMesh(file, data, mesh.SubMeshes.getLast()); + break; + case COGRE_MESH_BOUNDS: + { + readVector(file, data, mesh.BBoxMinEdge); + readVector(file, data, mesh.BBoxMaxEdge); + readFloat(file, data, mesh.BBoxRadius); + } + break; + case COGRE_SKELETON_LINK: + case COGRE_BONE_ASSIGNMENT: + case COGRE_MESH_LOD: + case COGRE_MESH_SUBMESH_NAME_TABLE: + case COGRE_MESH_EDGE_LISTS: + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + break; + default: + parent.read=parent.header.length; + file->seek(-(long)sizeof(ChunkHeader), true); + return true; + } + parent.read += data.read; + } + return true; +} + + +bool COgreMeshFileLoader::readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ + readInt(file, parent, geometry.NumVertex); + while(parent.read < parent.header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY_VERTEX_DECLARATION: + readVertexDeclaration(file, data, geometry); + break; + case COGRE_GEOMETRY_VERTEX_BUFFER: + readVertexBuffer(file, data, geometry); + break; + default: + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + } + parent.read += data.read; + } + return true; +} + + +bool COgreMeshFileLoader::readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ + NumUV = 0; + while(parent.read < parent.header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY_VERTEX_ELEMENT: + { + OgreVertexElement elem; + readShort(file, data, elem.Source); + readShort(file, data, elem.Type); + readShort(file, data, elem.Semantic); + if (elem.Semantic == 7) //Tex coords + { + ++NumUV; + } + readShort(file, data, elem.Offset); + elem.Offset /= sizeof(f32); + readShort(file, data, elem.Index); + geometry.Elements.push_back(elem); + } + break; + default: + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + } + parent.read += data.read; + } + return true; +} + + +bool COgreMeshFileLoader::readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ + OgreVertexBuffer buf; + readShort(file, parent, buf.BindIndex); + readShort(file, parent, buf.VertexSize); + buf.VertexSize /= sizeof(f32); + ChunkData data; + readChunkData(file, data); + + if (data.header.id == COGRE_GEOMETRY_VERTEX_BUFFER_DATA) + { + buf.Data = new f32[geometry.NumVertex*buf.VertexSize]; + for (s32 i=0; iseek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + break; + default: + parent.read=parent.header.length; + file->seek(-(long)sizeof(ChunkHeader), true); + return true; + } + parent.read += data.read; + } + return true; +} + + + +void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName) +{ + video::SMaterial& material=mb->getMaterial(); + for (u32 k=0; kgetTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename.c_str())); + if (!material.getTexture(0)) + { + // retry with relative path + core::stringc relative = Materials[k].Techniques[0].Passes[0].Texture.Filename; + s32 idx = relative.findLast('\\'); + if (idx != -1) + relative = relative.subString(idx+1, relative.size()-idx-1); + idx = relative.findLast('/'); + if (idx != -1) + relative = relative.subString(idx+1, relative.size()-idx-1); + material.setTexture(0, Driver->getTexture((CurrentlyLoadingFromPath+"/"+relative).c_str())); + } + } + break; + } + } +} + + + +scene::SMeshBuffer* COgreMeshFileLoader::composeMeshBuffer(const core::array& indices, const OgreGeometry& geom) +{ + scene::SMeshBuffer *mb=new scene::SMeshBuffer(); + + u32 i; + mb->Indices.set_used(indices.size()); + for (i=0; iIndices[i]=indices[i]; + + mb->Vertices.set_used(geom.NumVertex); + for (i=0; iVertices[k].Color=mb->Material.DiffuseColor; + mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==4) //Normal + { + for (u32 j=0; jVertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==7) //TexCoord + { + for (u32 j=0; jVertices[k].TCoords.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1]); + ePos += eSize; + } + } + } + } + } + return mb; +} + + + +scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const core::array& indices, const OgreGeometry& geom) +{ + scene::SMeshBufferLightMap *mb=new scene::SMeshBufferLightMap(); + + u32 i; + mb->Indices.set_used(indices.size()); + for (i=0; iIndices[i]=indices[i]; + + mb->Vertices.set_used(geom.NumVertex); + + for (i=0; iVertices[k].Color=mb->Material.DiffuseColor; + mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==4) //Normal + { + for (u32 j=0; jVertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==7) //TexCoord + { + for (u32 j=0; jVertices[k].TCoords.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); + mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]); + + ePos += eSize; + } + } + } + } + } + + return mb; +} + + + +void COgreMeshFileLoader::composeObject(void) +{ + for (u32 i=0; iaddMeshBuffer(mb); + mb->drop(); + } + } + } +} + + +core::stringc COgreMeshFileLoader::getTextureFileName(const core::stringc& texture, + core::stringc& model) +{ + s32 idx = -1; + idx = model.findLast('/'); + + if (idx == -1) + idx = model.findLast('\\'); + + if (idx == -1) + return core::stringc(); + + core::stringc p = model.subString(0, idx+1); + p.append(texture); + return p; +} + + +void COgreMeshFileLoader::getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine) +{ + c8 c=0; + token = ""; + + file->read(&c, sizeof(c8)); + while ( core::isspace(c) && (file->getPos() < file->getSize())) + { + if (noNewLine && c=='\n') + { + file->seek(-1, true); + return; + } + file->read(&c, sizeof(c8)); + } + do + { + if (c=='/') + { + file->read(&c, sizeof(c8)); + if (c=='/') + { // skip comments + while(c!='\n') + file->read(&c, sizeof(c8)); + } + else + { + token.append('/'); + if (core::isspace(c)) + return; + } + } + token.append(c); + file->read(&c, sizeof(c8)); + } + while ((!core::isspace(c)) && (file->getPos() < file->getSize())); + if (c == '\n' && noNewLine) + file->seek(-1, true); +} + + + +bool COgreMeshFileLoader::readColor(io::IReadFile* file, video::SColor& col) +{ + core::stringc token; + + getMaterialToken(file, token); + if (token!="vertexcolour") + { + video::SColorf col_f; + col_f.r=core::fast_atof(token.c_str()); + getMaterialToken(file, token); + col_f.g=core::fast_atof(token.c_str()); + getMaterialToken(file, token); + col_f.b=core::fast_atof(token.c_str()); + getMaterialToken(file, token, true); + if (token.size()) + col_f.a=core::fast_atof(token.c_str()); + else + col_f.a=1.0f; + if ((col_f.r==0.0f)&&(col_f.g==0.0f)&&(col_f.b==0.0f)) + col.set(255,255,255,255); + else + col=col_f.toSColor(); + return false; + } + return true; +} + + +void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique) +{ + core::stringc token; + technique.Passes.push_back(OgrePass()); + OgrePass& pass=technique.Passes.getLast(); + + getMaterialToken(file, token); //open brace or name + if (token != "{") + getMaterialToken(file, token); //open brace + + getMaterialToken(file, token); + u32 inBlocks=1; + while(inBlocks) + { + if (token=="ambient") + pass.AmbientTokenColor=readColor(file, pass.Material.AmbientColor); + else if (token=="diffuse") + pass.DiffuseTokenColor=readColor(file, pass.Material.AmbientColor); + else if (token=="specular") + { + pass.SpecularTokenColor=readColor(file, pass.Material.AmbientColor); + getMaterialToken(file, token); + pass.Material.Shininess=core::fast_atof(token.c_str()); + } + else if (token=="emissive") + pass.EmissiveTokenColor=readColor(file, pass.Material.AmbientColor); + else if (token=="scene_blend") + { // TODO: Choose correct values + getMaterialToken(file, token); + if (token=="add") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + else if (token=="modulate") + pass.Material.MaterialType=video::EMT_SOLID; + else if (token=="alpha_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else if (token=="colour_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + else + getMaterialToken(file, token); + } + else if (token=="depth_check") + { + getMaterialToken(file, token); + pass.Material.ZBuffer=(token=="on"); + } + else if (token=="depth_write") + { + getMaterialToken(file, token); + pass.Material.ZWriteEnable=(token=="on"); + } + else if (token=="depth_func") + { + getMaterialToken(file, token); // Function name + } + else if (token=="depth_bias") + { + getMaterialToken(file, token); // bias value + } + else if (token=="alpha_rejection") + { + getMaterialToken(file, token); // function name + getMaterialToken(file, token); // value + } + else if (token=="cull_hardware") + { + getMaterialToken(file, token); // rotation name + } + else if (token=="cull_software") + { + getMaterialToken(file, token); // culling side + } + else if (token=="lighting") + { + getMaterialToken(file, token); + pass.Material.Lighting=(token=="on"); + } + else if (token=="shading") + { + getMaterialToken(file, token); + // We take phong as gouraud + pass.Material.GouraudShading=(token!="flat"); + } + else if (token=="polygon_mode") + { + getMaterialToken(file, token); + // We take points as wireframe + pass.Material.Wireframe=(token!="solid"); + } + else if (token=="colour_write") + { + getMaterialToken(file, token); + pass.ColorWrite=(token=="on"); + } + else if (token=="max_lights") + { + getMaterialToken(file, token); + pass.MaxLights=strtol(token.c_str(),NULL,10); + } + else if (token=="point_size") + { + getMaterialToken(file, token); + pass.PointSize=core::fast_atof(token.c_str()); + } + else if (token=="point_sprites") + { + getMaterialToken(file, token); + pass.PointSprites=(token=="on"); + } + else if (token=="point_size_min") + { + getMaterialToken(file, token); + pass.PointSizeMin=strtol(token.c_str(),NULL,10); + } + else if (token=="point_size_max") + { + getMaterialToken(file, token); + pass.PointSizeMax=strtol(token.c_str(),NULL,10); + } + else if (token=="texture_unit") + { + getMaterialToken(file, token); //open brace + getMaterialToken(file, token); + while(token != "}") + { + if (token=="texture") + { + getMaterialToken(file, pass.Texture.Filename); + getMaterialToken(file, pass.Texture.CoordsType, true); + getMaterialToken(file, pass.Texture.MipMaps, true); + getMaterialToken(file, pass.Texture.Alpha, true); + } + else if (token=="texture_alias") + getMaterialToken(file, pass.Texture.Alias); + else if (token=="colour_op") + { // TODO: Choose correct values + getMaterialToken(file, token); + if (token=="add") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + else if (token=="modulate") + pass.Material.MaterialType=video::EMT_SOLID; + else if (token=="alpha_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else if (token=="colour_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + else + getMaterialToken(file, token); + } + getMaterialToken(file, token); + } + } + //fog_override, iteration, point_size_attenuation + //not considered yet! + getMaterialToken(file, token); + if (token=="{") + ++inBlocks; + else if (token=="}") + --inBlocks; + } +} + + + +void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat) +{ + core::stringc token; + mat.Techniques.push_back(OgreTechnique()); + OgreTechnique& technique=mat.Techniques.getLast(); + + getMaterialToken(file, technique.Name); //open brace or name + if (technique.Name != "{") + getMaterialToken(file, token); //open brace + else + technique.Name=core::stringc((int)mat.Techniques.size()); + + getMaterialToken(file, token); + while (token != "}") + { + if (token == "pass") + readPass(file, technique); + else if (token == "scheme") + getMaterialToken(file, token); + else if (token == "lod_index") + getMaterialToken(file, token); + getMaterialToken(file, token); + } +} + + + +void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile) +{ + core::stringc token,filename=meshFile->getFileName(); + core::stringc material = filename.subString(0, filename.size()-4) + "material"; + io::IReadFile* file = FileSystem->createAndOpenFile(material.c_str()); + + if (!file) + { + os::Printer::log("Could not load OGRE material", material.c_str()); + return; + } + + getMaterialToken(file, token); + + while (file->getPos() < file->getSize()) + { + Materials.push_back(OgreMaterial()); + OgreMaterial& mat = Materials.getLast(); + + if (token != "material") + return; + getMaterialToken(file, mat.Name); + getMaterialToken(file, token); //open brace + getMaterialToken(file, token); + while(token != "}") + { + if (token=="lod_distances") // can have several items + getMaterialToken(file, token); + else if (token=="receive_shadows") + { + getMaterialToken(file, token); + mat.ReceiveShadows=(token=="on"); + } + else if (token=="transparency_casts_shadows") + { + getMaterialToken(file, token); + mat.TransparencyCastsShadows=(token=="on"); + } + else if (token=="set_texture_alias") + { + getMaterialToken(file, token); + getMaterialToken(file, token); + } + else if (token=="technique") + readTechnique(file, mat); + getMaterialToken(file, token); + } + getMaterialToken(file, token); + } + + file->drop(); +} + + + +void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data) +{ + file->read(&data.header, sizeof(ChunkHeader)); + if (SwapEndian) + { + data.header.id = os::Byteswap::byteswap(data.header.id); + data.header.length = os::Byteswap::byteswap(data.header.length); + } + data.read += sizeof(ChunkHeader); +} + + +void COgreMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) +{ + c8 c = 0; + out = ""; + + while (c!='\n') + { + file->read(&c, sizeof(c8)); + if (c!='\n') + out.append(c); + + } + data.read+=out.size()+1; +} + + +void COgreMeshFileLoader::readBool(io::IReadFile* file, ChunkData& data, bool& out) +{ + // normal C type because we read a bit string + char c = 0; + file->read(&c, sizeof(char)); + out=(c!=0); + ++data.read; +} + + +void COgreMeshFileLoader::readInt(io::IReadFile* file, ChunkData& data, s32& out) +{ + // normal C type because we read a bit string + int tmp; + file->read(&tmp, sizeof(int)); + if (SwapEndian) + { + tmp = os::Byteswap::byteswap(tmp); + } + out=tmp; + data.read+=sizeof(int); +} + + +void COgreMeshFileLoader::readShort(io::IReadFile* file, ChunkData& data, u16& out) +{ + // normal C type because we read a bit string + short tmp; + file->read(&tmp, sizeof(short)); + if (SwapEndian) + { + tmp = os::Byteswap::byteswap(tmp); + } + out=tmp; + data.read+=sizeof(short); +} + + +void COgreMeshFileLoader::readFloat(io::IReadFile* file, ChunkData& data, f32& out) +{ + // normal C type because we read a bit string + float tmp; + file->read(&tmp, sizeof(float)); + if (SwapEndian) + { + tmp = os::Byteswap::byteswap(tmp); + } + out=tmp; + data.read+=sizeof(float); +} + + +void COgreMeshFileLoader::readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out) +{ + readFloat(file, data, out.X); + readFloat(file, data, out.Y); + readFloat(file, data, out.Z); +} + +void COgreMeshFileLoader::setCurrentlyLoadingPath(io::IReadFile* file) +{ + CurrentlyLoadingFromPath = file->getFileName(); + int idx = CurrentlyLoadingFromPath.findLast('/'); + + if (idx != -1) + { + CurrentlyLoadingFromPath = CurrentlyLoadingFromPath.subString(0, idx); + } + else + { + idx = CurrentlyLoadingFromPath.findLast('\\'); + + if (idx != -1) + CurrentlyLoadingFromPath = CurrentlyLoadingFromPath.subString(0, idx); + } +} + +void COgreMeshFileLoader::clearMeshes() +{ + for (u32 i=0; i Passes; + }; + + struct OgreMaterial + { + OgreMaterial() : Name(""), ReceiveShadows(true), + TransparencyCastsShadows(false) {} + + core::stringc Name; + bool ReceiveShadows; + bool TransparencyCastsShadows; + core::array LODDistances; + core::array Techniques; + }; + + struct OgreVertexBuffer + { + OgreVertexBuffer() : BindIndex(0), VertexSize(0), Data(0) {} + void destroy() { delete [] Data; Data = 0; }; + + u16 BindIndex, + VertexSize; + f32 *Data; + }; + + struct OgreVertexElement + { + u16 Source, + Type, + Semantic, + Offset, + Index; + }; + + struct OgreGeometry + { + s32 NumVertex; + core::array Elements; + core::array Buffers; + core::array Vertices; + core::array Normals; + core::array Colors; + core::array TexCoords; + }; + + struct OgreTextureAlias + { + OgreTextureAlias() {}; + OgreTextureAlias(const core::stringc& a, const core::stringc& b) : Texture(a), Alias(b) {}; + core::stringc Texture; + core::stringc Alias; + }; + + struct OgreSubMesh + { + core::stringc Material; + bool SharedVertices; + core::array Indices; + OgreGeometry Geometry; + u16 Operation; + core::array TextureAliases; + bool Indices32Bit; + }; + + struct OgreMesh + { + bool SkeletalAnimation; + OgreGeometry Geometry; + core::array SubMeshes; + core::vector3df BBoxMinEdge; + core::vector3df BBoxMaxEdge; + f32 BBoxRadius; + }; + + bool readChunk(io::IReadFile* file); + bool readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh); + bool readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh); + + void readChunkData(io::IReadFile* file, ChunkData& data); + void readString(io::IReadFile* file, ChunkData& data, core::stringc& out); + void readBool(io::IReadFile* file, ChunkData& data, bool& out); + void readInt(io::IReadFile* file, ChunkData& data, s32& out); + void readShort(io::IReadFile* file, ChunkData& data, u16& out); + void readFloat(io::IReadFile* file, ChunkData& data, f32& out); + void readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out); + + void composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName); + scene::SMeshBuffer* composeMeshBuffer(const core::array& indices, const OgreGeometry& geom); + scene::SMeshBufferLightMap* composeMeshBufferLightMap(const core::array& indices, const OgreGeometry& geom); + void composeObject(void); + bool readColor(io::IReadFile* meshFile, video::SColor& col); + void getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine=false); + void readTechnique(io::IReadFile* meshFile, OgreMaterial& mat); + void readPass(io::IReadFile* file, OgreTechnique& technique); + void loadMaterials(io::IReadFile* file); + core::stringc getTextureFileName(const core::stringc& texture, core::stringc& model); + void setCurrentlyLoadingPath(io::IReadFile* file); + void clearMeshes(); + + io::IFileSystem* FileSystem; + video::IVideoDriver* Driver; + + core::stringc Version; + bool SwapEndian; + core::array Meshes; + core::stringc CurrentlyLoadingFromPath; + + core::array Materials; + + SMesh* Mesh; + IMeshManipulator* Manipulator; + u32 NumUV; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLDriver.cpp b/src/dep/src/irrlicht/COpenGLDriver.cpp new file mode 100644 index 0000000..89dd042 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLDriver.cpp @@ -0,0 +1,2418 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "COpenGLDriver.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLTexture.h" +#include "COpenGLMaterialRenderer.h" +#include "COpenGLShaderMaterialRenderer.h" +#include "COpenGLSLMaterialRenderer.h" +#include "COpenGLNormalMapRenderer.h" +#include "COpenGLParallaxMapRenderer.h" +#include "CImage.h" +#include "os.h" + +#ifdef _IRR_USE_SDL_DEVICE_ +#include +#endif + +namespace irr +{ +namespace video +{ + +// ----------------------------------------------------------------------- +// WINDOWS CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_USE_WINDOWS_DEVICE_ +//! Windows constructor and init code +COpenGLDriver::COpenGLDriver(const core::dimension2d& screenSize, HWND window, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool antiAlias) +: CNullDriver(io, screenSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), + AntiAlias(antiAlias), RenderTargetTexture(0), LastSetLight(-1), + CurrentRendertargetSize(0,0), + HDc(0), Window(window), HRc(0) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif +} + +//! inits the open gl driver +bool COpenGLDriver::initDriver(const core::dimension2d& screenSize, + HWND window, u32 bits, bool fullscreen, bool vsync, bool stencilBuffer) +{ + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 24, // Z-Buffer (Depth Buffer) + stencilBuffer ? 1 : 0, // Stencil Buffer Depth + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + for (u32 i=0; i<5; ++i) + { + if (i == 1) + { + if (stencilBuffer) + { + os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); + stencilBuffer = false; + pfd.cStencilBits = 0; + } + else + continue; + } + else + if (i == 2) + { + pfd.cDepthBits = 24; + } + if (i == 3) + { + if (bits!=16) + pfd.cDepthBits = 16; + else + continue; + } + else + if (i == 4) + { + os::Printer::log("Cannot create a GL device context.", ELL_ERROR); + return false; + } + + // get hdc + if (!(HDc=GetDC(window))) + { + os::Printer::log("Cannot create a GL device context.", ELL_ERROR); + continue; + } + + GLuint PixelFormat; + + // choose pixelformat + if (!(PixelFormat = ChoosePixelFormat(HDc, &pfd))) + { + os::Printer::log("Cannot find a suitable pixelformat.", ELL_ERROR); + continue; + } + + // set pixel format + if(!SetPixelFormat(HDc, PixelFormat, &pfd)) + { + os::Printer::log("Cannot set the pixel format.", ELL_ERROR); + continue; + } + + // create rendering context + if (!(HRc=wglCreateContext(HDc))) + { + os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR); + continue; + } + + // activate rendering context + if(!wglMakeCurrent(HDc, HRc)) + { + os::Printer::log("Cannot activate GL rendering context", ELL_ERROR); + continue; + } + + break; + } + + genericDriverInit(screenSize, stencilBuffer); + + // set vsync + if (wglSwapIntervalEXT) + wglSwapIntervalEXT(vsync ? 1 : 0); + + // set exposed data + ExposedData.OpenGLWin32.HDc = reinterpret_cast(HDc); + ExposedData.OpenGLWin32.HRc = reinterpret_cast(HRc); + ExposedData.OpenGLWin32.HWnd = reinterpret_cast(Window); + + return true; +} + +#endif //IRR_USE_WINDOWS_DEVICE_ + +// ----------------------------------------------------------------------- +// MACOSX CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef MACOSX +//! Windows constructor and init code +COpenGLDriver::COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, bool stencilBuffer, CIrrDeviceMacOSX *device, io::IFileSystem* io, bool vsync, bool antiAlias) +: CNullDriver(io, screenSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), + AntiAlias(antiAlias), RenderTargetTexture(0), LastSetLight(-1), + CurrentRendertargetSize(0,0), _device(device) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + genericDriverInit(screenSize, stencilBuffer); +} + +#endif + +// ----------------------------------------------------------------------- +// LINUX CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_USE_LINUX_DEVICE_ +//! Linux constructor and init code +COpenGLDriver::COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias) +: CNullDriver(io, screenSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), + Transformation3DChanged(true), AntiAlias(antiAlias), + RenderTargetTexture(0), LastSetLight(-1), CurrentRendertargetSize(0,0) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + XWindow = glXGetCurrentDrawable(); + XDisplay = glXGetCurrentDisplay(); + ExposedData.OpenGLLinux.X11Display = XDisplay; + ExposedData.OpenGLLinux.X11Window = XWindow; + genericDriverInit(screenSize, stencilBuffer); + + // set vsync +#ifdef GLX_SGI_swap_control +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (vsync && glxSwapIntervalSGI) + glxSwapIntervalSGI(1); +#else + if (vsync) + glXSwapIntervalSGI(1); +#endif +#endif +} + +#endif // _IRR_USE_LINUX_DEVICE_ + + +// ----------------------------------------------------------------------- +// SDL CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_USE_SDL_DEVICE_ +//! SDL constructor and init code +COpenGLDriver::COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias) +: CNullDriver(io, screenSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), + Transformation3DChanged(true), AntiAlias(antiAlias), + RenderTargetTexture(0), LastSetLight(-1), CurrentRendertargetSize(0,0) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + + genericDriverInit(screenSize, stencilBuffer); +} + +#endif // _IRR_USE_SDL_DEVICE_ + + +//! destructor +COpenGLDriver::~COpenGLDriver() +{ + deleteMaterialRenders(); + + // I get a blue screen on my laptop, when I do not delete the + // textures manually before releasing the dc. Oh how I love this. + + deleteAllTextures(); + +#ifdef _IRR_USE_WINDOWS_DEVICE_ + if (HRc) + { + if (!wglMakeCurrent(0, 0)) + os::Printer::log("Release of dc and rc failed.", ELL_WARNING); + + if (!wglDeleteContext(HRc)) + os::Printer::log("Release of rendering context failed.", ELL_WARNING); + } + + if (HDc) + ReleaseDC(Window, HDc); +#endif +} + +// ----------------------------------------------------------------------- +// METHODS +// ----------------------------------------------------------------------- + +bool COpenGLDriver::genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer) +{ + Name=L"OpenGL "; + Name.append(glGetString(GL_VERSION)); + s32 pos=Name.findNext(L' ', 7); + if (pos != -1) + Name=Name.subString(0, pos); + printVersion(); + + // print renderer information + const GLubyte* renderer = glGetString(GL_RENDERER); + const GLubyte* vendor = glGetString(GL_VENDOR); + if (renderer && vendor) + os::Printer::log(reinterpret_cast(renderer), reinterpret_cast(vendor), ELL_INFORMATION); + + u32 i; + for (i=0; i101) || FeatureAvailable[IRR_EXT_rescale_normal]) +// glEnable(GL_RESCALE_NORMAL_EXT); + glClearDepth(1.0); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glDepthFunc(GL_LEQUAL); + glFrontFace( GL_CW ); +// currently disabled, because often in software, and thus very slow +// glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); +// glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); +// glEnable(GL_POINT_SMOOTH); +// glEnable(GL_LINE_SMOOTH); + + if (AntiAlias && MultiSamplingExtension) + glEnable(GL_MULTISAMPLE_ARB); + + UserClipPlane.reallocate(MaxUserClipPlanes); + UserClipPlaneEnabled.reallocate(MaxUserClipPlanes); + for (i=0; idrop(); + + // add remaining material renderer + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_DETAIL_MAP( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SPHERE_MAP( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_REFLECTION_2_LAYER( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA( this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER( this)); + + // add normal map renderers + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add parallax map renderers + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add basic 1 texture blending + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_ONETEXTURE_BLEND(this)); +} + + +//! presents the rendered scene on the screen, returns false if failed +bool COpenGLDriver::endScene( s32 windowId, core::rect* sourceRect ) +{ + CNullDriver::endScene( windowId ); + + glFlush(); + +#ifdef _IRR_USE_WINDOWS_DEVICE_ + return SwapBuffers(HDc) == TRUE; +#elif defined(_IRR_USE_LINUX_DEVICE_) + glXSwapBuffers(XDisplay, XWindow); + return true; +#elif defined(MACOSX) + _device->flush(); + return true; +#elif defined(_IRR_USE_SDL_DEVICE_) + SDL_GL_SwapBuffers(); + return true; +#else + return false; +#endif +} + + + +//! clears the zbuffer +bool COpenGLDriver::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color); + + GLbitfield mask = 0; + + if (backBuffer) + { + const f32 inv = 1.0f / 255.0f; + glClearColor(color.getRed() * inv, color.getGreen() * inv, + color.getBlue() * inv, color.getAlpha() * inv); + + mask |= GL_COLOR_BUFFER_BIT; + } + + if (zBuffer) + { + glDepthMask(GL_TRUE); + mask |= GL_DEPTH_BUFFER_BIT; + } + + glClear(mask); + return true; +} + + + +//! Returns the transformation set by setTransform +const core::matrix4& COpenGLDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + + + +//! sets transformation +void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + GLfloat glmat[16]; + Matrices[state] = mat; + Transformation3DChanged = true; + + switch(state) + { + case ETS_VIEW: + case ETS_WORLD: + { + // OpenGL only has a model matrix, view and world is not existent. so lets fake these two. + createGLMatrix(glmat, Matrices[ETS_VIEW] * Matrices[ETS_WORLD]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(glmat); + // we have to update the clip planes to the latest view matrix + for (u32 i=0; iisRenderTarget(); + + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB + i); + + glMatrixMode(GL_TEXTURE); + if (mat.isIdentity() && !isRTT) + glLoadIdentity(); + else + { + createGLTextureMatrix(glmat, mat); + if (isRTT) + glmat[5] *= -1.0f; + glLoadMatrixf(glmat); + } + break; + } + default: + break; + } +} + + + +//! draws a vertex primitive list +void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + if (!primitiveCount || !vertexCount) + return; + + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType); + + // convert colors to gl color format. + vertexCount *= 4; //reused as color component count + ColorBuffer.set_used(vertexCount); + u32 i; + + switch (vType) + { + case EVT_STANDARD: + { + const S3DVertex* p = reinterpret_cast(vertices); + for ( i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + case EVT_2TCOORDS: + { + const S3DVertex2TCoords* p = reinterpret_cast(vertices); + for ( i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + case EVT_TANGENTS: + { + const S3DVertexTangents* p = reinterpret_cast(vertices); + for ( i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + } + + // draw everything + + setRenderStates3DMode(); + + if (MultiTextureExtension) + extGlClientActiveTexture(GL_TEXTURE0_ARB); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_NORMAL_ARRAY); + + glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); + switch (vType) + { + case EVT_STANDARD: + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast(vertices))[0].Pos); + glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast(vertices))[0].TCoords); + if (MultiTextureExtension && CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast(vertices))[0].TCoords); + } + break; + case EVT_2TCOORDS: + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast(vertices))[0].Pos); + glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast(vertices))[0].Normal); + // texture coordinates + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast(vertices))[0].TCoords); + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast(vertices))[0].TCoords2); + } + break; + case EVT_TANGENTS: + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast(vertices))[0].Pos); + glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast(vertices))[0].Normal); + // texture coordinates + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast(vertices))[0].TCoords); + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast(vertices))[0].Tangent); + + extGlClientActiveTexture(GL_TEXTURE2_ARB); + glEnableClientState ( GL_TEXTURE_COORD_ARRAY ); + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast(vertices))[0].Binormal); + } + break; + } + + switch (pType) + { + case scene::EPT_POINTS: + case scene::EPT_POINT_SPRITES: + { +#ifdef GL_ARB_point_sprite + if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) + glEnable(GL_POINT_SPRITE_ARB); +#endif + float quadratic[] = {0.0f, 0.0f, 10.01f}; + extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic); + float maxParticleSize=1.0f; + glGetFloatv(GL_POINT_SIZE_MAX_ARB, &maxParticleSize); +// maxParticleSize=maxParticleSize& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + core::position2d targetPos(pos); + core::position2d sourcePos(sourceRect.UpperLeftCorner); + core::dimension2d sourceSize(sourceRect.getSize()); + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (targetPos.X + sourceSize.Width > renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + + tcoords.UpperLeftCorner.X = sourcePos.X / static_cast(ss.Width); + tcoords.UpperLeftCorner.Y = sourcePos.Y / static_cast(ss.Height); + tcoords.LowerRightCorner.X = (sourcePos.X + sourceSize.Width) / static_cast(ss.Width); + tcoords.LowerRightCorner.Y = (sourcePos.Y + sourceSize.Height) / static_cast(ss.Height); + + const core::rect poss(targetPos, sourceSize); + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + disableTextures(1); + if (!setTexture(0, texture)) + return; + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glBegin(GL_QUADS); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glEnd(); +} + + + +//! The same, but with a four element array of colors, one for each vertex +void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + video::SColor* colors, bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = sourceRect.UpperLeftCorner.X / static_cast(ss.Width); + tcoords.UpperLeftCorner.Y = sourceRect.UpperLeftCorner.Y / static_cast(ss.Height); + tcoords.LowerRightCorner.X = sourceRect.LowerRightCorner.X / static_cast(ss.Width); + tcoords.LowerRightCorner.Y = sourceRect.LowerRightCorner.Y / static_cast(ss.Height); + + video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + video::SColor* useColor = colors ? colors : temp; + + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); + + disableTextures(1); + setTexture(0, texture); + + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + + glBegin(GL_QUADS); + + glColor4ub(useColor[0].getRed(), useColor[0].getGreen(), useColor[0].getBlue(), useColor[0].getAlpha()); + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); + + glColor4ub(useColor[3].getRed(), useColor[3].getGreen(), useColor[3].getBlue(), useColor[3].getAlpha()); + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); + + glColor4ub(useColor[2].getRed(), useColor[2].getGreen(), useColor[2].getBlue(), useColor[2].getAlpha()); + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.LowerRightCorner.Y)); + + glColor4ub(useColor[1].getRed(), useColor[1].getGreen(), useColor[1].getBlue(), useColor[1].getAlpha()); + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.LowerRightCorner.Y)); + + glEnd(); + + if (clipRect) + glDisable(GL_SCISSOR_TEST); +} + + + +//! draws a set of 2d images, using a color and the alpha channel of the +//! texture if desired. The images are drawn beginning at pos and concatenated +//! in one line. All drawings are clipped against clipRect (if != 0). +//! The subtextures are defined by the array of sourceRects and are chosen +//! by the indices given. +void COpenGLDriver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + disableTextures(1); + if (!setTexture(0, texture)) + return; + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, + clipRect->getWidth(),clipRect->getHeight()); + } + + const core::dimension2d& ss = texture->getOriginalSize(); + core::position2d targetPos(pos); + core::position2d sourcePos; + core::dimension2d sourceSize; + core::rect tcoords; + + for (u32 i=0; i(ss.Width); + tcoords.UpperLeftCorner.Y = sourceRects[currentIndex].UpperLeftCorner.Y / static_cast(ss.Height); + tcoords.LowerRightCorner.X = sourceRects[currentIndex].LowerRightCorner.X / static_cast(ss.Width); + tcoords.LowerRightCorner.Y = sourceRects[currentIndex].LowerRightCorner.Y / static_cast(ss.Height); + + const core::rect poss(targetPos, sourceSize); + + glBegin(GL_QUADS); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glEnd(); + targetPos.X += sourceRects[currentIndex].getWidth(); + } + if (clipRect) + glDisable(GL_SCISSOR_TEST); +} + + + +//! draw a 2d rectangle +void COpenGLDriver::draw2DRectangle(SColor color, const core::rect& position, + const core::rect* clip) +{ + setRenderStates2DMode(color.getAlpha() < 255, false, false); + disableTextures(); + + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glRectf(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y), + GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); +} + + + +//! draw an 2d rectangle +void COpenGLDriver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + setRenderStates2DMode(colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + disableTextures(); + + glBegin(GL_QUADS); + glColor4ub(colorLeftUp.getRed(), colorLeftUp.getGreen(), + colorLeftUp.getBlue(), colorLeftUp.getAlpha()); + glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y)); + + glColor4ub(colorRightUp.getRed(), colorRightUp.getGreen(), + colorRightUp.getBlue(), colorRightUp.getAlpha()); + glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.UpperLeftCorner.Y)); + + glColor4ub(colorRightDown.getRed(), colorRightDown.getGreen(), + colorRightDown.getBlue(), colorRightDown.getAlpha()); + glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); + + glColor4ub(colorLeftDown.getRed(), colorLeftDown.getGreen(), + colorLeftDown.getBlue(), colorLeftDown.getAlpha()); + glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.LowerRightCorner.Y)); + + glEnd(); +} + + + +//! Draws a 2d line. +void COpenGLDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + setRenderStates2DMode(color.getAlpha() < 255, false, false); + disableTextures(); + + glBegin(GL_LINES); + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glVertex2f(GLfloat(start.X), GLfloat(start.Y)); + glVertex2f(GLfloat(end.X), GLfloat(end.Y)); + glEnd(); +} + + + +bool COpenGLDriver::setTexture(u32 stage, const video::ITexture* texture) +{ + if (stage >= MaxTextureUnits) + return false; + + if (CurrentTexture[stage]==texture) + return true; + + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB + stage); + + CurrentTexture[stage]=texture; + + if (!texture) + { + glDisable(GL_TEXTURE_2D); + return true; + } + else + { + if (texture->getDriverType() != EDT_OPENGL) + { + glDisable(GL_TEXTURE_2D); + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, + static_cast(texture)->getOpenGLTextureName()); + } + return true; +} + + + +//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. +//! Returns whether disabling was successful or not. +bool COpenGLDriver::disableTextures(u32 fromStage) +{ + bool result=true; + for (u32 i=fromStage; i= 0; --i) + { + setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), + material.getTextureMatrix(i)); + } +} + + + +//! prints error if an error happened. +bool COpenGLDriver::testGLError() +{ +#ifdef _DEBUG + GLenum g = glGetError(); + switch(g) + { + case GL_NO_ERROR: + return false; + case GL_INVALID_ENUM: + os::Printer::log("GL_INVALID_ENUM", ELL_ERROR); break; + case GL_INVALID_VALUE: + os::Printer::log("GL_INVALID_VALUE", ELL_ERROR); break; + case GL_INVALID_OPERATION: + os::Printer::log("GL_INVALID_OPERATION", ELL_ERROR); break; + case GL_STACK_OVERFLOW: + os::Printer::log("GL_STACK_OVERFLOW", ELL_ERROR); break; + case GL_STACK_UNDERFLOW: + os::Printer::log("GL_STACK_UNDERFLOW", ELL_ERROR); break; + case GL_OUT_OF_MEMORY: + os::Printer::log("GL_OUT_OF_MEMORY", ELL_ERROR); break; + case GL_TABLE_TOO_LARGE: + os::Printer::log("GL_TABLE_TOO_LARGE", ELL_ERROR); break; + }; + return true; +#else + return false; +#endif +} + + + +//! sets the needed renderstates +void COpenGLDriver::setRenderStates3DMode() +{ + if (CurrentRenderMode != ERM_3D) + { + // Reset Texture Stages + if (FeatureAvailable[IRR_ARB_texture_env_combine]) + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE ); + glDisable(GL_ALPHA_TEST); + glDisable( GL_BLEND ); + glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR ); + + // switch back the matrices + GLfloat glmat[16]; + + createGLMatrix(glmat, Matrices[ETS_VIEW] * Matrices[ETS_WORLD]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(glmat); + + createGLMatrix(glmat, Matrices[ETS_PROJECTION]); + glmat[12] *= -1.0f; + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(glmat); + + ResetRenderStates = true; + } + + if ( ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (LastMaterial.MaterialType != Material.MaterialType && + LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < static_cast(MaterialRenderers.size())) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + if (Material.MaterialType >= 0 && Material.MaterialType < static_cast(MaterialRenderers.size())) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + + LastMaterial = Material; + ResetRenderStates = false; + } + + if (Material.MaterialType >= 0 && Material.MaterialType < static_cast(MaterialRenderers.size())) + MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD); + + CurrentRenderMode = ERM_3D; +} + + +//! Can be called by an IMaterialRenderer to make its work easier. +void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderStates) +{ + if (resetAllRenderStates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.Shininess != material.Shininess) + { + GLfloat color[4]; + + const f32 inv = 1.0f / 255.0f; + + color[0] = material.AmbientColor.getRed() * inv; + color[1] = material.AmbientColor.getGreen() * inv; + color[2] = material.AmbientColor.getBlue() * inv; + color[3] = material.AmbientColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); + + color[0] = material.DiffuseColor.getRed() * inv; + color[1] = material.DiffuseColor.getGreen() * inv; + color[2] = material.DiffuseColor.getBlue() * inv; + color[3] = material.DiffuseColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); + + // disable Specular colors if no shininess is set + if (material.Shininess != 0.0f) + { +#ifdef GL_EXT_separate_specular_color + if (FeatureAvailable[IRR_EXT_separate_specular_color]) + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); +#endif + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess); + color[0] = material.SpecularColor.getRed() * inv; + color[1] = material.SpecularColor.getGreen() * inv; + color[2] = material.SpecularColor.getBlue() * inv; + color[3] = material.SpecularColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); + } +#ifdef GL_EXT_separate_specular_color + else + if (FeatureAvailable[IRR_EXT_separate_specular_color]) + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); +#endif + + color[0] = material.EmissiveColor.getRed() * inv; + color[1] = material.EmissiveColor.getGreen() * inv; + color[2] = material.EmissiveColor.getBlue() * inv; + color[3] = material.EmissiveColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color); + } + + // Texture filter + // Has to be checked always because it depends on the textures + // Filtering has to be set for each texture layer + for (u32 i=0; i0) + break; + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); + + if (material.getTexture(i) && material.getTexture(i)->hasMipMaps()) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST ); + else + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); + +#ifdef GL_EXT_texture_filter_anisotropic + if (AnisotropyExtension) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + material.TextureLayer[i].AnisotropicFilter ? MaxAnisotropy : 1.0f ); +#endif + } + + // fillmode + if (resetAllRenderStates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) + glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL); + + // shademode + + if (resetAllRenderStates || lastmaterial.GouraudShading != material.GouraudShading) + { + if (material.GouraudShading) + glShadeModel(GL_SMOOTH); + else + glShadeModel(GL_FLAT); + } + + // lighting + + if (resetAllRenderStates || lastmaterial.Lighting != material.Lighting) + { + if (material.Lighting) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); + } + + // zbuffer + if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case 0: + glDisable(GL_DEPTH_TEST); + break; + case 1: + glEnable(GL_DEPTH_TEST); + glDepthFunc ( GL_LEQUAL ); + break; + case 2: + glEnable(GL_DEPTH_TEST); + glDepthFunc ( GL_EQUAL ); + break; + } + } + + // zwrite + if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable) + { + if (material.ZWriteEnable) + { + glDepthMask(GL_TRUE); + } + else + glDepthMask(GL_FALSE); + } + + // back face culling + + if (resetAllRenderStates || lastmaterial.BackfaceCulling != material.BackfaceCulling) + { + if (material.BackfaceCulling) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + } + + // fog + if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable) + { + if (material.FogEnable) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + } + + // normalization + if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + if (material.NormalizeNormals) + glEnable(GL_NORMALIZE); + else + glDisable(GL_NORMALIZE); + } + + // thickness + if (resetAllRenderStates || lastmaterial.Thickness != material.Thickness) + { + glPointSize(material.Thickness); + glLineWidth(material.Thickness); + } + + // texture address mode + for (u32 u=0; u101) + mode=GL_CLAMP_TO_EDGE; + else +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (FeatureAvailable[IRR_SGIS_texture_edge_clamp]) + mode=GL_CLAMP_TO_EDGE_SGIS; + else +#endif + // fallback + mode=GL_CLAMP; + break; + case ETC_CLAMP_TO_BORDER: +#ifdef GL_VERSION_1_3 + if (Version>102) + mode=GL_CLAMP_TO_BORDER; + else +#endif +#ifdef GL_ARB_texture_border_clamp + if (FeatureAvailable[IRR_ARB_texture_border_clamp]) + mode=GL_CLAMP_TO_BORDER_ARB; + else +#endif +#ifdef GL_SGIS_texture_border_clamp + if (FeatureAvailable[IRR_SGIS_texture_border_clamp]) + mode=GL_CLAMP_TO_BORDER_SGIS; + else +#endif + // fallback + mode=GL_CLAMP_TO_EDGE; + break; + case ETC_MIRROR: +#ifdef GL_VERSION_1_4 + if (Version>103) + mode=GL_MIRRORED_REPEAT; + else +#endif +#ifdef GL_ARB_texture_border_clamp + if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat]) + mode=GL_MIRRORED_REPEAT_ARB; + else +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat]) + mode=GL_MIRRORED_REPEAT_IBM; + else +#endif + mode=GL_REPEAT; + break; + } + + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB + u); + else if (u>0) + break; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode); + } + } + // be sure to leave in texture stage 0 + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB); +} + + + +//! sets the needed renderstates +void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D && Material.MaterialType >= 0 && + Material.MaterialType < static_cast(MaterialRenderers.size())) + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + + GLfloat glmat[16]; + core::matrix4 m; + + glMatrixMode(GL_PROJECTION); + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-renderTargetSize.Height), -1.0, 1.0); + m.setTranslation(core::vector3df(-1,1,0)); + + createGLMatrix(glmat, m); + glLoadMatrixf(glmat); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef (0.375, 0.375, 0.0); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + Transformation3DChanged = false; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + + glDisable(GL_ALPHA_TEST); + glCullFace(GL_BACK); + } + + if (texture) + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if (alphaChannel) + { + if (alpha) + { + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + } + else + { + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); + } + else + { + if (alpha) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + glDisable(GL_ALPHA_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + } + } + } + else + { + if (alpha) + { + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_ALPHA_TEST); + } + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + } + + CurrentRenderMode = ERM_2D; +} + + +//! \return Returns the name of the video driver. Example: In case of the Direct3D8 +//! driver, it would return "Direct3D8.1". +const wchar_t* COpenGLDriver::getName() const +{ + return Name.c_str(); +} + + +//! deletes all dynamic lights there are +void COpenGLDriver::deleteAllDynamicLights() +{ + for (s32 i=0; i& area) +{ + core::rect vp = area; + core::rect rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); + vp.clipAgainst(rendert); + + if (vp.getHeight()>0 && vp.getWidth()>0) + glViewport(vp.UpperLeftCorner.X, + getCurrentRenderTargetSize().Height - vp.UpperLeftCorner.Y - vp.getHeight(), + vp.getWidth(), vp.getHeight()); + + ViewPort = vp; +} + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: First, draw all geometry. Then use this method, to draw the shadow +//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. +void COpenGLDriver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail) +{ + if (!StencilBuffer || !count) + return; + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + Material.MaterialType >= 0 && Material.MaterialType < static_cast(MaterialRenderers.size())) + { + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + ResetRenderStates = true; + } + + // store current OpenGL state + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | + GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_FALSE); // no depth buffer writing + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); // no color buffer drawing + glEnable(GL_STENCIL_TEST); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),&triangles[0]); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + // The first parts are not correctly working, yet. +#if 0 +#ifdef GL_EXT_stencil_two_side + if (FeatureAvailable[IRR_EXT_stencil_two_side]) + { + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); +#ifdef GL_NV_depth_clamp + if (FeatureAvailable[IRR_NV_depth_clamp]) + glEnable(GL_DEPTH_CLAMP_NV); +#endif + glDisable(GL_CULL_FACE); + if (!zfail) + { + // ZPASS Method + + extGlActiveStencilFace(GL_BACK); + if (FeatureAvailable[IRR_EXT_stencil_wrap]) + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT); + else + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + extGlActiveStencilFace(GL_FRONT); + if (FeatureAvailable[IRR_EXT_stencil_wrap]) + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT); + else + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + glDrawArrays(GL_TRIANGLES,0,count); + } + else + { + // ZFAIL Method + + extGlActiveStencilFace(GL_BACK); + if (FeatureAvailable[IRR_EXT_stencil_wrap]) + glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP); + else + glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + extGlActiveStencilFace(GL_FRONT); + if (FeatureAvailable[IRR_EXT_stencil_wrap]) + glStencilOp(GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP); + else + glStencilOp(GL_KEEP, GL_DECR, GL_KEEP); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + glDrawArrays(GL_TRIANGLES,0,count); + } + } + else +#endif + if (FeatureAvailable[IRR_ATI_separate_stencil]) + { + glDisable(GL_CULL_FACE); + if (!zfail) + { + // ZPASS Method + + extGlStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); + extGlStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); + extGlStencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 0, ~0); + glStencilMask(~0); + + glDrawArrays(GL_TRIANGLES,0,count); + } + else + { + // ZFAIL Method + + extGlStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP); + extGlStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP); + extGlStencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 0, ~0); + + glDrawArrays(GL_TRIANGLES,0,count); + } + } + else +#endif + { + glEnable(GL_CULL_FACE); + if (!zfail) + { + // ZPASS Method + + glCullFace(GL_BACK); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glDrawArrays(GL_TRIANGLES,0,count); + + glCullFace(GL_FRONT); + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); + glDrawArrays(GL_TRIANGLES,0,count); + } + else + { + // ZFAIL Method + + glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); + glCullFace(GL_FRONT); + glDrawArrays(GL_TRIANGLES,0,count); + + glStencilOp(GL_KEEP, GL_DECR, GL_KEEP); + glCullFace(GL_BACK); + glDrawArrays(GL_TRIANGLES,0,count); + } + } + + glDisableClientState(GL_VERTEX_ARRAY); //not stored on stack + glPopAttrib(); +} + + + +void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!StencilBuffer) + return; + + disableTextures(); + + // store attributes + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT ); + + glDisable( GL_LIGHTING ); + glDisable(GL_FOG); + glDepthMask(GL_FALSE); + + glShadeModel( GL_FLAT ); + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable( GL_STENCIL_TEST ); + glStencilFunc(GL_NOTEQUAL, 0, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // draw a shadow rectangle covering the entire screen using stencil buffer + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_QUADS); + + glColor4ub (leftDownEdge.getRed(), leftDownEdge.getGreen(), leftDownEdge.getBlue(), leftDownEdge.getAlpha() ); + glVertex3f(-1.1f,-1.1f,0.9f); + + glColor4ub (leftUpEdge.getRed(), leftUpEdge.getGreen(), leftUpEdge.getBlue(), leftUpEdge.getAlpha() ); + glVertex3f(-1.1f, 1.1f,0.9f); + + glColor4ub (rightUpEdge.getRed(), rightUpEdge.getGreen(), rightUpEdge.getBlue(), rightUpEdge.getAlpha() ); + glVertex3f( 1.1f, 1.1f,0.9f); + + glColor4ub (rightDownEdge.getRed(), rightDownEdge.getGreen(), rightDownEdge.getBlue(), rightDownEdge.getAlpha() ); + glVertex3f( 1.1f,-1.1f,0.9f); + + glEnd(); + + if (clearStencilBuffer) + glClear(GL_STENCIL_BUFFER_BIT); + + // restore settings + glPopMatrix(); + glPopAttrib(); +} + + +//! Sets the fog mode. +void COpenGLDriver::setFog(SColor c, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(c, linearFog, start, end, density, pixelFog, rangeFog); + + glFogi(GL_FOG_MODE, linearFog ? GL_LINEAR : GL_EXP); +#ifdef GL_EXT_fog_coord + if (FeatureAvailable[IRR_EXT_fog_coord]) + glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH); +#endif + + if(linearFog) + { + glFogf(GL_FOG_START, start); + glFogf(GL_FOG_END, end); + } + else + glFogf(GL_FOG_DENSITY, density); + + if (pixelFog) + glHint(GL_FOG_HINT, GL_NICEST); + else + glHint(GL_FOG_HINT, GL_FASTEST); + + SColorf color(c); + GLfloat data[4] = {color.r, color.g, color.b, color.a}; + glFogfv(GL_FOG_COLOR, data); +} + + + +//! Draws a 3d line. +void COpenGLDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setRenderStates3DMode(); + + glBegin(GL_LINES); + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glVertex3f(start.X, start.Y, start.Z); + + glVertex3f(end.X, end.Y, end.Z); + glEnd(); +} + + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void COpenGLDriver::OnResize(const core::dimension2d& size) +{ + CNullDriver::OnResize(size); + glViewport(0, 0, size.Width, size.Height); +} + + + +//! Returns type of video driver +E_DRIVER_TYPE COpenGLDriver::getDriverType() const +{ + return EDT_OPENGL; +} + + + +//! Sets a vertex shader constant. +void COpenGLDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ +#ifdef GL_ARB_vertex_program + for (s32 i=0; isetPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); + return false; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + COpenGLShaderMaterialRenderer* r = new COpenGLShaderMaterialRenderer( + this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + +//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry. +s32 COpenGLDriver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + s32 nr = -1; + + COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer( + this, nr, vertexShaderProgram, vertexShaderEntryPointName, + vsCompileTarget, pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, + callback,getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* COpenGLDriver::getVideoDriver() +{ + return this; +} + + +//! Returns pointer to the IGPUProgrammingServices interface. +IGPUProgrammingServices* COpenGLDriver::getGPUProgrammingServices() +{ + return this; +} + + +ITexture* COpenGLDriver::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + //disable mip-mapping + bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false); + + video::ITexture* rtt = 0; + if (name==0) + name="rt"; +#if defined(GL_EXT_framebuffer_object) + // if driver supports FrameBufferObjects, use them + if (queryFeature(EVDF_FRAMEBUFFER_OBJECT)) + rtt = new COpenGLTexture(size, PackedDepthStencilExtension, name, this); + else +#endif + { + rtt = addTexture(size, name); + if (rtt) + { + rtt->grab(); + static_cast(rtt)->setRenderTarget(true); + } + } + + //restore mip-mapping + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels); + + return rtt; +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 COpenGLDriver::getMaximalPrimitiveCount() const +{ + return 65535;// TODO: Fix all loaders to auto-split and then return the correct value: MaxIndices; +} + + +//! checks triangle count and print warning if wrong +bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + // check for right driver type + + if (texture && texture->getDriverType() != EDT_OPENGL) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + // check if we should set the previous RT back + + bool ret = true; + + setTexture(0, 0); + ResetRenderStates=true; + if (RenderTargetTexture!=0) + { + if (RenderTargetTexture->isFrameBufferObject()) + { + RenderTargetTexture->unbindFrameBufferObject(); + } + else + { + glBindTexture(GL_TEXTURE_2D, RenderTargetTexture->getOpenGLTextureName()); + + // Copy Our ViewPort To The Texture + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, + RenderTargetTexture->getSize().Width, RenderTargetTexture->getSize().Height); + } + } + + if (texture) + { + // we want to set a new target. so do this. + glViewport(0, 0, texture->getSize().Width, texture->getSize().Height); + RenderTargetTexture = static_cast(texture); + CurrentRendertargetSize = texture->getSize(); + + if (RenderTargetTexture->isFrameBufferObject()) + { + RenderTargetTexture->bindFrameBufferObject(); + } + } + else + { + glViewport(0,0,ScreenSize.Width,ScreenSize.Height); + RenderTargetTexture = 0; + CurrentRendertargetSize = core::dimension2d(0,0); + } + + GLbitfield mask = 0; + if (clearBackBuffer) + { + const f32 inv = 1.0f / 255.0f; + glClearColor(color.getRed() * inv, color.getGreen() * inv, + color.getBlue() * inv, color.getAlpha() * inv); + + mask |= GL_COLOR_BUFFER_BIT; + } + if (clearZBuffer) + { + glDepthMask(GL_TRUE); + mask |= GL_DEPTH_BUFFER_BIT; + } + + glClear(mask); + + return ret; +} + + +// returns the current size of the screen or rendertarget +const core::dimension2d& COpenGLDriver::getCurrentRenderTargetSize() const +{ + if ( CurrentRendertargetSize.Width == 0 ) + return ScreenSize; + else + return CurrentRendertargetSize; +} + +//! Clears the ZBuffer. +void COpenGLDriver::clearZBuffer() +{ + GLboolean enabled = GL_TRUE; + glGetBooleanv(GL_DEPTH_WRITEMASK, &enabled); + + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + + glDepthMask(enabled); +} + +//! Returns an image created from the last rendered frame. +IImage* COpenGLDriver::createScreenShot() +{ + IImage* newImage = new CImage(ECF_R8G8B8, ScreenSize); + + u8* pPixels = reinterpret_cast(newImage->lock()); + if (!pPixels) + { + newImage->drop(); + return 0; + } + + glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, GL_RGB, GL_UNSIGNED_BYTE, pPixels); + + // opengl images are inverted, so we have to fix that here. + s32 pitch=newImage->getPitch(); + u8* p2 = pPixels + (ScreenSize.Height - 1) * pitch; + u8* tmpBuffer = new u8[pitch]; + for (s32 i=0; i < ScreenSize.Height; i += 2) + { + memcpy(tmpBuffer, pPixels, pitch); + memcpy(pPixels, p2, pitch); + memcpy(p2, tmpBuffer, pitch); + pPixels += pitch; + p2 -= pitch; + } + delete [] tmpBuffer; + + newImage->unlock(); + + if (testGLError()) + { + newImage->drop(); + return 0; + } + + return newImage; +} + + +//! Set/unset a clipping plane. +//! There are at least 6 clipping planes available for the user to set at will. +//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. +//! \param plane: The plane itself. +//! \param enable: If true, enable the clipping plane else disable it. +bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + if (index >= MaxUserClipPlanes) + return false; + + UserClipPlane[index]=plane; + enableClipPlane(index, enable); + return true; +} + +void COpenGLDriver::uploadClipPlane(u32 index) +{ + // opengl needs an array of doubles for the plane equation + double clip_plane[4]; + clip_plane[0] = UserClipPlane[index].Normal.X; + clip_plane[1] = UserClipPlane[index].Normal.Y; + clip_plane[2] = UserClipPlane[index].Normal.Z; + clip_plane[3] = UserClipPlane[index].D; + glClipPlane(GL_CLIP_PLANE0 + index, clip_plane); +} + +//! Enable/disable a clipping plane. +//! There are at least 6 clipping planes available for the user to set at will. +//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. +//! \param enable: If true, enable the clipping plane else disable it. +void COpenGLDriver::enableClipPlane(u32 index, bool enable) +{ + if (index >= MaxUserClipPlanes) + return; + if (enable) + { + if (!UserClipPlaneEnabled[index]) + { + uploadClipPlane(index); + glEnable(GL_CLIP_PLANE0 + index); + } + } + else + glDisable(GL_CLIP_PLANE0 + index); + + UserClipPlaneEnabled[index]=enable; +} + + +} // end namespace +} // end namespace + + +namespace irr +{ +namespace video +{ + + +// ----------------------------------- +// WINDOWS VERSION +// ----------------------------------- +#ifdef _IRR_USE_WINDOWS_DEVICE_ +IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + HWND window, u32 bits, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + COpenGLDriver* ogl = new COpenGLDriver(screenSize, window, fullscreen, stencilBuffer, io, antiAlias); + if (!ogl->initDriver(screenSize, window, bits, fullscreen, vsync, stencilBuffer)) + { + ogl->drop(); + ogl = 0; + } + return ogl; +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_USE_WINDOWS_DEVICE_ + +// ----------------------------------- +// MACOSX VERSION +// ----------------------------------- +#ifdef MACOSX +IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + CIrrDeviceMacOSX *device, bool fullscreen, bool stencilBuffer, + io::IFileSystem* io, bool vsync, bool antiAlias) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return new COpenGLDriver(screenSize, fullscreen, stencilBuffer, + device, io, vsync, antiAlias); +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // MACOSX + +// ----------------------------------- +// LINUX VERSION +// ----------------------------------- +#ifdef _IRR_USE_LINUX_DEVICE_ +IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return new COpenGLDriver(screenSize, fullscreen, stencilBuffer, + io, vsync, antiAlias); +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_USE_LINUX_DEVICE_ + +// ----------------------------------- +// SDL VERSION +// ----------------------------------- +#ifdef _IRR_USE_SDL_DEVICE_ +IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, + bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return new COpenGLDriver(screenSize, fullscreen, stencilBuffer, + io, vsync, antiAlias); +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_USE_SDL_DEVICE_ + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_OPENGL_ + diff --git a/src/dep/src/irrlicht/COpenGLDriver.h b/src/dep/src/irrlicht/COpenGLDriver.h new file mode 100644 index 0000000..922d2ac --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLDriver.h @@ -0,0 +1,370 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_VIDEO_OPEN_GL_H_INCLUDED__ +#define __C_VIDEO_OPEN_GL_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "CNullDriver.h" +#include "IMaterialRendererServices.h" +#include "COpenGLExtensionHandler.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#if defined(_IRR_WINDOWS_API_) + // include windows headers for HWND + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#ifdef _MSC_VER + #pragma comment(lib, "OpenGL32.lib") + #pragma comment(lib, "GLu32.lib") +#endif +#elif defined(MACOSX) + #include "CIrrDeviceMacOSX.h" + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #endif + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #endif +#elif defined(_IRR_USE_SDL_DEVICE_) + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #include + #define NO_SDL_GLEXT + #include "glext.h" +#else + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #include + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #undef GLX_ARB_get_proc_address // avoid problems with local glxext.h + #include "glxext.h" + #endif +#endif + +namespace irr +{ +namespace video +{ + class COpenGLTexture; + + class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler + { + public: + + #ifdef _IRR_WINDOWS_API_ + //! win32 constructor + COpenGLDriver(const core::dimension2d& screenSize, HWND window, bool fullscreen, + bool stencilBuffer, io::IFileSystem* io, bool antiAlias); + + //! inits the windows specific parts of the open gl driver + bool initDriver(const core::dimension2d& screenSize, HWND window, + u32 bits, bool fullscreen, bool vsync, bool stencilBuffer); + #endif + + #ifdef _IRR_USE_LINUX_DEVICE_ + COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, + bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias); + #endif + + #ifdef MACOSX + COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, + bool stencilBuffer, CIrrDeviceMacOSX *device,io::IFileSystem* io, bool vsync, bool antiAlias); + #endif + + #ifdef _IRR_USE_SDL_DEVICE_ + COpenGLDriver(const core::dimension2d& screenSize, bool fullscreen, + bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias); + #endif + + //! destructor + virtual ~COpenGLDriver(); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene( s32 windowId, core::rect* sourceRect=0 ); + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const + { + return COpenGLExtensionHandler::queryFeature(feature); + } + + //! Sets a material. All 3d drawing functions draw geometry now + //! using this material. + //! \param material: Material to be used from now on. + virtual void setMaterial(const SMaterial& material); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! draws a set of 2d images, using a color and the alpha + /** channel of the texture if desired. The images are drawn + beginning at pos and concatenated in one line. All drawings + are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects + and are chosen by the indices given. + \param texture: Texture to be drawn. + \param pos: Upper left 2d destination position where the image will be drawn. + \param sourceRects: Source rectangles of the image. + \param indices: List of indices which choose the actual rectangle used each time. + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be 0. Then the image is not clipped. + \param color: Color with which the image is colored. + Note that the alpha component is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + const core::rect* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, + SColor color = SColor(255,255,255,255)); + + //! \return Returns the name of the video driver. Example: In case of the Direct3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light + virtual void addDynamicLight(const SLight& light); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do + //! this: First, draw all geometry. Then use this method, to draw the shadow + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! Sets the fog mode. + virtual void setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates); + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! sets the current Texture + //! Returns whether setting was a success or not. + bool setTexture(u32 stage, const video::ITexture* texture); + + //! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. + //! Returns whether disabling was successful or not. + bool disableTextures(u32 fromStage=0); + + //! Adds a new material renderer to the VideoDriver, using extGLGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status) pixel and/or + //! vertex shaders to render geometry. + virtual s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData); + + //! Adds a new material renderer to the VideoDriver, using GLSL to render geometry. + virtual s32 addHighLevelShaderMaterial(const c8* vertexShaderProgram, const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, const c8* pixelShaderProgram, const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, + s32 userData); + + //! Returns pointer to the IGPUProgrammingServices interface. + virtual IGPUProgrammingServices* getGPUProgrammingServices(); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! checks if an OpenGL error has happend and prints it + //! for performance reasons only available in debug mode + bool testGLError(); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + private: + + void uploadClipPlane(u32 index); + + //! inits the parts of the open gl driver used on all platforms + bool genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer); + //! returns a device dependent texture from a software surface (IImage) + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name); + + //! creates a transposed matrix in supplied GLfloat array to pass to OpenGL + inline void createGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m); + inline void createGLTextureMatrix(GLfloat gl_matrix[16], const core::matrix4& m); + + //! sets the needed renderstates + void setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + // returns the current size of the screen or rendertarget + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + void createMaterialRenderers(); + + core::stringw Name; + core::matrix4 Matrices[ETS_COUNT]; + core::array ColorBuffer; + + //! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D // 3d rendering mode + }; + + E_RENDER_MODE CurrentRenderMode; + //! bool to make all renderstates reset if set to true. + bool ResetRenderStates; + bool Transformation3DChanged; + bool AntiAlias; + + SMaterial Material, LastMaterial; + COpenGLTexture* RenderTargetTexture; + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + s32 LastSetLight; + core::array UserClipPlane; + core::array UserClipPlaneEnabled; + + core::dimension2d CurrentRendertargetSize; + + #ifdef _IRR_WINDOWS_API_ + HDC HDc; // Private GDI Device Context + HWND Window; + HGLRC HRc; // Permanent Rendering Context + #elif defined(_IRR_USE_LINUX_DEVICE_) + GLXDrawable XWindow; + Display* XDisplay; + #elif defined(MACOSX) + CIrrDeviceMacOSX *_device; + #endif + }; + +} // end namespace video +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_OPENGL_ +#endif + + diff --git a/src/dep/src/irrlicht/COpenGLExtensionHandler.cpp b/src/dep/src/irrlicht/COpenGLExtensionHandler.cpp new file mode 100644 index 0000000..6a42bdb --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLExtensionHandler.cpp @@ -0,0 +1,430 @@ +#include "COpenGLExtensionHandler.h" +#include "irrString.h" +#include "SMaterial.h" // for MATERIAL_MAX_TEXTURES +#include "fast_atof.h" + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +namespace irr +{ +namespace video +{ + +COpenGLExtensionHandler::COpenGLExtensionHandler() : + StencilBuffer(false), + MultiTextureExtension(false), MultiSamplingExtension(false), AnisotropyExtension(false), + SeparateStencilExtension(false), + TextureCompressionExtension(false), + PackedDepthStencilExtension(false), + MaxTextureUnits(1), MaxLights(1), MaxIndices(65535), + MaxAnisotropy(1.0f), MaxUserClipPlanes(0), + Version(0), ShaderLanguageVersion(0) +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + ,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0), + pGlGenProgramsARB(0), pGlBindProgramARB(0), pGlProgramStringARB(0), + pGlDeleteProgramsARB(0), pGlProgramLocalParameter4fvARB(0), + pGlCreateShaderObjectARB(0), pGlShaderSourceARB(0), + pGlCompileShaderARB(0), pGlCreateProgramObjectARB(0), pGlAttachObjectARB(0), + pGlLinkProgramARB(0), pGlUseProgramObjectARB(0), pGlDeleteObjectARB(0), + pGlGetObjectParameterivARB(0), pGlGetUniformLocationARB(0), + pGlUniform1ivARB(0), pGlUniform1fvARB(0), pGlUniform2fvARB(0), pGlUniform3fvARB(0), pGlUniform4fvARB(0), pGlUniformMatrix2fvARB(0), + pGlUniformMatrix3fvARB(0), pGlUniformMatrix4fvARB(0), pGlGetActiveUniformARB(0), pGlPointParameterfARB(0), pGlPointParameterfvARB(0), + pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0), + pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0), + pGlCompressedTexImage2D(0), +#ifdef _IRR_USE_WINDOWS_DEVICE_ + wglSwapIntervalEXT(0), +#elif defined(GLX_SGI_swap_control) + glxSwapIntervalSGI(0), +#endif + pGlBindFramebufferEXT(0), pGlDeleteFramebuffersEXT(0), pGlGenFramebuffersEXT(0), + pGlCheckFramebufferStatusEXT(0), pGlFramebufferTexture2DEXT(0), + pGlBindRenderbufferEXT(0), pGlDeleteRenderbuffersEXT(0), pGlGenRenderbuffersEXT(0), + pGlRenderbufferStorageEXT(0), pGlFramebufferRenderbufferEXT(0) +#endif // _IRR_OPENGL_USE_EXTPOINTER_ +{ + for (u32 i=0; i(glGetString(GL_VERSION))); + Version = core::floor32(ogl_ver)*100+core::ceil32(core::fract(ogl_ver)*10.0f); + if ( Version >= 102) + os::Printer::log("OpenGL driver version is 1.2 or better.", ELL_INFORMATION); + else + os::Printer::log("OpenGL driver version is not 1.2 or better.", ELL_WARNING); + + { + const char* t = reinterpret_cast(glGetString(GL_EXTENSIONS)); + const size_t len = strlen(t); + c8 *str = new c8[len+1]; + c8* p = str; + + for (size_t i=0; i(t[i]); + + if (str[i] == ' ') + { + str[i] = 0; + for (u32 j=0; j(x)) + #else + // Accessing the correct function is quite complex + // All libraries should support the ARB version, however + // since GLX 1.4 the non-ARB version is the official one + // So we have to check the runtime environment and + // choose the proper symbol + // In case you still have problems please enable the + // next line by uncommenting it + // #define _IRR_GETPROCADDRESS_WORKAROUND_ + + #ifndef _IRR_GETPROCADDRESS_WORKAROUND_ + __GLXextFuncPtr (*IRR_OGL_LOAD_EXTENSION)(const GLubyte*)=0; + #ifdef GLX_VERSION_1_4 + int major,minor; + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if ((major>1) || (minor>3)) + IRR_OGL_LOAD_EXTENSION=glXGetProcAddress; + else + #endif + IRR_OGL_LOAD_EXTENSION=glXGetProcAddressARB; + #else + #define IRR_OGL_LOAD_EXTENSION glXGetProcAddressARB + #endif + #endif + + pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glActiveTextureARB")); + + pGlClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glClientActiveTextureARB")); + + // get fragment and vertex program function pointers + pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenProgramsARB")); + + pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindProgramARB")); + + pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glProgramStringARB")); + + pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSNVPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteProgramsARB")); + + pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glProgramLocalParameter4fvARB")); + + pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCreateShaderObjectARB")); + + pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glShaderSourceARB")); + + pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCompileShaderARB")); + + pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCreateProgramObjectARB")); + + pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glAttachObjectARB")); + + pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glLinkProgramARB")); + + pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUseProgramObjectARB")); + + pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteObjectARB")); + + pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetInfoLogARB")); + + pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetObjectParameterivARB")); + + pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetUniformLocationARB")); + + pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform4fvARB")); + + pGlUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform1ivARB")); + + pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform1fvARB")); + + pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform2fvARB")); + + pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform3fvARB")); + + pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniform4fvARB")); + + pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix2fvARB")); + + pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix3fvARB")); + + pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glUniformMatrix4fvARB")); + + pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGetActiveUniformARB")); + + // get point parameter extension + pGlPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glPointParameterfARB")); + pGlPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glPointParameterfvARB")); + + // get stencil extension + pGlStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilFuncSeparate")); + pGlStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilOpSeparate")); + pGlStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilFuncSeparateATI")); + pGlStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glStencilOpSeparateATI")); + + // compressed textures + pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCompressedTexImage2D")); + + #if defined(GLX_SGI_swap_control) && !defined(_IRR_USE_SDL_DEVICE_) + // get vsync extension + glxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glXSwapIntervalSGI")); + #endif + + // FrameBufferObjects + pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindFramebufferEXT")); + + pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteFramebuffersEXT")); + + pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenFramebuffersEXT")); + + pGlCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glCheckFramebufferStatusEXT")); + + pGlFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glFramebufferTexture2DEXT")); + + pGlBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glBindRenderbufferEXT")); + + pGlDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDeleteRenderbuffersEXT")); + + pGlGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glGenRenderbuffersEXT")); + + pGlRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glRenderbufferStorageEXT")); + + pGlFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glFramebufferRenderbufferEXT")); + + #endif // _IRR_OPENGL_USE_EXTPOINTER_ +#endif // _IRR_WINDOWS_API_ + + // set some properties +#if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3) + if (Version>102 || FeatureAvailable[IRR_ARB_multitexture]) + { + GLint num; + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num); + MaxTextureUnits=num; + } +#endif + glGetIntegerv(GL_MAX_LIGHTS, &MaxLights); +#ifdef GL_EXT_texture_filter_anisotropic + if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic]) + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisotropy); +#endif +#ifdef GL_VERSION_1_2 + if (Version>101) + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &MaxIndices); +#endif + glGetIntegerv(GL_MAX_CLIP_PLANES, reinterpret_cast(&MaxUserClipPlanes)); +#if defined(GL_ARB_shading_language_100) || defined (GL_VERSION_2_0) + if (FeatureAvailable[IRR_ARB_shading_language_100] || Version>=200) + { + glGetError(); // clean error buffer +#ifdef GL_SHADING_LANGUAGE_VERSION + const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); +#else + const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); +#endif + if (glGetError() == GL_INVALID_ENUM) + ShaderLanguageVersion = 100; + else + { + const f32 sl_ver = core::fast_atof(reinterpret_cast(shaderVersion)); + ShaderLanguageVersion = core::floor32(sl_ver)*100+core::ceil32(core::fract(sl_ver)*10.0f); + } + } +#endif + +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (!pGlActiveTextureARB || !pGlClientActiveTextureARB) + { + MultiTextureExtension = false; + os::Printer::log("Failed to load OpenGL's multitexture extension, proceeding without.", ELL_WARNING); + } + else +#endif + if (MaxTextureUnits < 2) + { + MultiTextureExtension = false; + os::Printer::log("Warning: OpenGL device only has one texture unit. Disabling multitexturing.", ELL_WARNING); + } + MaxTextureUnits = core::min_(MaxTextureUnits,MATERIAL_MAX_TEXTURES); + +} + +bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_RENDER_TO_TARGET: + return true; + case EVDF_MULTITEXTURE: + return MultiTextureExtension; + case EVDF_BILINEAR_FILTER: + return true; + case EVDF_MIP_MAP: + return true; + case EVDF_MIP_MAP_AUTO_UPDATE: + return FeatureAvailable[IRR_SGIS_generate_mipmap]; + case EVDF_STENCIL_BUFFER: + return StencilBuffer; + case EVDF_ARB_VERTEX_PROGRAM_1: + return FeatureAvailable[IRR_ARB_vertex_program]; + case EVDF_ARB_FRAGMENT_PROGRAM_1: + return FeatureAvailable[IRR_ARB_fragment_program]; + case EVDF_ARB_GLSL: + return FeatureAvailable[IRR_ARB_shading_language_100]; + case EVDF_TEXTURE_NPOT: + return FeatureAvailable[IRR_ARB_texture_non_power_of_two]; + case EVDF_FRAMEBUFFER_OBJECT: + return FeatureAvailable[IRR_EXT_framebuffer_object]; + default: + return false; + }; +} + + +} +} + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLExtensionHandler.h b/src/dep/src/irrlicht/COpenGLExtensionHandler.h new file mode 100644 index 0000000..76be7d2 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLExtensionHandler.h @@ -0,0 +1,1330 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_OPEN_GL_FEATURE_MAP_H_INCLUDED__ +#define __C_OPEN_GL_FEATURE_MAP_H_INCLUDED__ + +#include "EDriverFeatures.h" +#include "irrTypes.h" +#include "os.h" + +#if defined(_IRR_WINDOWS_API_) + // include windows headers for HWND + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#ifdef _MSC_VER + #pragma comment(lib, "OpenGL32.lib") +#endif +#elif defined(MACOSX) + #include "CIrrDeviceMacOSX.h" + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #endif + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #endif +#elif defined(_IRR_USE_SDL_DEVICE_) + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #include + #define NO_SDL_GLEXT + #include "glext.h" +#else + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #include + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #undef GLX_ARB_get_proc_address // avoid problems with local glxext.h + #include "glxext.h" + #endif +#endif + + +namespace irr +{ +namespace video +{ + +static const char* const OpenGLFeatureStrings[] = { + "GL_3DFX_multisample", + "GL_3DFX_tbuffer", + "GL_3DFX_texture_compression_FXT1", + "GL_APPLE_client_storage", + "GL_APPLE_element_array", + "GL_APPLE_fence", + "GL_APPLE_flush_buffer_range", + "GL_APPLE_specular_vector", + "GL_APPLE_transform_hint", + "GL_APPLE_vertex_array_object", + "GL_APPLE_vertex_array_range", + "GL_APPLE_ycbcr_422", + "GL_ARB_color_buffer_float", + "GL_ARB_depth_texture", + "GL_ARB_draw_buffers", + "GL_ARB_fragment_program", + "GL_ARB_fragment_program_shadow", + "GL_ARB_fragment_shader", + "GL_ARB_half_float_pixel", + "GL_ARB_imaging", + "GL_ARB_matrix_palette", + "GL_ARB_multisample", + "GL_ARB_multitexture", + "GL_ARB_occlusion_query", + "GL_ARB_pixel_buffer_object", + "GL_ARB_point_parameters", + "GL_ARB_point_sprite", + "GL_ARB_shader_objects", + "GL_ARB_shading_language_100", + "GL_ARB_shadow", + "GL_ARB_shadow_ambient", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_compression", + "GL_ARB_texture_cube_map", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_crossbar", + "GL_ARB_texture_env_dot3", + "GL_ARB_texture_float", + "GL_ARB_texture_mirrored_repeat", + "GL_ARB_texture_non_power_of_two", + "GL_ARB_texture_rectangle", + "GL_ARB_transpose_matrix", + "GL_ARB_vertex_blend", + "GL_ARB_vertex_buffer_object", + "GL_ARB_vertex_program", + "GL_ARB_vertex_shader", + "GL_ARB_window_pos", + "GL_ATI_draw_buffers", + "GL_ATI_element_array", + "GL_ATI_envmap_bumpmap", + "GL_ATI_fragment_shader", + "GL_ATI_map_object_buffer", + "GL_ATI_pixel_format_float", + "GL_ATI_pn_triangles", + "GL_ATI_separate_stencil", + "GL_ATI_text_fragment_shader", + "GL_ATI_texture_env_combine3", + "GL_ATI_texture_float", + "GL_ATI_texture_mirror_once", + "GL_ATI_vertex_array_object", + "GL_ATI_vertex_attrib_array_object", + "GL_ATI_vertex_streams", + "GL_EXT_422_pixels", + "GL_EXT_abgr", + "GL_EXT_bgra", + "GL_EXT_bindable_uniform", + "GL_EXT_blend_color", + "GL_EXT_blend_equation_separate", + "GL_EXT_blend_func_separate", + "GL_EXT_blend_logic_op", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_clip_volume_hint", + "GL_EXT_cmyka", + "GL_EXT_color_subtable", + "GL_EXT_compiled_vertex_array", + "GL_EXT_convolution", + "GL_EXT_coordinate_frame", + "GL_EXT_copy_texture", + "GL_EXT_cull_vertex", + "GL_EXT_depth_bounds_test", + "GL_EXT_draw_buffers2", + "GL_EXT_draw_instanced", + "GL_EXT_draw_range_elements", + "GL_EXT_fog_coord", + "GL_EXT_framebuffer_blit", + "GL_EXT_framebuffer_multisample", + "GL_EXT_framebuffer_object", + "GL_EXT_framebuffer_sRGB", + "GL_EXT_geometry_shader4", + "GL_EXT_gpu_program_parameters", + "GL_EXT_gpu_shader4", + "GL_EXT_histogram", + "GL_EXT_index_array_formats", + "GL_EXT_index_func", + "GL_EXT_index_material", + "GL_EXT_index_texture", + "GL_EXT_light_texture", + "GL_EXT_misc_attribute", + "GL_EXT_multi_draw_arrays", + "GL_EXT_multisample", + "GL_EXT_packed_depth_stencil", + "GL_EXT_packed_float", + "GL_EXT_packed_pixels", + "GL_EXT_paletted_texture", + "GL_EXT_pixel_buffer_object", + "GL_EXT_pixel_transform", + "GL_EXT_pixel_transform_color_table", + "GL_EXT_point_parameters", + "GL_EXT_polygon_offset", + "GL_EXT_rescale_normal", + "GL_EXT_secondary_color", + "GL_EXT_separate_specular_color", + "GL_EXT_shadow_funcs", + "GL_EXT_shared_texture_palette", + "GL_EXT_stencil_clear_tag", + "GL_EXT_stencil_two_side", + "GL_EXT_stencil_wrap", + "GL_EXT_subtexture", + "GL_EXT_texture", + "GL_EXT_texture3D", + "GL_EXT_texture_array", + "GL_EXT_texture_buffer_object", + "GL_EXT_texture_compression_latc", + "GL_EXT_texture_compression_rgtc", + "GL_EXT_texture_compression_s3tc", + "GL_EXT_texture_cube_map", + "GL_EXT_texture_env_add", + "GL_EXT_texture_env_combine", + "GL_EXT_texture_env_dot3", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_integer", + "GL_EXT_texture_lod_bias", + "GL_EXT_texture_mirror_clamp", + "GL_EXT_texture_object", + "GL_EXT_texture_perturb_normal", + "GL_EXT_texture_shared_exponent", + "GL_EXT_texture_sRGB", + "GL_EXT_timer_query", + "GL_EXT_vertex_array", + "GL_EXT_vertex_shader", + "GL_EXT_vertex_weighting", + "GL_FfdMaskSGIX", + "GL_GREMEDY_string_marker", + "GL_HP_convolution_border_modes", + "GL_HP_image_transform", + "GL_HP_occlusion_test", + "GL_HP_texture_lighting", + "GL_IBM_cull_vertex", + "GL_IBM_multimode_draw_arrays", + "GL_IBM_rasterpos_clip", + "GL_IBM_texture_mirrored_repeat", + "GL_IBM_vertex_array_lists", + "GL_INGR_blend_func_separate", + "GL_INGR_color_clamp", + "GL_INGR_interlace_read", + "GL_INGR_palette_buffer", + "GL_INTEL_parallel_arrays", + "GL_INTEL_texture_scissor", + "GL_MESA_pack_invert", + "GL_MESA_resize_buffers", + "GL_MESA_window_pos", + "GL_MESAX_texture_stack", + "GL_MESA_ycbcr_texture", + "GL_NV_blend_square", + "GL_NV_copy_depth_to_color", + "GL_NV_depth_buffer_float", + "GL_NV_depth_clamp", + "GL_NV_evaluators", + "GL_NV_fence", + "GL_NV_float_buffer", + "GL_NV_fog_distance", + "GL_NV_fragment_program", + "GL_NV_fragment_program2", + "GL_NV_fragment_program4", + "GL_NV_fragment_program_option", + "GL_NV_framebuffer_multisample_coverage", + "GL_NV_geometry_program4", + "GL_NV_geometry_shader4", + "GL_NV_gpu_program4", + "GL_NV_half_float", + "GL_NV_light_max_exponent", + "GL_NV_multisample_filter_hint", + "GL_NV_occlusion_query", + "GL_NV_packed_depth_stencil", + "GL_NV_parameter_buffer_object", + "GL_NV_pixel_data_range", + "GL_NV_point_sprite", + "GL_NV_primitive_restart", + "GL_NV_register_combiners", + "GL_NV_register_combiners2", + "GL_NV_texgen_emboss", + "GL_NV_texgen_reflection", + "GL_NV_texture_compression_vtc", + "GL_NV_texture_env_combine4", + "GL_NV_texture_expand_normal", + "GL_NV_texture_rectangle", + "GL_NV_texture_shader", + "GL_NV_texture_shader2", + "GL_NV_texture_shader3", + "GL_NV_transform_feedback", + "GL_NV_vertex_array_range", + "GL_NV_vertex_array_range2", + "GL_NV_vertex_program", + "GL_NV_vertex_program1_1", + "GL_NV_vertex_program2", + "GL_NV_vertex_program2_option", + "GL_NV_vertex_program3", + "GL_NV_vertex_program4", + "GL_OES_read_format", + "GL_OML_interlace", + "GL_OML_resample", + "GL_OML_subsample", + "GL_PGI_misc_hints", + "GL_PGI_vertex_hints", + "GL_REND_screen_coordinates", + "GL_S3_s3tc", + "GL_SGI_color_matrix", + "GL_SGI_color_table", + "GL_SGI_depth_pass_instrument", + "GL_SGIS_detail_texture", + "GL_SGIS_fog_function", + "GL_SGIS_generate_mipmap", + "GL_SGIS_multisample", + "GL_SGIS_pixel_texture", + "GL_SGIS_point_line_texgen", + "GL_SGIS_point_parameters", + "GL_SGIS_sharpen_texture", + "GL_SGIS_texture4D", + "GL_SGIS_texture_border_clamp", + "GL_SGIS_texture_color_mask", + "GL_SGIS_texture_edge_clamp", + "GL_SGIS_texture_filter4", + "GL_SGIS_texture_lod", + "GL_SGIS_texture_select", + "GL_SGI_texture_color_table", + "GL_SGIX_async", + "GL_SGIX_async_histogram", + "GL_SGIX_async_pixel", + "GL_SGIX_blend_alpha_minmax", + "GL_SGIX_calligraphic_fragment", + "GL_SGIX_clipmap", + "GL_SGIX_convolution_accuracy", + "GL_SGIX_depth_pass_instrument", + "GL_SGIX_depth_texture", + "GL_SGIX_flush_raster", + "GL_SGIX_fog_offset", + "GL_SGIX_fog_scale", + "GL_SGIX_fragment_lighting", + "GL_SGIX_framezoom", + "GL_SGIX_igloo_interface", + "GL_SGIX_impact_pixel_texture", + "GL_SGIX_instruments", + "GL_SGIX_interlace", + "GL_SGIX_ir_instrument1", + "GL_SGIX_list_priority", + "GL_SGIX_pixel_texture", + "GL_SGIX_pixel_tiles", + "GL_SGIX_polynomial_ffd", + "GL_SGIX_reference_plane", + "GL_SGIX_resample", + "GL_SGIX_scalebias_hint", + "GL_SGIX_shadow", + "GL_SGIX_shadow_ambient", + "GL_SGIX_sprite", + "GL_SGIX_subsample", + "GL_SGIX_tag_sample_buffer", + "GL_SGIX_texture_add_env", + "GL_SGIX_texture_coordinate_clamp", + "GL_SGIX_texture_lod_bias", + "GL_SGIX_texture_multi_buffer", + "GL_SGIX_texture_scale_bias", + "GL_SGIX_texture_select", + "GL_SGIX_vertex_preclip", + "GL_SGIX_ycrcb", + "GL_SGIX_ycrcba", + "GL_SGIX_ycrcb_subsample", + "GL_SUN_convolution_border_modes", + "GL_SUN_global_alpha", + "GL_SUN_mesh_array", + "GL_SUN_slice_accum", + "GL_SUN_triangle_list", + "GL_SUN_vertex", + "GL_SUNX_constant_data", + "GL_WIN_phong_shading", + "GL_WIN_specular_fog" +}; + + +class COpenGLExtensionHandler +{ + public: + enum EOpenGLFeatures { + IRR_3DFX_multisample = 0, + IRR_3DFX_tbuffer, + IRR_3DFX_texture_compression_FXT1, + IRR_APPLE_client_storage, + IRR_APPLE_element_array, + IRR_APPLE_fence, + IRR_APPLE_flush_buffer_range, + IRR_APPLE_specular_vector, + IRR_APPLE_transform_hint, + IRR_APPLE_vertex_array_object, + IRR_APPLE_vertex_array_range, + IRR_APPLE_ycbcr_422, + IRR_ARB_color_buffer_float, + IRR_ARB_depth_texture, + IRR_ARB_draw_buffers, + IRR_ARB_fragment_program, + IRR_ARB_fragment_program_shadow, + IRR_ARB_fragment_shader, + IRR_ARB_half_float_pixel, + IRR_ARB_imaging, + IRR_ARB_matrix_palette, + IRR_ARB_multisample, + IRR_ARB_multitexture, + IRR_ARB_occlusion_query, + IRR_ARB_pixel_buffer_object, + IRR_ARB_point_parameters, + IRR_ARB_point_sprite, + IRR_ARB_shader_objects, + IRR_ARB_shading_language_100, + IRR_ARB_shadow, + IRR_ARB_shadow_ambient, + IRR_ARB_texture_border_clamp, + IRR_ARB_texture_compression, + IRR_ARB_texture_cube_map, + IRR_ARB_texture_env_add, + IRR_ARB_texture_env_combine, + IRR_ARB_texture_env_crossbar, + IRR_ARB_texture_env_dot3, + IRR_ARB_texture_float, + IRR_ARB_texture_mirrored_repeat, + IRR_ARB_texture_non_power_of_two, + IRR_ARB_texture_rectangle, + IRR_ARB_transpose_matrix, + IRR_ARB_vertex_blend, + IRR_ARB_vertex_buffer_object, + IRR_ARB_vertex_program, + IRR_ARB_vertex_shader, + IRR_ARB_window_pos, + IRR_ATI_draw_buffers, + IRR_ATI_element_array, + IRR_ATI_envmap_bumpmap, + IRR_ATI_fragment_shader, + IRR_ATI_map_object_buffer, + IRR_ATI_pixel_format_float, + IRR_ATI_pn_triangles, + IRR_ATI_separate_stencil, + IRR_ATI_text_fragment_shader, + IRR_ATI_texture_env_combine3, + IRR_ATI_texture_float, + IRR_ATI_texture_mirror_once, + IRR_ATI_vertex_array_object, + IRR_ATI_vertex_attrib_array_object, + IRR_ATI_vertex_streams, + IRR_EXT_422_pixels, + IRR_EXT_abgr, + IRR_EXT_bgra, + IRR_EXT_bindable_uniform, + IRR_EXT_blend_color, + IRR_EXT_blend_equation_separate, + IRR_EXT_blend_func_separate, + IRR_EXT_blend_logic_op, + IRR_EXT_blend_minmax, + IRR_EXT_blend_subtract, + IRR_EXT_clip_volume_hint, + IRR_EXT_cmyka, + IRR_EXT_color_subtable, + IRR_EXT_compiled_vertex_array, + IRR_EXT_convolution, + IRR_EXT_coordinate_frame, + IRR_EXT_copy_texture, + IRR_EXT_cull_vertex, + IRR_EXT_depth_bounds_test, + IRR_EXT_draw_buffers2, + IRR_EXT_draw_instanced, + IRR_EXT_draw_range_elements, + IRR_EXT_fog_coord, + IRR_EXT_framebuffer_blit, + IRR_EXT_framebuffer_multisample, + IRR_EXT_framebuffer_object, + IRR_EXT_framebuffer_sRGB, + IRR_EXT_geometry_shader4, + IRR_EXT_gpu_program_parameters, + IRR_EXT_gpu_shader4, + IRR_EXT_histogram, + IRR_EXT_index_array_formats, + IRR_EXT_index_func, + IRR_EXT_index_material, + IRR_EXT_index_texture, + IRR_EXT_light_texture, + IRR_EXT_misc_attribute, + IRR_EXT_multi_draw_arrays, + IRR_EXT_multisample, + IRR_EXT_packed_depth_stencil, + IRR_EXT_packed_float, + IRR_EXT_packed_pixels, + IRR_EXT_paletted_texture, + IRR_EXT_pixel_buffer_object, + IRR_EXT_pixel_transform, + IRR_EXT_pixel_transform_color_table, + IRR_EXT_point_parameters, + IRR_EXT_polygon_offset, + IRR_EXT_rescale_normal, + IRR_EXT_secondary_color, + IRR_EXT_separate_specular_color, + IRR_EXT_shadow_funcs, + IRR_EXT_shared_texture_palette, + IRR_EXT_stencil_clear_tag, + IRR_EXT_stencil_two_side, + IRR_EXT_stencil_wrap, + IRR_EXT_subtexture, + IRR_EXT_texture, + IRR_EXT_texture3D, + IRR_EXT_texture_array, + IRR_EXT_texture_buffer_object, + IRR_EXT_texture_compression_latc, + IRR_EXT_texture_compression_rgtc, + IRR_EXT_texture_compression_s3tc, + IRR_EXT_texture_cube_map, + IRR_EXT_texture_env_add, + IRR_EXT_texture_env_combine, + IRR_EXT_texture_env_dot3, + IRR_EXT_texture_filter_anisotropic, + IRR_EXT_texture_integer, + IRR_EXT_texture_lod_bias, + IRR_EXT_texture_mirror_clamp, + IRR_EXT_texture_object, + IRR_EXT_texture_perturb_normal, + IRR_EXT_texture_shared_exponent, + IRR_EXT_texture_sRGB, + IRR_EXT_timer_query, + IRR_EXT_vertex_array, + IRR_EXT_vertex_shader, + IRR_EXT_vertex_weighting, + IRR_FfdMaskSGIX, + IRR_GREMEDY_string_marker, + IRR_HP_convolution_border_modes, + IRR_HP_image_transform, + IRR_HP_occlusion_test, + IRR_HP_texture_lighting, + IRR_IBM_cull_vertex, + IRR_IBM_multimode_draw_arrays, + IRR_IBM_rasterpos_clip, + IRR_IBM_texture_mirrored_repeat, + IRR_IBM_vertex_array_lists, + IRR_INGR_blend_func_separate, + IRR_INGR_color_clamp, + IRR_INGR_interlace_read, + IRR_INGR_palette_buffer, + IRR_INTEL_parallel_arrays, + IRR_INTEL_texture_scissor, + IRR_MESA_pack_invert, + IRR_MESA_resize_buffers, + IRR_MESA_window_pos, + IRR_MESAX_texture_stack, + IRR_MESA_ycbcr_texture, + IRR_NV_blend_square, + IRR_NV_copy_depth_to_color, + IRR_NV_depth_buffer_float, + IRR_NV_depth_clamp, + IRR_NV_evaluators, + IRR_NV_fence, + IRR_NV_float_buffer, + IRR_NV_fog_distance, + IRR_NV_fragment_program, + IRR_NV_fragment_program2, + IRR_NV_fragment_program4, + IRR_NV_fragment_program_option, + IRR_NV_framebuffer_multisample_coverage, + IRR_NV_geometry_program4, + IRR_NV_geometry_shader4, + IRR_NV_gpu_program4, + IRR_NV_half_float, + IRR_NV_light_max_exponent, + IRR_NV_multisample_filter_hint, + IRR_NV_occlusion_query, + IRR_NV_packed_depth_stencil, + IRR_NV_parameter_buffer_object, + IRR_NV_pixel_data_range, + IRR_NV_point_sprite, + IRR_NV_primitive_restart, + IRR_NV_register_combiners, + IRR_NV_register_combiners2, + IRR_NV_texgen_emboss, + IRR_NV_texgen_reflection, + IRR_NV_texture_compression_vtc, + IRR_NV_texture_env_combine4, + IRR_NV_texture_expand_normal, + IRR_NV_texture_rectangle, + IRR_NV_texture_shader, + IRR_NV_texture_shader2, + IRR_NV_texture_shader3, + IRR_NV_transform_feedback, + IRR_NV_vertex_array_range, + IRR_NV_vertex_array_range2, + IRR_NV_vertex_program, + IRR_NV_vertex_program1_1, + IRR_NV_vertex_program2, + IRR_NV_vertex_program2_option, + IRR_NV_vertex_program3, + IRR_NV_vertex_program4, + IRR_OES_read_format, + IRR_OML_interlace, + IRR_OML_resample, + IRR_OML_subsample, + IRR_PGI_misc_hints, + IRR_PGI_vertex_hints, + IRR_REND_screen_coordinates, + IRR_S3_s3tc, + IRR_SGI_color_matrix, + IRR_SGI_color_table, + IRR_SGI_depth_pass_instrument, + IRR_SGIS_detail_texture, + IRR_SGIS_fog_function, + IRR_SGIS_generate_mipmap, + IRR_SGIS_multisample, + IRR_SGIS_pixel_texture, + IRR_SGIS_point_line_texgen, + IRR_SGIS_point_parameters, + IRR_SGIS_sharpen_texture, + IRR_SGIS_texture4D, + IRR_SGIS_texture_border_clamp, + IRR_SGIS_texture_color_mask, + IRR_SGIS_texture_edge_clamp, + IRR_SGIS_texture_filter4, + IRR_SGIS_texture_lod, + IRR_SGIS_texture_select, + IRR_SGI_texture_color_table, + IRR_SGIX_async, + IRR_SGIX_async_histogram, + IRR_SGIX_async_pixel, + IRR_SGIX_blend_alpha_minmax, + IRR_SGIX_calligraphic_fragment, + IRR_SGIX_clipmap, + IRR_SGIX_convolution_accuracy, + IRR_SGIX_depth_pass_instrument, + IRR_SGIX_depth_texture, + IRR_SGIX_flush_raster, + IRR_SGIX_fog_offset, + IRR_SGIX_fog_scale, + IRR_SGIX_fragment_lighting, + IRR_SGIX_framezoom, + IRR_SGIX_igloo_interface, + IRR_SGIX_impact_pixel_texture, + IRR_SGIX_instruments, + IRR_SGIX_interlace, + IRR_SGIX_ir_instrument1, + IRR_SGIX_list_priority, + IRR_SGIX_pixel_texture, + IRR_SGIX_pixel_tiles, + IRR_SGIX_polynomial_ffd, + IRR_SGIX_reference_plane, + IRR_SGIX_resample, + IRR_SGIX_scalebias_hint, + IRR_SGIX_shadow, + IRR_SGIX_shadow_ambient, + IRR_SGIX_sprite, + IRR_SGIX_subsample, + IRR_SGIX_tag_sample_buffer, + IRR_SGIX_texture_add_env, + IRR_SGIX_texture_coordinate_clamp, + IRR_SGIX_texture_lod_bias, + IRR_SGIX_texture_multi_buffer, + IRR_SGIX_texture_scale_bias, + IRR_SGIX_texture_select, + IRR_SGIX_vertex_preclip, + IRR_SGIX_ycrcb, + IRR_SGIX_ycrcba, + IRR_SGIX_ycrcb_subsample, + IRR_SUN_convolution_border_modes, + IRR_SUN_global_alpha, + IRR_SUN_mesh_array, + IRR_SUN_slice_accum, + IRR_SUN_triangle_list, + IRR_SUN_vertex, + IRR_SUNX_constant_data, + IRR_WIN_phong_shading, + IRR_WIN_specular_fog, + IRR_OpenGL_Feature_Count + }; + + // constructor + COpenGLExtensionHandler(); + + // deferred initialization + void initExtensions(bool stencilBuffer); + + //! queries the features of the driver, returns true if feature is available + bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! show all features with availablity + void dump() const; + + // Some variables for properties + bool StencilBuffer; + bool MultiTextureExtension; + bool MultiSamplingExtension; + bool AnisotropyExtension; + bool SeparateStencilExtension; + bool TextureCompressionExtension; + bool PackedDepthStencilExtension; + + // Some non-boolean properties + //! Maxmimum texture layers supported by the fixed pipeline + u32 MaxTextureUnits; + //! Maximum hardware lights supported + GLint MaxLights; + //! Optimal number of indices per meshbuffer + GLint MaxIndices; + //! Maximal Anisotropy + f32 MaxAnisotropy; + //! Number of user clipplanes + u32 MaxUserClipPlanes; + + //! OpenGL version as Integer: 100*Major+Minor, i.e. 2.1 becomes 201 + u32 Version; + //! GLSL version as Integer: 100*Major+Minor + u32 ShaderLanguageVersion; + + // public access to the (loaded) extensions. + // general functions + void extGlActiveTexture(GLenum texture); + void extGlClientActiveTexture(GLenum texture); + void extGlPointParameterf(GLint loc, GLfloat f); + void extGlPointParameterfv(GLint loc, const GLfloat *v); + void extGlStencilFuncSeparate (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); + void extGlStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + void extGlCompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void* data); + + // shader programming + void extGlGenPrograms(GLsizei n, GLuint *programs); + void extGlBindProgram(GLenum target, GLuint program); + void extGlProgramString(GLenum target, GLenum format, GLsizei len, const GLvoid *string); + void extGlDeletePrograms(GLsizei n, const GLuint *programs); + void extGlProgramLocalParameter4fv(GLenum, GLuint, const GLfloat *); + GLhandleARB extGlCreateShaderObject(GLenum shaderType); + void extGlShaderSource(GLhandleARB shader, int numOfStrings, const char **strings, int *lenOfStrings); + void extGlCompileShader(GLhandleARB shader); + GLhandleARB extGlCreateProgramObject(void); + void extGlAttachObject(GLhandleARB program, GLhandleARB shader); + void extGlLinkProgram(GLhandleARB program); + void extGlUseProgramObject(GLhandleARB prog); + void extGlDeleteObject(GLhandleARB object); + void extGlGetInfoLog(GLhandleARB object, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); + void extGlGetObjectParameteriv(GLhandleARB object, GLenum type, int *param); + GLint extGlGetUniformLocation(GLhandleARB program, const char *name); + void extGlUniform4fv(GLint location, GLsizei count, const GLfloat *v); + void extGlUniform1iv(GLint loc, GLsizei count, const GLint *v); + void extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlGetActiveUniform(GLhandleARB program, GLuint index, GLsizei maxlength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); + + // framebuffer objects + void extGlBindFramebuffer(GLenum target, GLuint framebuffer); + void extGlDeleteFramebuffers(GLsizei n, const GLuint *framebuffers); + void extGlGenFramebuffers(GLsizei n, GLuint *framebuffers); + GLenum extGlCheckFramebufferStatus(GLenum target); + void extGlFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + void extGlBindRenderbuffer(GLenum target, GLuint renderbuffer); + void extGlDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); + void extGlGenRenderbuffers(GLsizei n, GLuint *renderbuffers); + void extGlRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void extGlFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + void extGlActiveStencilFace(GLenum face); + + protected: + // the global feature array + bool FeatureAvailable[IRR_OpenGL_Feature_Count]; + + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + PFNGLACTIVETEXTUREARBPROC pGlActiveTextureARB; + PFNGLCLIENTACTIVETEXTUREARBPROC pGlClientActiveTextureARB; + PFNGLGENPROGRAMSARBPROC pGlGenProgramsARB; + PFNGLBINDPROGRAMARBPROC pGlBindProgramARB; + PFNGLPROGRAMSTRINGARBPROC pGlProgramStringARB; + PFNGLDELETEPROGRAMSNVPROC pGlDeleteProgramsARB; + PFNGLPROGRAMLOCALPARAMETER4FVARBPROC pGlProgramLocalParameter4fvARB; + PFNGLCREATESHADEROBJECTARBPROC pGlCreateShaderObjectARB; + PFNGLSHADERSOURCEARBPROC pGlShaderSourceARB; + PFNGLCOMPILESHADERARBPROC pGlCompileShaderARB; + PFNGLCREATEPROGRAMOBJECTARBPROC pGlCreateProgramObjectARB; + PFNGLATTACHOBJECTARBPROC pGlAttachObjectARB; + PFNGLLINKPROGRAMARBPROC pGlLinkProgramARB; + PFNGLUSEPROGRAMOBJECTARBPROC pGlUseProgramObjectARB; + PFNGLDELETEOBJECTARBPROC pGlDeleteObjectARB; + PFNGLGETINFOLOGARBPROC pGlGetInfoLogARB; + PFNGLGETOBJECTPARAMETERIVARBPROC pGlGetObjectParameterivARB; + PFNGLGETUNIFORMLOCATIONARBPROC pGlGetUniformLocationARB; + PFNGLUNIFORM1IVARBPROC pGlUniform1ivARB; + PFNGLUNIFORM1FVARBPROC pGlUniform1fvARB; + PFNGLUNIFORM2FVARBPROC pGlUniform2fvARB; + PFNGLUNIFORM3FVARBPROC pGlUniform3fvARB; + PFNGLUNIFORM4FVARBPROC pGlUniform4fvARB; + PFNGLUNIFORMMATRIX2FVARBPROC pGlUniformMatrix2fvARB; + PFNGLUNIFORMMATRIX3FVARBPROC pGlUniformMatrix3fvARB; + PFNGLUNIFORMMATRIX4FVARBPROC pGlUniformMatrix4fvARB; + PFNGLGETACTIVEUNIFORMARBPROC pGlGetActiveUniformARB; + PFNGLPOINTPARAMETERFARBPROC pGlPointParameterfARB; + PFNGLPOINTPARAMETERFVARBPROC pGlPointParameterfvARB; + PFNGLSTENCILFUNCSEPARATEPROC pGlStencilFuncSeparate; + PFNGLSTENCILOPSEPARATEPROC pGlStencilOpSeparate; + PFNGLSTENCILFUNCSEPARATEATIPROC pGlStencilFuncSeparateATI; + PFNGLSTENCILOPSEPARATEATIPROC pGlStencilOpSeparateATI; + PFNGLCOMPRESSEDTEXIMAGE2DPROC pGlCompressedTexImage2D; + #ifdef _IRR_WINDOWS_API_ + typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int); + PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT; + #elif defined(_IRR_LINUX_PLATFORM_) && defined(GLX_SGI_swap_control) + PFNGLXSWAPINTERVALSGIPROC glxSwapIntervalSGI; + #endif + PFNGLBINDFRAMEBUFFEREXTPROC pGlBindFramebufferEXT; + PFNGLDELETEFRAMEBUFFERSEXTPROC pGlDeleteFramebuffersEXT; + PFNGLGENFRAMEBUFFERSEXTPROC pGlGenFramebuffersEXT; + PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pGlCheckFramebufferStatusEXT; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pGlFramebufferTexture2DEXT; + PFNGLBINDRENDERBUFFEREXTPROC pGlBindRenderbufferEXT; + PFNGLDELETERENDERBUFFERSEXTPROC pGlDeleteRenderbuffersEXT; + PFNGLGENRENDERBUFFERSEXTPROC pGlGenRenderbuffersEXT; + PFNGLRENDERBUFFERSTORAGEEXTPROC pGlRenderbufferStorageEXT; + PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC pGlFramebufferRenderbufferEXT; + PFNGLACTIVESTENCILFACEEXTPROC pGlActiveStencilFaceEXT; + #endif +}; + +inline void COpenGLExtensionHandler::extGlActiveTexture(GLenum texture) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (MultiTextureExtension && pGlActiveTextureARB) + pGlActiveTextureARB(texture); +#else + if (MultiTextureExtension) glActiveTextureARB(texture); +#endif +} + +inline void COpenGLExtensionHandler::extGlClientActiveTexture(GLenum texture) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (MultiTextureExtension && pGlClientActiveTextureARB) + pGlClientActiveTextureARB(texture); +#else + if (MultiTextureExtension) glClientActiveTextureARB(texture); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenPrograms(GLsizei n, GLuint *programs) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenProgramsARB) + pGlGenProgramsARB(n, programs); +#elif defined(GL_ARB_vertex_program) + glGenProgramsARB(n,programs); +#else + os::Printer::log("glGenPrograms not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindProgram(GLenum target, GLuint program) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindProgramARB) + pGlBindProgramARB(target, program); +#elif defined(GL_ARB_vertex_program) + glBindProgramARB(target, program); +#else + os::Printer::log("glBindProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlProgramString(GLenum target, GLenum format, GLsizei len, const GLvoid *string) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlProgramStringARB) + pGlProgramStringARB(target, format, len, string); +#elif defined(GL_ARB_vertex_program) + glProgramStringARB(target,format,len,string); +#else + os::Printer::log("glProgramString not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeletePrograms(GLsizei n, const GLuint *programs) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteProgramsARB) + pGlDeleteProgramsARB(n, programs); +#elif defined(GL_ARB_vertex_program) + glDeleteProgramsARB(n,programs); +#else + os::Printer::log("glDeletePrograms not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlProgramLocalParameter4fv(GLenum n, GLuint i, const GLfloat * f) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlProgramLocalParameter4fvARB) + pGlProgramLocalParameter4fvARB(n,i,f); +#elif defined(GL_ARB_vertex_program) + glProgramLocalParameter4fvARB(n,i,f); +#else + os::Printer::log("glProgramLocalParameter4fv not supported", ELL_ERROR); +#endif +} + +inline GLhandleARB COpenGLExtensionHandler::extGlCreateShaderObject(GLenum shaderType) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateShaderObjectARB) + return pGlCreateShaderObjectARB(shaderType); +#elif defined(GL_ARB_shader_objects) + return glCreateShaderObjectARB(shaderType); +#else + os::Printer::log("glCreateShaderObject not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlShaderSource(GLhandleARB shader, int numOfStrings, const char **strings, int *lenOfStrings) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlShaderSourceARB) + pGlShaderSourceARB(shader, numOfStrings, strings, lenOfStrings); +#elif defined(GL_ARB_shader_objects) + glShaderSourceARB(shader, numOfStrings, strings, (GLint *)lenOfStrings); +#else + os::Printer::log("glShaderSource not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlCompileShader(GLhandleARB shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompileShaderARB) + pGlCompileShaderARB(shader); +#elif defined(GL_ARB_shader_objects) + glCompileShaderARB(shader); +#else + os::Printer::log("glCompileShader not supported", ELL_ERROR); +#endif +} + +inline GLhandleARB COpenGLExtensionHandler::extGlCreateProgramObject(void) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateProgramObjectARB) + return pGlCreateProgramObjectARB(); +#elif defined(GL_ARB_shader_objects) + return glCreateProgramObjectARB(); +#else + os::Printer::log("glCreateProgramObject not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlAttachObject(GLhandleARB program, GLhandleARB shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlAttachObjectARB) + pGlAttachObjectARB(program, shader); +#elif defined(GL_ARB_shader_objects) + glAttachObjectARB(program, shader); +#else + os::Printer::log("glAttachObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlLinkProgram(GLhandleARB program) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlLinkProgramARB) + pGlLinkProgramARB(program); +#elif defined(GL_ARB_shader_objects) + glLinkProgramARB(program); +#else + os::Printer::log("glLinkProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUseProgramObject(GLhandleARB prog) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUseProgramObjectARB) + pGlUseProgramObjectARB(prog); +#elif defined(GL_ARB_shader_objects) + glUseProgramObjectARB(prog); +#else + os::Printer::log("glUseProgramObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteObject(GLhandleARB object) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteObjectARB) + pGlDeleteObjectARB(object); +#elif defined(GL_ARB_shader_objects) + glDeleteObjectARB(object); +#else + os::Printer::log("gldeleteObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetInfoLog(GLhandleARB object, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetInfoLogARB) + pGlGetInfoLogARB(object, maxLength, length, infoLog); +#elif defined(GL_ARB_shader_objects) + glGetInfoLogARB(object, maxLength, length, infoLog); +#else + os::Printer::log("glGetInfoLog not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetObjectParameteriv(GLhandleARB object, GLenum type, int *param) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetObjectParameterivARB) + pGlGetObjectParameterivARB(object, type, param); +#elif defined(GL_ARB_shader_objects) + glGetObjectParameterivARB(object, type, (GLint *)param); +#else + os::Printer::log("glGetObjectParameteriv not supported", ELL_ERROR); +#endif +} + +inline GLint COpenGLExtensionHandler::extGlGetUniformLocation(GLhandleARB program, const char *name) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetUniformLocationARB) + return pGlGetUniformLocationARB(program, name); +#elif defined(GL_ARB_shader_objects) + return glGetUniformLocationARB(program, name); +#else + os::Printer::log("glGetUniformLocation not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform4fvARB) + pGlUniform4fvARB(location, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform4fvARB(location, count, v); +#else + os::Printer::log("glUniform4fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform1iv(GLint loc, GLsizei count, const GLint *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform1ivARB) + pGlUniform1ivARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform1ivARB(loc, count, v); +#else + os::Printer::log("glUniform1iv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform1fvARB) + pGlUniform1fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform1fvARB(loc, count, v); +#else + os::Printer::log("glUniform1fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform2fvARB) + pGlUniform2fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform2fvARB(loc, count, v); +#else + os::Printer::log("glUniform2fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform3fvARB) + pGlUniform3fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform3fvARB(loc, count, v); +#else + os::Printer::log("glUniform3fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix2fvARB) + pGlUniformMatrix2fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix2fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix2fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix3fvARB) + pGlUniformMatrix3fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix3fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix3fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix4fvARB) + pGlUniformMatrix4fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix4fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix4fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetActiveUniform(GLhandleARB program, GLuint index, GLsizei maxlength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetActiveUniformARB) + pGlGetActiveUniformARB(program, index, maxlength, length, size, type, name); +#elif defined(GL_ARB_shader_objects) + glGetActiveUniformARB(program, index, maxlength, length, size, type, name); +#else + os::Printer::log("glGetActiveUniform not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlPointParameterf(GLint loc, GLfloat f) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlPointParameterfARB) + pGlPointParameterfARB(loc, f); +#elif defined(GL_ARB_point_parameters) + glPointParameterfARB(loc, f); +#else + os::Printer::log("glPointParameterf not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlPointParameterfv(GLint loc, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlPointParameterfvARB) + pGlPointParameterfvARB(loc, v); +#elif defined(GL_ARB_point_parameters) + glPointParameterfvARB(loc, v); +#else + os::Printer::log("glPointParameterfv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlStencilFuncSeparate (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlStencilFuncSeparate) + pGlStencilFuncSeparate(frontfunc, backfunc, ref, mask); + else if (pGlStencilFuncSeparateATI) + pGlStencilFuncSeparateATI(frontfunc, backfunc, ref, mask); +#elif defined(GL_VERSION_2_0) + glStencilFuncSeparate(frontfunc, backfunc, ref, mask); +#elif defined(GL_ATI_separate_stencil) + glStencilFuncSeparateATI(frontfunc, backfunc, ref, mask); +#else + os::Printer::log("glStencilFuncSeparate not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlStencilOpSeparate) + pGlStencilOpSeparate(face, fail, zfail, zpass); + else if (pGlStencilOpSeparateATI) + pGlStencilOpSeparateATI(face, fail, zfail, zpass); +#elif defined(GL_VERSION_2_0) + glStencilOpSeparate(face, fail, zfail, zpass); +#elif defined(GL_ATI_separate_stencil) + glStencilOpSeparateATI(face, fail, zfail, zpass); +#else + os::Printer::log("glStencilOpSeparate not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, const void* data) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompressedTexImage2D) + pGlCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +#elif defined(GL_ARB_texture_compression) + glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +#else + os::Printer::log("glCompressedTexImage2D not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindFramebuffer(GLenum target, GLuint framebuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindFramebufferEXT) + pGlBindFramebufferEXT(target, framebuffer); +#elif defined(GL_EXT_framebuffer_object) + glBindFramebufferEXT(target, framebuffer); +#else + os::Printer::log("glBindFramebuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteFramebuffersEXT) + pGlDeleteFramebuffersEXT(n, framebuffers); +#elif defined(GL_EXT_framebuffer_object) + glDeleteFramebuffersEXT(n, framebuffers); +#else + os::Printer::log("glDeleteFramebuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenFramebuffers(GLsizei n, GLuint *framebuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenFramebuffersEXT) + pGlGenFramebuffersEXT(n, framebuffers); +#elif defined(GL_EXT_framebuffer_object) + glGenFramebuffersEXT(n, framebuffers); +#else + os::Printer::log("glGenFramebuffers not supported", ELL_ERROR); +#endif +} + +inline GLenum COpenGLExtensionHandler::extGlCheckFramebufferStatus(GLenum target) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCheckFramebufferStatusEXT) + return pGlCheckFramebufferStatusEXT(target); + else + return 0; +#elif defined(GL_EXT_framebuffer_object) + return glCheckFramebufferStatusEXT(target); +#else + os::Printer::log("glCheckFramebufferStatus not supported", ELL_ERROR); + return 0; +#endif +} + +inline void COpenGLExtensionHandler::extGlFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlFramebufferTexture2DEXT) + pGlFramebufferTexture2DEXT(target, attachment, textarget, texture, level); +#elif defined(GL_EXT_framebuffer_object) + glFramebufferTexture2DEXT(target, attachment, textarget, texture, level); +#else + os::Printer::log("glFramebufferTexture2D not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindRenderbufferEXT) + pGlBindRenderbufferEXT(target, renderbuffer); +#elif defined(GL_EXT_framebuffer_object) + glBindRenderbufferEXT(target, renderbuffer); +#else + os::Printer::log("glBindRenderbuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteRenderbuffersEXT) + pGlDeleteRenderbuffersEXT(n, renderbuffers); +#elif defined(GL_EXT_framebuffer_object) + glDeleteRenderbuffersEXT(n, renderbuffers); +#else + os::Printer::log("glDeleteRenderbuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenRenderbuffersEXT) + pGlGenRenderbuffersEXT(n, renderbuffers); +#elif defined(GL_EXT_framebuffer_object) + glGenRenderbuffersEXT(n, renderbuffers); +#else + os::Printer::log("glGenRenderbuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlRenderbufferStorageEXT) + pGlRenderbufferStorageEXT(target, internalformat, width, height); +#elif defined(GL_EXT_framebuffer_object) + glRenderbufferStorageEXT(target, internalformat, width, height); +#else + os::Printer::log("glRenderbufferStorage not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlFramebufferRenderbufferEXT) + pGlFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); +#elif defined(GL_EXT_framebuffer_object) + glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); +#else + os::Printer::log("glFramebufferRenderbuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlActiveStencilFace(GLenum face) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlActiveStencilFaceEXT) + pGlActiveStencilFaceEXT(face); +#elif defined(GL_EXT_stencil_two_side) + glActiveStencilFaceEXT(face); +#else + os::Printer::log("glActiveStencilFace not supported", ELL_ERROR); +#endif +} + + +} +} + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLMaterialRenderer.h b/src/dep/src/irrlicht/COpenGLMaterialRenderer.h new file mode 100644 index 0000000..3b6b911 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLMaterialRenderer.h @@ -0,0 +1,672 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLDriver.h" +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +//! Base class for all internal OpenGL material renderers +class COpenGLMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + COpenGLMaterialRenderer(video::COpenGLDriver* driver) : Driver(driver) + { + } + +protected: + + video::COpenGLDriver* Driver; +}; + + +//! Solid material renderer +class COpenGLMaterialRenderer_SOLID : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + // thanks to Murphy, the following line removed some + // bugs with several OpenGL implementations. + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +}; + + +//! Generic Texture Blend +class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + +// if (material.MaterialType != lastMaterial.MaterialType || +// material.MaterialTypeParam != lastMaterial.MaterialTypeParam || +// resetAllRenderstates) + { + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + unpack_texureBlendFunc ( srcFact, dstFact, modulate, material.MaterialTypeParam ); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate ); + + glBlendFunc( getGLBlend(srcFact), getGLBlend(dstFact) ); + glEnable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + + if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) ) + { + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); + } + } + } + + virtual void OnUnsetMaterial() + { + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + private: + + u32 getGLBlend ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_ZERO: r = GL_ZERO; break; + case EBF_ONE: r = GL_ONE; break; + case EBF_DST_COLOR: r = GL_DST_COLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break; + case EBF_SRC_COLOR: r = GL_SRC_COLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break; + case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break; + case EBF_DST_ALPHA: r = GL_DST_ALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break; + } + return r; + } + + u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const + { + u32 r; + switch ( factor ) + { + case EBF_SRC_ALPHA: r = 1; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; + case EBF_DST_ALPHA: r = 1; break; + case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; + case EBF_SRC_ALPHA_SATURATE: r = 1; break; + default: r = 0; break; + } + return r; + } +}; + + +//! Solid 2 layer material renderer +class COpenGLMaterialRenderer_SOLID_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setTexture(1, material.getTexture(1)); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +}; + + +//! Transparent add color material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates) + { + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT ); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + glDepthMask(GL_FALSE); + } + + virtual void OnUnsetMaterial() + { + // default values + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT ); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + + f32 refValue = material.MaterialTypeParam; + if ( refValue == 0.0f ) + refValue = 0.5f; + + glAlphaFunc(GL_GREATER, refValue); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + + +//! Transparent alpha channel material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_ALPHA_TEST); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + +//! material renderer for all kinds of lightmaps +class COpenGLMaterialRenderer_LIGHTMAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setTexture(1, material.getTexture(1)); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + // diffuse map + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + switch (material.MaterialType) + { + case EMT_LIGHTMAP_LIGHTING: + case EMT_LIGHTMAP_LIGHTING_M2: + case EMT_LIGHTMAP_LIGHTING_M4: + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + break; + case EMT_LIGHTMAP_ADD: + case EMT_LIGHTMAP: + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_M4: + default: + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE); + break; + } + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR ); + + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + // lightmap + + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + + if (material.MaterialType == EMT_LIGHTMAP_ADD) + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_ARB); + else + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + + switch (material.MaterialType) + { + case EMT_LIGHTMAP_M4: + case EMT_LIGHTMAP_LIGHTING_M4: + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f); + break; + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_LIGHTING_M2: + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); + break; + default: + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f); + } + } + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f ); + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } +}; + + + +//! detail map material renderer +class COpenGLMaterialRenderer_DETAIL_MAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setTexture(1, material.getTexture(1)); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + // diffuse map + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + // detail map + + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT); + + glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR); + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } + } +}; + + +//! sphere map material renderer +class COpenGLMaterialRenderer_SPHERE_MAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } +}; + + +//! reflection 2 layer material renderer +class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setTexture(1, material.getTexture(1)); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT ); + + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + + } + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +}; + + +//! reflection 2 layer material renderer +class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setTexture(1, material.getTexture(1)); + Driver->setTexture(0, material.getTexture(0)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT ); + + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + } + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); + glEnable(GL_BLEND); + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/COpenGLNormalMapRenderer.cpp b/src/dep/src/irrlicht/COpenGLNormalMapRenderer.cpp new file mode 100644 index 0000000..0f3d01d --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLNormalMapRenderer.cpp @@ -0,0 +1,296 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLNormalMapRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + +// Irrlicht Engine OpenGL render path normal map vertex shader +// I guess it could be optimized a lot, because I wrote it in D3D ASM and +// transferred it 1:1 to OpenGL +const char OPENGL_NORMAL_MAP_VSH[] = + "!!ARBvp1.0\n"\ + "#input\n"\ + "# 0-3: transposed world matrix;\n"\ + "#;12: Light01 position \n"\ + "#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\ + "#;14: Light02 position \n"\ + "#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\ + "\n"\ + "ATTRIB InPos = vertex.position;\n"\ + "ATTRIB InColor = vertex.color;\n"\ + "ATTRIB InNormal = vertex.normal;\n"\ + "ATTRIB InTexCoord = vertex.texcoord[0];\n"\ + "ATTRIB InTangent = vertex.texcoord[1];\n"\ + "ATTRIB InBinormal = vertex.texcoord[2];\n"\ + "\n"\ + "#output\n"\ + "OUTPUT OutPos = result.position;\n"\ + "OUTPUT OutLightColor1 = result.color.primary;\n"\ + "OUTPUT OutLightColor2 = result.color.secondary;\n"\ + "OUTPUT OutTexCoord = result.texcoord[0];\n"\ + "OUTPUT OutLightVector1 = result.texcoord[1];\n"\ + "OUTPUT OutLightVector2 = result.texcoord[2];\n"\ + "\n"\ + "PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\ + "TEMP Temp;\n"\ + "TEMP TempColor;\n"\ + "TEMP TempNormal;\n"\ + "TEMP TempTangent;\n"\ + "TEMP TempBinormal;\n"\ + "TEMP TempLightVector1;\n"\ + "TEMP TempLightVector2;\n"\ + "TEMP TempTransLightV1;\n"\ + "TEMP TempTransLightV2;\n"\ + "\n"\ + "# transform position to clip space \n"\ + "DP4 OutPos.x, MVP[0], InPos;\n"\ + "DP4 OutPos.y, MVP[1], InPos;\n"\ + "DP4 OutPos.z, MVP[2], InPos;\n"\ + "DP4 OutPos.w, MVP[3], InPos;\n"\ + "\n"\ + "# transform normal \n"\ + "DP3 TempNormal.x, InNormal.x, program.local[0];\n"\ + "DP3 TempNormal.y, InNormal.y, program.local[1]; \n"\ + "DP3 TempNormal.z, InNormal.z, program.local[2];\n"\ + "\n"\ + "# transform tangent \n"\ + "DP3 TempTangent.x, InTangent.x, program.local[0];\n"\ + "DP3 TempTangent.y, InTangent.y, program.local[1]; \n"\ + "DP3 TempTangent.z, InTangent.z, program.local[2];\n"\ + "\n"\ + "# transform binormal \n"\ + "DP3 TempBinormal.x, InBinormal.x, program.local[0];\n"\ + "DP3 TempBinormal.y, InBinormal.y, program.local[1]; \n"\ + "DP3 TempBinormal.z, InBinormal.z, program.local[2];\n"\ + "\n"\ + "# vertex into world position \n"\ + "DP4 Temp.x, InPos, program.local[0];\n"\ + "DP4 Temp.y, InPos, program.local[1];\n"\ + "DP4 Temp.z, InPos, program.local[2];\n"\ + "DP4 Temp.w, InPos, program.local[3];\n"\ + "\n"\ + "# vertex - lightpositions \n"\ + "SUB TempLightVector1, program.local[12], Temp; \n"\ + "SUB TempLightVector2, program.local[14], Temp; \n"\ + "\n"\ + "# transform the light vector 1 with U, V, W \n"\ + "DP3 TempTransLightV1.x, TempTangent, TempLightVector1; \n"\ + "DP3 TempTransLightV1.y, TempBinormal, TempLightVector1; \n"\ + "DP3 TempTransLightV1.z, TempNormal, TempLightVector1; \n"\ + "\n"\ + "# transform the light vector 2 with U, V, W \n"\ + "DP3 TempTransLightV2.x, TempTangent, TempLightVector2; \n"\ + "DP3 TempTransLightV2.y, TempBinormal, TempLightVector2; \n"\ + "DP3 TempTransLightV2.z, TempNormal, TempLightVector2; \n"\ + "\n"\ + "# normalize light vector 1 \n"\ + "DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\ + "RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\ + "MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\ + "\n"\ + "# normalize light vector 2 \n"\ + "DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\ + "RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\ + "MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\ + "\n"\ + "\n"\ + "# move light vectors out\n"\ + "MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "\n"\ + "# calculate attenuation of light 1\n"\ + "MOV TempLightVector1.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\ + "MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w; \n"\ + "RSQ TempLightVector1, TempLightVector1.x; \n"\ + "MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# calculate attenuation of light 2\n"\ + "MOV TempLightVector2.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\ + "MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w; \n"\ + "RSQ TempLightVector2, TempLightVector2.x; \n"\ + "MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# move out texture coordinates and original alpha value\n"\ + "MOV OutTexCoord, InTexCoord; \n"\ + "MOV OutLightColor1.w, InColor.w; \n"\ + "\n"\ + "END\n"; + +// Irrlicht Engine OpenGL render path normal map pixel shader +// I guess it could be optimized a bit, because I wrote it in D3D ASM and +// transfered it 1:1 to OpenGL +const char OPENGL_NORMAL_MAP_PSH[] = + "!!ARBfp1.0\n"\ + "\n"\ + "#Input\n"\ + "ATTRIB inTexCoord = fragment.texcoord[0]; \n"\ + "ATTRIB light1Vector = fragment.texcoord[1]; \n"\ + "ATTRIB light2Vector = fragment.texcoord[2]; \n"\ + "ATTRIB light1Color = fragment.color.primary; \n"\ + "ATTRIB light2Color = fragment.color.secondary; \n"\ + "\n"\ + "#Output\n"\ + "OUTPUT outColor = result.color;\n"\ + "TEMP temp;\n"\ + "TEMP temp2;\n"\ + "TEMP colorMapColor;\n"\ + "TEMP normalMapColor;\n"\ + "\n"\ + "# fetch color and normal map; \n"\ + "TXP colorMapColor, inTexCoord, texture[0], 2D; \n"\ + "TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\ + "\n"\ + "# calculate color of light1; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp, normalMapColor, temp; \n"\ + "MUL temp, light1Color, temp; \n"\ + "\n"\ + "# calculate color of light2; \n"\ + "MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp2, normalMapColor, temp2; \n"\ + "MAD temp, light2Color, temp2, temp; \n"\ + "\n"\ + "# luminance * base color; \n"\ + "MUL outColor, temp, colorMapColor; \n"\ + "MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\ + "\n"\ + "END\n"; + +//! Constructor +COpenGLNormalMapRenderer::COpenGLNormalMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true) +{ + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) || + !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + + if (renderer) + { + // use the already compiled shaders + video::COpenGLNormalMapRenderer* nmr = reinterpret_cast(renderer); + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, OPENGL_NORMAL_MAP_VSH, OPENGL_NORMAL_MAP_PSH, EVT_TANGENTS); + } +} + + +//! Destructor +COpenGLNormalMapRenderer::~COpenGLNormalMapRenderer() +{ + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } +} + + +//! Returns the render capability of the material. +s32 COpenGLNormalMapRenderer::getRenderCapability() const +{ + if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) && + Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + return 0; + + return 1; +} + + +//! Called by the engine when the vertex and/or pixel shader constants for an +//! material renderer should be set. +void COpenGLNormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) +{ + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed(); + services->setVertexShaderConstant(tWorld.pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + core::matrix4 tr(worldViewProj.getTransposed()); + services->setVertexShaderConstant(tr.pointer(), 8, 4); + + // here we fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + video::SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant( + reinterpret_cast(&light.Position), 12+(i*2), 1); + + services->setVertexShaderConstant( + reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } +} + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLNormalMapRenderer.h b/src/dep/src/irrlicht/COpenGLNormalMapRenderer.h new file mode 100644 index 0000000..42d46fe --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLNormalMapRenderer.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__ +#define __C_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Class for rendering normal maps with OpenGL +class COpenGLNormalMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack +{ +public: + + //! Constructor + COpenGLNormalMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + //! Destructor + ~COpenGLNormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +protected: + + bool CompiledShaders; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.cpp b/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.cpp new file mode 100644 index 0000000..2853835 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.cpp @@ -0,0 +1,361 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLParallaxMapRenderer.h" +#include "COpenGLDriver.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +// Irrlicht Engine OpenGL render path parallax map vertex shader +// I guess it could be optimized a lot, because I wrote it in D3D ASM and +// transferred it 1:1 to OpenGL +const char OPENGL_PARALLAX_MAP_VSH[] = + "!!ARBvp1.0\n"\ + "#input\n"\ + "# 0-3: transposed world matrix;\n"\ + "#;12: Light01 position \n"\ + "#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\ + "#;14: Light02 position \n"\ + "#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\ + "#;16: Eye position \n"\ + "\n"\ + "ATTRIB InPos = vertex.position;\n"\ + "ATTRIB InColor = vertex.color;\n"\ + "ATTRIB InNormal = vertex.normal;\n"\ + "ATTRIB InTexCoord = vertex.texcoord[0];\n"\ + "ATTRIB InTangent = vertex.texcoord[1];\n"\ + "ATTRIB InBinormal = vertex.texcoord[2];\n"\ + "\n"\ + "#output\n"\ + "OUTPUT OutPos = result.position;\n"\ + "OUTPUT OutLightColor1 = result.color.primary;\n"\ + "OUTPUT OutLightColor2 = result.color.secondary;\n"\ + "OUTPUT OutTexCoord = result.texcoord[0];\n"\ + "OUTPUT OutLightVector1 = result.texcoord[1];\n"\ + "OUTPUT OutLightVector2 = result.texcoord[2];\n"\ + "OUTPUT OutEyeVector = result.texcoord[3];\n"\ + "\n"\ + "PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\ + "TEMP Temp;\n"\ + "TEMP TempColor;\n"\ + "TEMP TempNormal;\n"\ + "TEMP TempTangent;\n"\ + "TEMP TempBinormal;\n"\ + "TEMP TempLightVector1;\n"\ + "TEMP TempLightVector2;\n"\ + "TEMP TempEyeVector;\n"\ + "TEMP TempTransLightV1;\n"\ + "TEMP TempTransLightV2;\n"\ + "\n"\ + "# transform position to clip space \n"\ + "DP4 OutPos.x, MVP[0], InPos;\n"\ + "DP4 OutPos.y, MVP[1], InPos;\n"\ + "DP4 OutPos.z, MVP[2], InPos;\n"\ + "DP4 OutPos.w, MVP[3], InPos;\n"\ + "\n"\ + "# transform normal \n"\ + "DP3 TempNormal.x, InNormal.x, program.local[0];\n"\ + "DP3 TempNormal.y, InNormal.y, program.local[1]; \n"\ + "DP3 TempNormal.z, InNormal.z, program.local[2];\n"\ + "\n"\ + "# transform tangent \n"\ + "DP3 TempTangent.x, InTangent.x, program.local[0];\n"\ + "DP3 TempTangent.y, InTangent.y, program.local[1]; \n"\ + "DP3 TempTangent.z, InTangent.z, program.local[2];\n"\ + "\n"\ + "# transform binormal \n"\ + "DP3 TempBinormal.x, InBinormal.x, program.local[0];\n"\ + "DP3 TempBinormal.y, InBinormal.y, program.local[1]; \n"\ + "DP3 TempBinormal.z, InBinormal.z, program.local[2];\n"\ + "\n"\ + "# vertex into world position \n"\ + "DP4 Temp.x, InPos, program.local[0];\n"\ + "DP4 Temp.y, InPos, program.local[1];\n"\ + "DP4 Temp.z, InPos, program.local[2];\n"\ + "DP4 Temp.w, InPos, program.local[3];\n"\ + "\n"\ + "# vertex - lightpositions \n"\ + "SUB TempLightVector1, program.local[12], Temp; \n"\ + "SUB TempLightVector2, program.local[14], Temp; \n"\ + "\n"\ + "# eye vector \n"\ + "SUB Temp, program.local[16], Temp; \n"\ + "\n"\ + "# transform the light vector 1 with U, V, W \n"\ + "DP3 TempTransLightV1.x, TempTangent, TempLightVector1; \n"\ + "DP3 TempTransLightV1.y, TempBinormal, TempLightVector1; \n"\ + "DP3 TempTransLightV1.z, TempNormal, TempLightVector1; \n"\ + "\n"\ + "# transform the light vector 2 with U, V, W \n"\ + "DP3 TempTransLightV2.x, TempTangent, TempLightVector2; \n"\ + "DP3 TempTransLightV2.y, TempBinormal, TempLightVector2; \n"\ + "DP3 TempTransLightV2.z, TempNormal, TempLightVector2; \n"\ + "\n"\ + "# transform the eye vector with U, V, W \n"\ + "DP3 TempEyeVector.x, TempTangent, Temp; \n"\ + "DP3 TempEyeVector.y, TempBinormal, Temp; \n"\ + "DP3 TempEyeVector.z, TempNormal, Temp; \n"\ + "\n"\ + "# normalize light vector 1 \n"\ + "DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\ + "RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\ + "MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\ + "\n"\ + "# normalize light vector 2 \n"\ + "DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\ + "RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\ + "MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\ + "\n"\ + "# normalize eye vector \n"\ + "DP3 TempEyeVector.w, TempEyeVector, TempEyeVector; \n"\ + "RSQ TempEyeVector.w, TempEyeVector.w; \n"\ + "MUL TempEyeVector, TempEyeVector, TempEyeVector.w;\n"\ + "MUL TempEyeVector, TempEyeVector, {1,-1,-1,1}; # flip x \n"\ + "\n"\ + "\n"\ + "# move light and eye vectors out\n"\ + "MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutEyeVector, TempEyeVector, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "\n"\ + "# calculate attenuation of light 1\n"\ + "MOV TempLightVector1.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\ + "MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w; \n"\ + "RSQ TempLightVector1, TempLightVector1.x; \n"\ + "MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# calculate attenuation of light 2\n"\ + "MOV TempLightVector2.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\ + "MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w; \n"\ + "RSQ TempLightVector2, TempLightVector2.x; \n"\ + "MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# move out texture coordinates and original alpha value\n"\ + "MOV OutTexCoord, InTexCoord; \n"\ + "MOV OutLightColor1.w, InColor.w; \n"\ + "\n"\ + "END\n"; + +// Irrlicht Engine OpenGL render path parallax map pixel shader +// I guess it could be optimized a bit, because I wrote it in D3D ASM and +// transfered it 1:1 to OpenGL +const char OPENGL_PARALLAX_MAP_PSH[] = + "!!ARBfp1.0\n"\ + "\n"\ + "#Input\n"\ + "ATTRIB inTexCoord = fragment.texcoord[0]; \n"\ + "ATTRIB light1Vector = fragment.texcoord[1]; \n"\ + "ATTRIB light2Vector = fragment.texcoord[2]; \n"\ + "ATTRIB eyeVector = fragment.texcoord[3]; \n"\ + "ATTRIB light1Color = fragment.color.primary; \n"\ + "ATTRIB light2Color = fragment.color.secondary; \n"\ + "\n"\ + "#Output\n"\ + "OUTPUT outColor = result.color;\n"\ + "TEMP temp;\n"\ + "TEMP temp2;\n"\ + "TEMP colorMapColor;\n"\ + "TEMP normalMapColor;\n"\ + "\n"\ + "PARAM height_scale = program.local[0]; \n"\ + "# fetch color and normal map; \n"\ + "TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "\n"\ + "\n"\ + "# extract eye vector (so substract 0.5f and multiply by 2)\n"\ + "MAD temp, eyeVector, {2,2,2,2}, {-1,-1,-1,-1};\n"\ + "\n"\ + "# height = height * scale \n"\ + "MUL normalMapColor, normalMapColor, height_scale;\n"\ + "\n"\ + "# calculate new texture coord: height * eye + oldTexCoord\n"\ + "MAD temp, temp, normalMapColor.wwww, inTexCoord;\n"\ + "\n"\ + "# fetch new textures \n"\ + "TXP colorMapColor, temp, texture[0], 2D; \n"\ + "TXP normalMapColor, temp, texture[1], 2D; \n"\ + "\n"\ + "# calculate color of light1; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp, normalMapColor, temp; \n"\ + "MUL temp, light1Color, temp; \n"\ + "\n"\ + "# calculate color of light2; \n"\ + "MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp2, normalMapColor, temp2; \n"\ + "MAD temp, light2Color, temp2, temp; \n"\ + "\n"\ + "# luminance * base color; \n"\ + "MUL outColor, temp, colorMapColor; \n"\ + "MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\ + "\n"\ + "END\n"; + +//! Constructor +COpenGLParallaxMapRenderer::COpenGLParallaxMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true) +{ + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basically, this simply compiles the hard coded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) || + !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + + if (renderer) + { + // use the already compiled shaders + video::COpenGLParallaxMapRenderer* nmr = reinterpret_cast(renderer); + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, OPENGL_PARALLAX_MAP_VSH, OPENGL_PARALLAX_MAP_PSH, EVT_TANGENTS); + } +} + + +//! Destructor +COpenGLParallaxMapRenderer::~COpenGLParallaxMapRenderer() +{ + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } +} + + +void COpenGLParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + COpenGLShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; +} + + + +//! Returns the render capability of the material. +s32 COpenGLParallaxMapRenderer::getRenderCapability() const +{ + if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) && + Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + return 0; + + return 1; +} + + +//! Called by the engine when the vertex and/or pixel shader constants for an +//! material renderer should be set. +void COpenGLParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) +{ + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed(); + services->setVertexShaderConstant(tWorld.pointer(), 0, 4); + + // The viewpoint is at (0., 0., 0.) in eye space. + // Turning this into a vector [0 0 0 1] and multiply it by + // the inverse of the view matrix, the resulting vector is the + // object space location of the camera. + + f32 floats[4] = {0.0f,0.0f,0.0f,1.0f}; + core::matrix4 minv(driver->getTransform(video::ETS_VIEW)); + minv.makeInverse(); + minv.multiplyWith1x4Matrix(floats); + services->setVertexShaderConstant(floats, 16, 1); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + core::matrix4 tr(worldViewProj.getTransposed()); + services->setVertexShaderConstant(tr.pointer(), 8, 4); + + // here we fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + video::SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant( + reinterpret_cast(&light.Position), 12+(i*2), 1); + + services->setVertexShaderConstant( + reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0.0f) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, factor}; + services->setPixelShaderConstant(c6, 0, 1); +} + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.h b/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.h new file mode 100644 index 0000000..1fe5295 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLParallaxMapRenderer.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__ +#define __C_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Class for rendering normal maps with OpenGL +class COpenGLParallaxMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack +{ +public: + + //! Constructor + COpenGLParallaxMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + //! Destructor + ~COpenGLParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + + virtual void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + +protected: + + bool CompiledShaders; + f32 CurrentScale; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.cpp b/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.cpp new file mode 100644 index 0000000..605046d --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.cpp @@ -0,0 +1,363 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// This file was originally written by William Finlayson. I (Nikolaus +// Gebhardt) did some minor modifications and changes to it and integrated it +// into Irrlicht. Thanks a lot to William for his work on this and that he gave +// me his permission to add it into Irrlicht using the zlib license. + +// After Irrlicht 0.12, Michael Zoech did some improvements to this renderer, I +// merged this into Irrlicht 0.14, thanks to him for his work. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLSLMaterialRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + + +//! Constructor +COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + video::IMaterialRenderer* baseMaterial, + s32 userData) + : Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + Program(0), UserData(userData) +{ + //entry points must always be main, and the compile target isn't selectable + //it is fine to ignore what has been asked for, as the compiler should spot anything wrong + //just check that GLSL is available + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + if (!Driver->queryFeature(EVDF_ARB_GLSL)) + return; + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram); +} + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData) +: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + Program(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +//! Destructor +COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if(Program) + { + Driver->extGlDeleteObject(Program); + Program = 0; + } + + UniformInfo.clear(); + + if (BaseMaterial) + BaseMaterial->drop(); +} + +void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* pixelShaderProgram) +{ + outMaterialTypeNr = -1; + + if (!createProgram()) + return; + +#if defined(GL_ARB_vertex_shader) && defined (GL_ARB_fragment_shader) + if (!createShader(GL_VERTEX_SHADER_ARB, vertexShaderProgram)) + return; + + if (!createShader(GL_FRAGMENT_SHADER_ARB, pixelShaderProgram)) + return; +#endif + + if (!linkProgram()) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + +bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, + E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (Program)) + CallBack->OnSetConstants(this, UserData); + + return true; +} + + +void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, + video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if(Program) + Driver->extGlUseProgramObject(Program); + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, this); + } + + for (u32 i=0; isetTexture(i, material.getTexture(i)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +void COpenGLSLMaterialRenderer::OnUnsetMaterial() +{ + Driver->extGlUseProgramObject(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + +//! Returns if the material is transparent. +bool COpenGLSLMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +bool COpenGLSLMaterialRenderer::createProgram() +{ + Program = Driver->extGlCreateProgramObject(); + return true; +} + +bool COpenGLSLMaterialRenderer::createShader(GLenum shaderType, const char* shader) +{ + GLhandleARB shaderHandle = Driver->extGlCreateShaderObject(shaderType); + + Driver->extGlShaderSource(shaderHandle, 1, &shader, NULL); + Driver->extGlCompileShader(shaderHandle); + + int status = 0; + +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status); +#endif + + if (!status) + { + os::Printer::log("GLSL shader failed to compile"); + // check error message and log it + int maxLength=0; + GLsizei length; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(shaderHandle, + GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); +#endif + GLcharARB *pInfoLog = new GLcharARB[maxLength]; + Driver->extGlGetInfoLog(shaderHandle, maxLength, &length, pInfoLog); + os::Printer::log(reinterpret_cast(pInfoLog)); + delete [] pInfoLog; + + return false; + } + + Driver->extGlAttachObject(Program, shaderHandle); + + return true; +} + +bool COpenGLSLMaterialRenderer::linkProgram() +{ + Driver->extGlLinkProgram(Program); + + int status = 0; + +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_LINK_STATUS_ARB, &status); +#endif + + if (!status) + { + os::Printer::log("GLSL shader program failed to link"); + // check error message and log it + int maxLength=0; + GLsizei length; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, + GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); +#endif + GLcharARB *pInfoLog = new GLcharARB[maxLength]; + Driver->extGlGetInfoLog(Program, maxLength, &length, pInfoLog); + os::Printer::log(reinterpret_cast(pInfoLog)); + delete [] pInfoLog; + + return false; + } + + // get uniforms information + + int num = 0; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &num); +#endif + + if (num == 0) + { + // no uniforms + return true; + } + + int maxlen = 0; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &maxlen); +#endif + + if (maxlen == 0) + { + os::Printer::log("GLSL: failed to retrieve uniform information"); + return false; + } + + c8 *buf = new c8[maxlen]; + + UniformInfo.clear(); + UniformInfo.reallocate(num); + + for (int i=0; i < num; ++i) + { + SUniformInfo ui; + memset(buf, 0, maxlen); + + GLint size; + Driver->extGlGetActiveUniform(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast(buf)); + ui.name = buf; + + UniformInfo.push_back(ui); + } + + delete [] buf; + + return true; +} + + + +void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material, + const SMaterial& lastMaterial, + bool resetAllRenderstates) +{ + // forward + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +bool COpenGLSLMaterialRenderer::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + return setPixelShaderConstant(name, floats, count); +} + + +void COpenGLSLMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, please use high level shader call instead."); +} + +bool COpenGLSLMaterialRenderer::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + int i, num = static_cast(UniformInfo.size()); + + for (i=0; i < num; ++i) + { + if (UniformInfo[i].name == name) + break; + } + + if (i == num) + return false; + +#ifdef GL_ARB_shader_objects + switch (UniformInfo[i].type) + { + case GL_FLOAT: + Driver->extGlUniform1fv(i, count, floats); + break; + case GL_FLOAT_VEC2_ARB: + Driver->extGlUniform2fv(i, count/2, floats); + break; + case GL_FLOAT_VEC3_ARB: + Driver->extGlUniform3fv(i, count/3, floats); + break; + case GL_FLOAT_VEC4_ARB: + Driver->extGlUniform4fv(i, count/4, floats); + break; + case GL_FLOAT_MAT2_ARB: + Driver->extGlUniformMatrix2fv(i, count/4, false, floats); + break; + case GL_FLOAT_MAT3_ARB: + Driver->extGlUniformMatrix3fv(i, count/9, false, floats); + break; + case GL_FLOAT_MAT4_ARB: + Driver->extGlUniformMatrix4fv(i, count/16, false, floats); + break; + default: + Driver->extGlUniform1iv(i, count, reinterpret_cast(floats)); + break; + } +#endif + + return true; +} + +void COpenGLSLMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, use high level shader call."); +} + +IVideoDriver* COpenGLSLMaterialRenderer::getVideoDriver() +{ + return Driver; +} + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.h b/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.h new file mode 100644 index 0000000..b47d155 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLSLMaterialRenderer.h @@ -0,0 +1,124 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_SHADER_LANGUAGE_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_SHADER_LANGUAGE_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#ifdef _IRR_WINDOWS_API_ + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#else +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#endif +#if defined(MACOSX) + #include +#else + #include +#endif +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" +#endif +#endif + + +#include "IMaterialRenderer.h" +#include "IMaterialRendererServices.h" +#include "IGPUProgrammingServices.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +class IShaderConstantSetCallBack; + +//! Class for using GLSL shaders with OpenGL +//! Please note: This renderer implements its own IMaterialRendererServices +class COpenGLSLMaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices +{ +public: + + //! Constructor + COpenGLSLMaterialRenderer( + video::COpenGLDriver* driver, + s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + video::IMaterialRenderer* baseMaterial, + s32 userData); + + //! Destructor + virtual ~COpenGLSLMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + virtual void OnUnsetMaterial(); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + + // implementations for the render services + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates); + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual IVideoDriver* getVideoDriver(); + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + COpenGLSLMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData=0); + + void init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* pixelShaderProgram); + + bool createProgram(); + bool createShader(GLenum shaderType, const char* shader); + bool linkProgram(); + + video::COpenGLDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + struct SUniformInfo + { + core::stringc name; + GLenum type; + }; + + GLhandleARB Program; + core::array UniformInfo; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif // compile with OpenGL +#endif // if included + diff --git a/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.cpp b/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.cpp new file mode 100644 index 0000000..69a7aca --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.cpp @@ -0,0 +1,237 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + + +//! Constructor +COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) + : Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD); +} + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData) +: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +//! Destructor +COpenGLShaderMaterialRenderer::~COpenGLShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + Driver->extGlDeletePrograms(1, &VertexShader); + + if (PixelShader) + Driver->extGlDeletePrograms(1, &PixelShader); + + if (BaseMaterial) + BaseMaterial->drop (); +} + +void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram, E_VERTEX_TYPE type) +{ + outMaterialTypeNr = -1; + + // create vertex shader + if (!createVertexShader(vertexShaderProgram)) + return; + + // create pixel shader + if (!createPixelShader(pixelShaderProgram)) + return; + + // register as a new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + +bool COpenGLShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader)) + CallBack->OnSetConstants(service, UserData); + + return true; +} + + +void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { +#ifdef GL_ARB_vertex_program + if (VertexShader) + { + // set new vertex shader + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_ARB, VertexShader); + glEnable(GL_VERTEX_PROGRAM_ARB); + } +#endif + + // set new pixel shader +#ifdef GL_ARB_fragment_program + if (PixelShader) + { + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_ARB, PixelShader); + glEnable(GL_FRAGMENT_PROGRAM_ARB); + } +#endif + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + for (u32 i=0; isetTexture(i, material.getTexture(i)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +void COpenGLShaderMaterialRenderer::OnUnsetMaterial() +{ + // disable vertex shader +#ifdef GL_ARB_vertex_program + if (VertexShader) + glDisable(GL_VERTEX_PROGRAM_ARB); +#endif + +#ifdef GL_ARB_fragment_program + if (PixelShader) + glDisable(GL_FRAGMENT_PROGRAM_ARB); +#endif + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + +//! Returns if the material is transparent. +bool COpenGLShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +bool COpenGLShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + + Driver->extGlGenPrograms(1, &PixelShader); +#ifdef GL_ARB_fragment_program + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_ARB, PixelShader); + + // clear error buffer + while(glGetError() != GL_NO_ERROR) + {} + + // compile + Driver->extGlProgramString(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(pxsh), pxsh); +#endif + +#ifdef GL_ARB_vertex_program + GLenum g = glGetError(); + if (g != GL_NO_ERROR) + { + GLint errPos; + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); + + const char* errString = reinterpret_cast(glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + + char tmp[2048]; + sprintf(tmp, "Pixel shader compilation failed at position %d:\n%s", errPos, errString); + os::Printer::log(tmp); + + return false; + } +#else + return false; +#endif + + return true; +} + +bool COpenGLShaderMaterialRenderer::createVertexShader(const char* vtxsh) +{ + if (!vtxsh) + return true; + +#ifdef GL_ARB_vertex_program + Driver->extGlGenPrograms(1, &VertexShader); + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_ARB, VertexShader); + + // clear error buffer + while(glGetError() != GL_NO_ERROR) + {} + + // compile + Driver->extGlProgramString(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(vtxsh), vtxsh); + + GLenum g = glGetError(); + if (g != GL_NO_ERROR) + { + GLint errPos; + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); + + const char* errString = reinterpret_cast(glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + + char tmp[2048]; + sprintf(tmp, "Vertex shader compilation failed at position %d:\n%s", errPos, errString); + os::Printer::log(tmp); + + return false; + } +#else + return false; +#endif + + return true; +} + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.h b/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.h new file mode 100644 index 0000000..c79b982 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLShaderMaterialRenderer.h @@ -0,0 +1,92 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#ifdef _IRR_WINDOWS_API_ + #define WIN32_LEAN_AND_MEAN + #include + #include +#else +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#endif +#if defined(MACOSX) + #include +#else + #include +#endif +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" +#endif +#endif + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with OpenGL +class COpenGLShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + virtual ~COpenGLShaderMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + virtual void OnUnsetMaterial(); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + COpenGLShaderMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData=0); + + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram, E_VERTEX_TYPE type); + + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const char* vtxsh); + + video::COpenGLDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + GLuint VertexShader; + GLuint PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/dep/src/irrlicht/COpenGLTexture.cpp b/src/dep/src/irrlicht/COpenGLTexture.cpp new file mode 100644 index 0000000..a1243a8 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLTexture.cpp @@ -0,0 +1,556 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "irrTypes.h" +#include "COpenGLTexture.h" +#include "COpenGLDriver.h" +#include "os.h" +#include "CImage.h" +#include "CColorConverter.h" + +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +// helper function for render to texture +static bool checkFBOStatus(COpenGLDriver* Driver); + +//! constructor for usual textures +COpenGLTexture::COpenGLTexture(IImage* image, const char* name, COpenGLDriver* driver) + : ITexture(name), Driver(driver), Image(0), + TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), + PixelType(GL_UNSIGNED_BYTE), HasMipMaps(true), IsRenderTarget(false), + ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0), Locks(0) +{ + #ifdef _DEBUG + setDebugName("COpenGLTexture"); + #endif + + getImageData(image); + + HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); + if (Image) + { + glGenTextures(1, &TextureName); + copyTexture(); + } +} + +//! ColorFrameBuffer constructor +COpenGLTexture::COpenGLTexture(const core::dimension2d& size, + bool extPackedDepthStencilSupported, + const char* name, + COpenGLDriver* driver) + : ITexture(name), ImageSize(size), Driver(driver), Image(0), + TextureName(0), InternalFormat(GL_RGB8), PixelFormat(GL_RGBA), + PixelType(GL_UNSIGNED_BYTE), HasMipMaps(false), IsRenderTarget(true), + ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0), Locks(0) +{ + #ifdef _DEBUG + setDebugName("COpenGLTexture_FBO"); + #endif + + // generate color texture + glGenTextures(1, &TextureName); + glBindTexture(GL_TEXTURE_2D, TextureName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width, + ImageSize.Height, 0, PixelFormat, PixelType, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +#ifdef GL_EXT_packed_depth_stencil + if (extPackedDepthStencilSupported) + { + // generate packed depth stencil texture + glGenTextures(1, &DepthRenderBuffer); + glBindTexture(GL_TEXTURE_2D, DepthRenderBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_EXT, ImageSize.Width, + ImageSize.Height, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + StencilRenderBuffer = DepthRenderBuffer; // stencil is packed with depth + } + else // generate separate stencil and depth textures +#endif + { + // generate depth texture + glGenTextures(1, &DepthRenderBuffer); + glBindTexture(GL_TEXTURE_2D, DepthRenderBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, ImageSize.Width, + ImageSize.Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // we 're in trouble! the code below does not complete the FBO currently... + // stencil buffer is only supported with EXT_packed_depth_stencil extension (above) + +// // generate stencil texture +// glGenTextures(1, &StencilRenderBuffer); +// glBindTexture(GL_TEXTURE_2D, StencilRenderBuffer); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +// glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX, ImageSize.Width, +// ImageSize.Height, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 0); +// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + +#ifdef GL_EXT_framebuffer_object + // generate frame buffer + Driver->extGlGenFramebuffers(1, &ColorFrameBuffer); + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer); + + // attach color texture to frame buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + TextureName, + 0); + // attach depth texture to depth buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_TEXTURE_2D, + DepthRenderBuffer, + 0); + // attach stencil texture to stencil buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_TEXTURE_2D, + StencilRenderBuffer, + 0); + glGetError(); + + // check the status + if (!checkFBOStatus(Driver)) + { + printf("FBO=%u, Color=%u, Depth=%u, Stencil=%u\n", + ColorFrameBuffer, TextureName, DepthRenderBuffer, StencilRenderBuffer); + if (ColorFrameBuffer) + Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer); + if (DepthRenderBuffer) + glDeleteTextures(1, &DepthRenderBuffer); + if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer) + glDeleteTextures(1, &StencilRenderBuffer); + ColorFrameBuffer = 0; + DepthRenderBuffer = 0; + StencilRenderBuffer = 0; + } + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); +#endif +} + + +//! destructor +COpenGLTexture::~COpenGLTexture() +{ + if (ColorFrameBuffer) + Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer); + if (DepthRenderBuffer) + glDeleteTextures(1, &DepthRenderBuffer); + if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer) + glDeleteTextures(1, &StencilRenderBuffer); + + glDeleteTextures(1, &TextureName); + if (Image) + Image->drop(); +} + + +ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format) +{ + ECOLOR_FORMAT destFormat = ECF_A8R8G8B8; + switch (format) + { + case ECF_A1R5G5B5: + if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_R5G6B5: + if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_A8R8G8B8: + if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) || + Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_R8G8B8: + if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) || + Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + destFormat = ECF_A1R5G5B5; + break; + } + if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL)) + { + switch (destFormat) + { + case ECF_A1R5G5B5: + destFormat = ECF_R5G6B5; + break; + case ECF_A8R8G8B8: + destFormat = ECF_R8G8B8; + break; + default: + break; + } + } + return destFormat; +} + + +void COpenGLTexture::getImageData(IImage* image) +{ + if (!image) + { + os::Printer::log("No image for OpenGL texture.", ELL_ERROR); + return; + } + + ImageSize = image->getDimension(); + + if ( !ImageSize.Width || !ImageSize.Height) + { + os::Printer::log("Invalid size of image for OpenGL Texture.", ELL_ERROR); + return; + } + + core::dimension2d nImageSize; + if (Driver->queryFeature(EVDF_TEXTURE_NPOT)) + nImageSize=ImageSize; + else + { + nImageSize.Width = getTextureSizeFromSurfaceSize(ImageSize.Width); + nImageSize.Height = getTextureSizeFromSurfaceSize(ImageSize.Height); + } + + ECOLOR_FORMAT destFormat = getBestColorFormat(image->getColorFormat()); + if (ImageSize==nImageSize) + Image = new CImage(destFormat, image); + else + { + Image = new CImage(destFormat, nImageSize); + // scale texture + image->copyToScaling(Image); + } +} + + + +//! copies the the texture into an open gl texture. +void COpenGLTexture::copyTexture(bool newTexture) +{ + glBindTexture(GL_TEXTURE_2D, TextureName); + if (Driver->testGLError()) + os::Printer::log("Could not bind Texture", ELL_ERROR); + + switch (Image->getColorFormat()) + { + case ECF_A1R5G5B5: + InternalFormat=GL_RGBA; + PixelFormat=GL_BGRA_EXT; + PixelType=GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case ECF_R5G6B5: + InternalFormat=GL_RGB; + PixelFormat=GL_BGR; + PixelType=GL_UNSIGNED_SHORT_5_6_5_REV; + break; + case ECF_R8G8B8: + InternalFormat=GL_RGB; + PixelFormat=GL_BGR; + PixelType=GL_UNSIGNED_BYTE; + break; + case ECF_A8R8G8B8: + InternalFormat=GL_RGBA; + PixelFormat=GL_BGRA_EXT; + if (Driver->Version > 101) + PixelType=GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + os::Printer::log("Unsupported texture format", ELL_ERROR); + break; + } + + if (newTexture) + { + #ifndef DISABLE_MIPMAPPING + if (HasMipMaps && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + // automatically generate and update mipmaps + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); + AutomaticMipmapUpdate=true; + } + else + { + AutomaticMipmapUpdate=false; + regenerateMipMapLevels(); + } + if (HasMipMaps) // might have changed in regenerateMipMapLevels + { + // enable bilinear mipmap filter + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + #else + HasMipMaps=false; + os::Printer::log("Did not create OpenGL texture mip maps.", ELL_ERROR); + #endif + { + // enable bilinear filter without mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + } + + void* source = Image->lock(); + if (newTexture) + glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, Image->getDimension().Width, + Image->getDimension().Height, 0, PixelFormat, PixelType, source); + else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Image->getDimension().Width, + Image->getDimension().Height, PixelFormat, PixelType, source); + Image->unlock(); + + if (Driver->testGLError()) + os::Printer::log("Could not glTexImage2D", ELL_ERROR); +} + + + +//! returns the size of a texture which would be the optimal size for rendering it +inline s32 COpenGLTexture::getTextureSizeFromSurfaceSize(s32 size) const +{ + s32 ts = 0x01; + while(ts < size) + ts <<= 1; + + return ts; +} + + +//! lock function +void* COpenGLTexture::lock() +{ + if (Image) + { + ++Locks; + return Image->lock(); + } + else + return 0; +} + + + +//! unlock function +void COpenGLTexture::unlock() +{ + if (Image) + { + --Locks; + Image->unlock(); + copyTexture(false); + } +} + + + +//! Returns size of the original image. +const core::dimension2d& COpenGLTexture::getOriginalSize() const +{ + return ImageSize; +} + + + +//! Returns of the texture. +const core::dimension2d& COpenGLTexture::getSize() const +{ + if (Image) + return Image->getDimension(); + else + return ImageSize; +} + + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE COpenGLTexture::getDriverType() const +{ + return EDT_OPENGL; +} + + + +//! returns color format of texture +ECOLOR_FORMAT COpenGLTexture::getColorFormat() const +{ + if (Image) + return Image->getColorFormat(); + else + return ECF_A8R8G8B8; +} + + + +//! returns pitch of texture (in bytes) +u32 COpenGLTexture::getPitch() const +{ + if (Image) + return Image->getPitch(); + else + return 0; +} + + + +//! return open gl texture name +GLuint COpenGLTexture::getOpenGLTextureName() const +{ + return TextureName; +} + + +//! Returns whether this texture has mipmaps +//! return true if texture has mipmaps +bool COpenGLTexture::hasMipMaps() const +{ + return HasMipMaps; +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void COpenGLTexture::regenerateMipMapLevels() +{ + if (AutomaticMipmapUpdate || !HasMipMaps) + return; + if ((Image->getDimension().Width==1) && (Image->getDimension().Height==1)) + return; + + // Manually create mipmaps + u32 width=Image->getDimension().Width; + u32 height=Image->getDimension().Height; + u32 i=0; + u8* target = new u8[Image->getImageDataSizeInBytes()]; + do + { + if (width>1) + width>>=1; + if (height>1) + height>>=1; + ++i; + Image->copyToScaling(target, width, height, Image->getColorFormat()); + glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height, + 0, PixelFormat, PixelType, target); + } + while (width!=1 || height!=1); + delete [] target; + Image->unlock(); +} + + +bool COpenGLTexture::isFrameBufferObject() const +{ + return ColorFrameBuffer != 0; +} + +bool COpenGLTexture::isRenderTarget() const +{ + return IsRenderTarget; +} + +void COpenGLTexture::setRenderTarget(bool isTarget) +{ + IsRenderTarget = isTarget; +} + + +//! Bind ColorFrameBuffer (valid only if isFrameBufferObject() returns true). +void COpenGLTexture::bindFrameBufferObject() +{ +#ifdef GL_EXT_framebuffer_object + if (ColorFrameBuffer != 0) + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer); +#endif +} + + +//! Unbind ColorFrameBuffer (valid only if isFrameBufferObject() returns true). +void COpenGLTexture::unbindFrameBufferObject() +{ +#ifdef GL_EXT_framebuffer_object + if (ColorFrameBuffer != 0) + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); +#endif +} + +bool checkFBOStatus(COpenGLDriver* Driver) +{ +#ifdef GL_EXT_framebuffer_object + GLenum status = Driver->extGlCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + + switch (status) + { + //Our FBO is perfect, return true + case GL_FRAMEBUFFER_COMPLETE_EXT: + return true; + + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + os::Printer::log("FBO has invalid read buffer", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + os::Printer::log("FBO has invalid draw buffer", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + os::Printer::log("FBO has one or several incomplete image attachments", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + os::Printer::log("FBO has one or several image attachments with different internal formats", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + os::Printer::log("FBO has one or several image attachments with different dimensions", ELL_ERROR); + break; + +// not part of fbo_object anymore, but won't harm as it is just a return value +#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT + case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: + os::Printer::log("FBO has a duplicate image attachment", ELL_ERROR); + break; +#endif + + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + os::Printer::log("FBO missing an image attachment", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + os::Printer::log("FBO format unsupported", ELL_ERROR); + break; + + default: + break; + } + os::Printer::log("FBO error", ELL_ERROR); +#endif + return false; +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OPENGL_ diff --git a/src/dep/src/irrlicht/COpenGLTexture.h b/src/dep/src/irrlicht/COpenGLTexture.h new file mode 100644 index 0000000..5e84225 --- /dev/null +++ b/src/dep/src/irrlicht/COpenGLTexture.h @@ -0,0 +1,144 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPEN_GL_TEXTURE_H_INCLUDED__ +#define __C_OPEN_GL_TEXTURE_H_INCLUDED__ + +#include "ITexture.h" +#include "IImage.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#ifdef _IRR_WINDOWS_API_ + // include windows headers for HWND + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#ifdef _MSC_VER + #pragma comment(lib, "OpenGL32.lib") + #pragma comment(lib, "GLu32.lib") +#endif +#else + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #endif + #if defined(MACOSX) + #include + #else + #include + #endif + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #endif +#endif + + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +//! OpenGL texture. +class COpenGLTexture : public ITexture +{ +public: + + //! constructor + COpenGLTexture(IImage* surface, const char* name, COpenGLDriver* driver=0); + //! FrameBufferObject constructor + COpenGLTexture(const core::dimension2d& size, bool extPackedDepthStencilSupported, const char* name, COpenGLDriver* driver=0); + + //! destructor + virtual ~COpenGLTexture(); + + //! lock function + virtual void* lock(); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns size of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! return open gl texture name + GLuint getOpenGLTextureName() const; + + //! return whether this texture has mipmaps + virtual bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. Useful after + //! locking and modifying the texture + virtual void regenerateMipMapLevels(); + + //! Is it a render target? + virtual bool isRenderTarget() const; + + //! Is it a FrameBufferObject? + bool isFrameBufferObject() const; + + //! Bind FrameBufferObject (valid only if isFrameBufferObject() returns true). + void bindFrameBufferObject(); + + //! Unbind FrameBufferObject (valid only if isFrameBufferObject() returns true). + void unbindFrameBufferObject(); + + //! sets whether this texture is intended to be used as a render target. + void setRenderTarget(bool isTarget); + +private: + + //! get the desired color format based on texture creation flags and the input format. + ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format); + + //! convert the image into an internal image with better properties for this driver. + void getImageData(IImage* image); + + //! copies the the texture into an open gl texture. + //! \param: newTexture is true if method is called from a newly created texture for the first time. Otherwise call with false to improve memory handling. + void copyTexture(bool newTexture=true); + + //! returns the size of a texture which would be the optimize size for rendering it + inline s32 getTextureSizeFromSurfaceSize(s32 size) const; + + core::dimension2d ImageSize; + COpenGLDriver* Driver; + IImage* Image; + + GLuint TextureName; + GLint InternalFormat; + GLenum PixelFormat; + GLenum PixelType; + bool HasMipMaps; + bool IsRenderTarget; + bool AutomaticMipmapUpdate; + + GLuint ColorFrameBuffer; // for FBO path + GLuint DepthRenderBuffer; // for FBO path + GLuint StencilRenderBuffer; // for FBO path + + u32 Locks; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif // _IRR_COMPILE_WITH_OPENGL_ + diff --git a/src/dep/src/irrlicht/CPakReader.cpp b/src/dep/src/irrlicht/CPakReader.cpp new file mode 100644 index 0000000..062ea83 --- /dev/null +++ b/src/dep/src/irrlicht/CPakReader.cpp @@ -0,0 +1,226 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code contributed by skreamz + +#include "CPakReader.h" +#include "os.h" + +#include "IrrCompileConfig.h" + +namespace irr +{ +namespace io +{ + + +CPakReader::CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths) +: File(file), IgnoreCase(ignoreCase), IgnorePaths(ignorePaths) +{ + #ifdef _DEBUG + setDebugName("CPakReader"); + #endif + + if (File) + { + File->grab(); + + // scan local headers + scanLocalHeader(); + + // prepare file index for binary search + FileList.sort(); + } +} + +CPakReader::~CPakReader() +{ + if (File) + File->drop(); +} + + + +//! splits filename from zip file into useful filenames and paths +void CPakReader::extractFilename(SPakFileEntry* entry) +{ + s32 lorfn = 56; // length of real file name + + if (!lorfn) + return; + + if (IgnoreCase) + entry->pakFileName.make_lower(); + + const c8* p = entry->pakFileName.c_str() + lorfn; + + // suche ein slash oder den anfang. + + while (*p!='/' && p!=entry->pakFileName.c_str()) + { + --p; + --lorfn; + } + + bool thereIsAPath = p != entry->pakFileName.c_str(); + + if (thereIsAPath) + { + // there is a path + ++p; + ++lorfn; + } + + entry->simpleFileName = p; + entry->path = ""; + + // pfad auch kopieren + if (thereIsAPath) + { + lorfn = (s32)(p - entry->pakFileName.c_str()); + entry->path.append(entry->pakFileName, lorfn); + } + + if (!IgnorePaths) + entry->simpleFileName = entry->pakFileName; // thanks to Pr3t3nd3r for this fix +} + + + +//! scans for a local header, returns false if there is no more local file header. +bool CPakReader::scanLocalHeader() +{ + c8 tmp[1024]; + + SPakFileEntry entry; + entry.pos = 0; + + memset(&header, 0, sizeof(SPAKFileHeader)); + File->read(&header, sizeof(SPAKFileHeader)); + + + if (header.tag[0] != 'P' && header.tag[1] != 'A') + return false; // local file headers end here. + + File->seek(header.offset); + + const int count = header.length / ((sizeof(u32) * 2) + 56); + + for(int i = 0; i < count; i++) + { + // read filename + entry.pakFileName.reserve(56+2); + File->read(tmp, 56); + tmp[56] = 0x0; + entry.pakFileName = tmp; + + #ifdef _DEBUG + os::Printer::log(entry.pakFileName.c_str()); + #endif + + extractFilename(&entry); + + File->read(&entry.pos, sizeof(u32)); + File->read(&entry.length, sizeof(u32)); + FileList.push_back(entry); + } + + return true; +} + + + +//! opens a file by file name +IReadFile* CPakReader::openFile(const c8* filename) +{ + s32 index = findFile(filename); + + if (index != -1) + return openFile(index); + + return 0; +} + + + +//! opens a file by index +IReadFile* CPakReader::openFile(s32 index) +{ + File->seek(FileList[index].pos); + return createLimitReadFile(FileList[index].simpleFileName.c_str(), File, FileList[index].length); +} + + + +//! returns count of files in archive +s32 CPakReader::getFileCount() +{ + return FileList.size(); +} + + + +//! returns data of file +const SPakFileEntry* CPakReader::getFileInfo(s32 index) const +{ + return &FileList[index]; +} + + + +//! deletes the path from a filename +void CPakReader::deletePathFromFilename(core::stringc& filename) +{ + // delete path from filename + const c8* p = filename.c_str() + filename.size(); + + // suche ein slash oder den anfang. + + while (*p!='/' && *p!='\\' && p!=filename.c_str()) + --p; + + core::stringc newName; + + if (p != filename.c_str()) + { + ++p; + filename = p; + } +} + + + +//! returns fileindex +s32 CPakReader::findFile(const c8* simpleFilename) +{ + SPakFileEntry entry; + entry.simpleFileName = simpleFilename; + + if (IgnoreCase) + entry.simpleFileName.make_lower(); + + if (IgnorePaths) + deletePathFromFilename(entry.simpleFileName); + + s32 res = FileList.binary_search(entry); + + #ifdef _DEBUG + if (res == -1) + { + for (u32 i=0; i FileList; + + bool IgnoreCase; + bool IgnorePaths; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp b/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp new file mode 100644 index 0000000..6436479 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp @@ -0,0 +1,203 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleAnimatedMeshSceneNodeEmitter.h" +#include "IAnimatedMeshSceneNode.h" +#include "IMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleAnimatedMeshSceneNodeEmitter::CParticleAnimatedMeshSceneNodeEmitter( + IAnimatedMeshSceneNode* node, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) + : Node(node), TotalVertices(0), MBCount(0), MBNumber(mbNumber), + EveryMeshVertex(everyMeshVertex), UseNormalDirection(useNormalDirection), + NormalDirectionModifier(normalDirectionModifier), Direction(direction), + MinParticlesPerSecond(minParticlesPerSecond), MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ + AnimatedMesh = node->getMesh(); + BaseMesh = AnimatedMesh->getMesh(0); + + TotalVertices = 0; + MBCount = BaseMesh->getMeshBufferCount(); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( BaseMesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += BaseMesh->getMeshBuffer(i)->getVertexCount(); + } +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleAnimatedMeshSceneNodeEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond * 2) + amount = MaxParticlesPerSecond * 2; + + // Get Mesh for this frame + IMesh* frameMesh = AnimatedMesh->getMesh( core::floor32(Node->getFrameNr()), 255, Node->getStartFrame(), Node->getEndFrame() ); + for(u32 i=0; igetMeshBufferCount(); ++j ) + { + for( u32 k=0; kgetMeshBuffer(j)->getVertexCount(); ++k ) + { + switch( frameMesh->getMeshBuffer(j)->getVertexType() ) + { + case video::EVT_STANDARD: + p.pos = ((video::S3DVertex*)frameMesh->getMeshBuffer(j)->getVertices())[k].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertex*)frameMesh->getMeshBuffer(j)->getVertices())[k].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + case video::EVT_TANGENTS: + p.pos = ((video::S3DVertexTangents*)frameMesh->getMeshBuffer(j)->getVertices())[k].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertexTangents*)frameMesh->getMeshBuffer(j)->getVertices())[k].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + } + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = p.vector; + tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df()); + tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df()); + tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df()); + p.vector = tgt; + } + + if(MaxLifeTime - MinLifeTime == 0) + p.endTime = now + MinLifeTime; + else + p.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); + + p.color = MinStartColor.getInterpolated( + MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); + + p.startColor = p.color; + p.startVector = p.vector; + + Particles.push_back(p); + } + } + } + else + { + s32 randomMB = 0; + + if( MBNumber < 0 ) + { + randomMB = os::Randomizer::rand() % MBCount; + } + else + { + randomMB = MBNumber; + } + + u32 vertexNumber = os::Randomizer::rand() % frameMesh->getMeshBuffer(randomMB)->getVertexCount(); + + switch( frameMesh->getMeshBuffer(randomMB)->getVertexType() ) + { + case video::EVT_STANDARD: + p.pos = ((video::S3DVertex*)frameMesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertex*)frameMesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + case video::EVT_TANGENTS: + p.pos = ((video::S3DVertexTangents*)frameMesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertexTangents*)frameMesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + } + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + p.vector = tgt; + } + + if(MaxLifeTime - MinLifeTime == 0) + p.endTime = now + MinLifeTime; + else + p.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); + + p.color = MinStartColor.getInterpolated( + MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); + + p.startColor = p.color; + p.startVector = p.vector; + + Particles.push_back(p); + } + } + + outArray = Particles.pointer(); + + return Particles.size(); + } + + return 0; +} + +//! Set Mesh to emit particles from +void CParticleAnimatedMeshSceneNodeEmitter::setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ) +{ + Node = node; + AnimatedMesh = node->getMesh(); + BaseMesh = AnimatedMesh->getMesh(0); + + TotalVertices = 0; + MBCount = BaseMesh->getMeshBufferCount(); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( BaseMesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += BaseMesh->getMeshBuffer(i)->getVertexCount(); + } +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h b/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h new file mode 100644 index 0000000..200d25c --- /dev/null +++ b/src/dep/src/irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h @@ -0,0 +1,127 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + +#include "IParticleAnimatedMeshSceneNodeEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! An animated mesh emitter +class CParticleAnimatedMeshSceneNodeEmitter : public IParticleAnimatedMeshSceneNodeEmitter +{ +public: + + //! constructor + CParticleAnimatedMeshSceneNodeEmitter( + IAnimatedMeshSceneNode* node, + bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,-1.0f), + f32 normalDirectionModifier = 100.0f, + s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, + u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set Mesh to emit particles from + virtual void setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ); + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection ) { UseNormalDirection = useNormalDirection; } + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) { NormalDirectionModifier = normalDirectionModifier; } + + //! Sets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex ) { EveryMeshVertex = everyMeshVertex; } + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Get Mesh we're emitting particles from + virtual const IAnimatedMeshSceneNode* getAnimatedMeshSceneNode() const { return Node; } + + //! Get whether to use vertex normal for direciton, or direction specified + virtual bool isUsingNormalDirection() const { return UseNormalDirection; } + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const { return NormalDirectionModifier; } + + //! Gets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual bool getEveryMeshVertex() const { return EveryMeshVertex; } + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + +private: + + IAnimatedMeshSceneNode* Node; + IAnimatedMesh* AnimatedMesh; + const IMesh* BaseMesh; + s32 TotalVertices; + u32 MBCount; + s32 MBNumber; + core::array VertexPerMeshBufferList; + + bool EveryMeshVertex; + bool UseNormalDirection; + f32 NormalDirectionModifier; + core::array Particles; + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CParticleAttractionAffector.cpp b/src/dep/src/irrlicht/CParticleAttractionAffector.cpp new file mode 100644 index 0000000..8934628 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleAttractionAffector.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleAttractionAffector.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleAttractionAffector::CParticleAttractionAffector( + const core::vector3df& point, f32 speed, bool attract, + bool affectX, bool affectY, bool affectZ ) + : Point(point), Speed(speed), AffectX(affectX), AffectY(affectY), + AffectZ(affectZ), Attract(attract), LastTime(0) +{ +} + + +//! Affects an array of particles. +void CParticleAttractionAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if( LastTime == 0 ) + { + LastTime = now; + return; + } + + f32 timeDelta = ( now - LastTime ) / 1000.0f; + LastTime = now; + + if( !Enabled ) + return; + + for(u32 i=0; i everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + const core::vector3df& extent = Box.getExtent(); + + if (amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for (u32 i=0; iaddVector3d("Box", b); + out->addVector3d("Direction", Direction); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + + +//! Reads attributes of the object. +s32 CParticleBoxEmitter::deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + // read data and correct input values here + + core::vector3df b = in->getAttributeAsVector3d("Box"); + + if (b.X <= 0) + b.X = 1.0f; + if (b.Y <= 0) + b.Y = 1.0f; + if (b.Z <= 0) + b.Z = 1.0f; + + Box.MinEdge.X = -b.X; + Box.MinEdge.Y = -b.Y; + Box.MinEdge.Z = -b.Z; + Box.MaxEdge.X = b.X; + Box.MaxEdge.Y = b.Y; + Box.MaxEdge.Z = b.Z; + + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); + + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + + return in->findAttribute("MaxAngleDegrees"); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleBoxEmitter.h b/src/dep/src/irrlicht/CParticleBoxEmitter.h new file mode 100644 index 0000000..79c4feb --- /dev/null +++ b/src/dep/src/irrlicht/CParticleBoxEmitter.h @@ -0,0 +1,99 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_BOX_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_BOX_EMITTER_H_INCLUDED__ + +#include "IParticleBoxEmitter.h" +#include "irrArray.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleBoxEmitter : public IParticleBoxEmitter +{ +public: + + //! constructor + CParticleBoxEmitter( + const core::aabbox3df& box, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + video::SColor minStartColor = video::SColor(255,0,0,0), + video::SColor maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles. + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles emitted per second. + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles emitted per second. + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum start color. + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum start color. + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set box from which the particles are emitted. + virtual void setBox( const core::aabbox3df& box ) { Box = box; } + + //! Gets direction the emitter emits particles. + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets minimum number of particles emitted per second. + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets maximum number of particles emitted per second. + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets minimum start color. + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets maximum start color. + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Get box from which the particles are emitted. + virtual const core::aabbox3df& getBox() const { return Box; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::array Particles; + core::aabbox3df Box; + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleCylinderEmitter.cpp b/src/dep/src/irrlicht/CParticleCylinderEmitter.cpp new file mode 100644 index 0000000..11c2fa4 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleCylinderEmitter.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleCylinderEmitter.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleCylinderEmitter::CParticleCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees) + : Center(center), Normal(normal), Radius(radius), Length(length), OutlineOnly( outlineOnly ), + Direction(direction), MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), Time(0), Emitted(0), + MaxAngleDegrees(maxAngleDegrees) +{ +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleCylinderEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; i Particles; + + core::vector3df Center; + core::vector3df Normal; + f32 Radius; + f32 Length; + bool OutlineOnly; + + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleFadeOutAffector.cpp b/src/dep/src/irrlicht/CParticleFadeOutAffector.cpp new file mode 100644 index 0000000..ffebb58 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleFadeOutAffector.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleFadeOutAffector.h" +#include "IAttributes.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleFadeOutAffector::CParticleFadeOutAffector( + const video::SColor& targetColor, u32 fadeOutTime) + : IParticleFadeOutAffector(), TargetColor(targetColor) +{ + FadeOutTime = fadeOutTime ? static_cast(fadeOutTime) : 1.0f; +} + + +//! Affects an array of particles. +void CParticleFadeOutAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if (!Enabled) + return; + f32 d; + + for (u32 i=0; iaddColor("TargetColor", TargetColor); + out->addFloat("FadeOutTime", FadeOutTime); +} + +//! Reads attributes of the object. +//! Implement this to set the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml deserialization purposes. +//! \param startIndex: start index where to start reading attributes. +//! \return: returns last index of an attribute read by this affector +s32 CParticleFadeOutAffector::deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + const char* name = in->getAttributeName(startIndex); + + if (!name || strcmp(name, "TargetColor")) + return startIndex; // attribute not valid + + TargetColor = in->getAttributeAsColor(startIndex); + ++startIndex; + + name = in->getAttributeName(startIndex); + if (!name || strcmp(name, "FadeOutTime")) + return startIndex; // attribute not valid + + FadeOutTime = in->getAttributeAsFloat(startIndex); + + ++startIndex; + return startIndex; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleFadeOutAffector.h b/src/dep/src/irrlicht/CParticleFadeOutAffector.h new file mode 100644 index 0000000..6260c16 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleFadeOutAffector.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + +#include "IParticleFadeOutAffector.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for fading out a color +class CParticleFadeOutAffector : public IParticleFadeOutAffector +{ +public: + + CParticleFadeOutAffector(const video::SColor& targetColor, u32 fadeOutTime); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Sets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual void setTargetColor( const video::SColor& targetColor ) { TargetColor = targetColor; } + + //! Sets the amount of time it takes for each particle to fade out. + virtual void setFadeOutTime( f32 fadeOutTime ) { FadeOutTime = fadeOutTime; } + + //! Sets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual const video::SColor& getTargetColor() const { return TargetColor; } + + //! Sets the amount of time it takes for each particle to fade out. + virtual f32 getFadeOutTime() const { return FadeOutTime; } + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \return: returns last index of an attribute read by this affector + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + video::SColor TargetColor; + f32 FadeOutTime; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleGravityAffector.cpp b/src/dep/src/irrlicht/CParticleGravityAffector.cpp new file mode 100644 index 0000000..f4b18a2 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleGravityAffector.cpp @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleGravityAffector.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleGravityAffector::CParticleGravityAffector( + const core::vector3df& gravity, u32 timeForceLost) + : IParticleGravityAffector(), TimeForceLost(static_cast(timeForceLost)), Gravity(gravity) +{ +} + + +//! Affects an array of particles. +void CParticleGravityAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if (!Enabled) + return; + f32 d; + + for (u32 i=0; i 1.0f) + d = 1.0f; + if (d < 0.0f) + d = 0.0f; + d = 1.0f - d; + + particlearray[i].vector = particlearray[i].startVector.getInterpolated(Gravity, d); + } +} + +//! Writes attributes of the object. +void CParticleGravityAffector::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Gravity", Gravity); + out->addFloat("TimeForceLost", TimeForceLost); +} + + +//! Reads attributes of the object. +s32 CParticleGravityAffector::deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + const char* name = in->getAttributeName(startIndex); + + if (!name || strcmp(name, "Gravity")) + return startIndex; // attribute not valid + + Gravity = in->getAttributeAsVector3d(startIndex); + ++startIndex; + + name = in->getAttributeName(startIndex); + if (!name || strcmp(name, "TimeForceLost")) + return startIndex; // attribute not valid + + TimeForceLost = in->getAttributeAsFloat(startIndex); + + ++startIndex; + return startIndex; +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleGravityAffector.h b/src/dep/src/irrlicht/CParticleGravityAffector.h new file mode 100644 index 0000000..bed10f1 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleGravityAffector.h @@ -0,0 +1,65 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + +#include "IParticleGravityAffector.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for affecting direction of particle +class CParticleGravityAffector : public IParticleGravityAffector +{ +public: + + CParticleGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Set the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual void setTimeForceLost( f32 timeForceLost ) { TimeForceLost = timeForceLost; } + + //! Set the direction and force of gravity. + virtual void setGravity( const core::vector3df& gravity ) { Gravity = gravity; } + + //! Set the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual f32 getTimeForceLost() const { return TimeForceLost; } + + //! Set the direction and force of gravity. + virtual const core::vector3df& getGravity() const { return Gravity; } + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \return: returns last index of an attribute read by this affector + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + f32 TimeForceLost; + core::vector3df Gravity; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleMeshEmitter.cpp b/src/dep/src/irrlicht/CParticleMeshEmitter.cpp new file mode 100644 index 0000000..c9dfcaf --- /dev/null +++ b/src/dep/src/irrlicht/CParticleMeshEmitter.cpp @@ -0,0 +1,196 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CParticleMeshEmitter.h" +#include "os.h" +#include + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleMeshEmitter::CParticleMeshEmitter( + IMesh* mesh, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) + : Mesh(mesh), TotalVertices(0), MBCount(0), MBNumber(mbNumber), + EveryMeshVertex(everyMeshVertex), UseNormalDirection(useNormalDirection), + NormalDirectionModifier(normalDirectionModifier), Direction(direction), + MinParticlesPerSecond(minParticlesPerSecond), MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ + MBCount = Mesh->getMeshBufferCount(); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( Mesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += Mesh->getMeshBuffer(i)->getVertexCount(); + } +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleMeshEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond * 2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; igetMeshBufferCount(); ++j ) + { + for( u32 k=0; kgetMeshBuffer(j)->getVertexCount(); ++k ) + { + switch( Mesh->getMeshBuffer(j)->getVertexType() ) + { + case video::EVT_STANDARD: + p.pos = ((video::S3DVertex*)Mesh->getMeshBuffer(j)->getVertices())[k].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertex*)Mesh->getMeshBuffer(j)->getVertices())[k].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + case video::EVT_TANGENTS: + p.pos = ((video::S3DVertexTangents*)Mesh->getMeshBuffer(j)->getVertices())[k].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertexTangents*)Mesh->getMeshBuffer(j)->getVertices())[k].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + } + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = p.vector; + tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + p.vector = tgt; + } + + if(MaxLifeTime - MinLifeTime == 0) + p.endTime = now + MinLifeTime; + else + p.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); + + p.color = MinStartColor.getInterpolated( + MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); + + p.startColor = p.color; + p.startVector = p.vector; + + Particles.push_back(p); + } + } + } + else + { + s32 randomMB = 0; + + if( MBNumber < 0 ) + { + randomMB = os::Randomizer::rand() % MBCount; + } + else + { + randomMB = MBNumber; + } + + u32 vertexNumber = os::Randomizer::rand() % Mesh->getMeshBuffer(randomMB)->getVertexCount(); + + switch( Mesh->getMeshBuffer(randomMB)->getVertexType() ) + { + case video::EVT_STANDARD: + p.pos = ((video::S3DVertex*)Mesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertex*)Mesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + case video::EVT_TANGENTS: + p.pos = ((video::S3DVertexTangents*)Mesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Pos; + if( UseNormalDirection ) + p.vector = ((video::S3DVertexTangents*)Mesh->getMeshBuffer(randomMB)->getVertices())[vertexNumber].Normal / NormalDirectionModifier; + else + p.vector = Direction; + break; + } + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + p.vector = tgt; + } + + if(MaxLifeTime - MinLifeTime == 0) + p.endTime = now + MinLifeTime; + else + p.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); + + p.color = MinStartColor.getInterpolated( + MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); + + p.startColor = p.color; + p.startVector = p.vector; + + Particles.push_back(p); + } + } + + outArray = Particles.pointer(); + + return Particles.size(); + } + + return 0; +} + +//! Set Mesh to emit particles from +void CParticleMeshEmitter::setMesh( IMesh* mesh ) +{ + Mesh = mesh; + + TotalVertices = 0; + MBCount = Mesh->getMeshBufferCount(); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( Mesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += Mesh->getMeshBuffer(i)->getVertexCount(); + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleMeshEmitter.h b/src/dep/src/irrlicht/CParticleMeshEmitter.h new file mode 100644 index 0000000..83a1593 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleMeshEmitter.h @@ -0,0 +1,126 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ + +#include "IParticleMeshEmitter.h" +#include "irrArray.h" +#include "aabbox3d.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleMeshEmitter : public IParticleMeshEmitter +{ +public: + + //! constructor + CParticleMeshEmitter( + IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, + s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, + u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set Mesh to emit particles from + virtual void setMesh( IMesh* mesh ); + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection ) { UseNormalDirection = useNormalDirection; } + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) { NormalDirectionModifier = normalDirectionModifier; } + + //! Sets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex ) { EveryMeshVertex = everyMeshVertex; } + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Get Mesh we're emitting particles from + virtual const IMesh* getMesh() const { return Mesh; } + + //! Get whether to use vertex normal for direciton, or direction specified + virtual bool isUsingNormalDirection() const { return UseNormalDirection; } + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const { return NormalDirectionModifier; } + + //! Gets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual bool getEveryMeshVertex() const { return EveryMeshVertex; } + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + +private: + + const IMesh* Mesh; + s32 TotalVertices; + u32 MBCount; + s32 MBNumber; + core::array VertexPerMeshBufferList; + + bool EveryMeshVertex; + bool UseNormalDirection; + f32 NormalDirectionModifier; + core::array Particles; + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/CParticlePointEmitter.cpp b/src/dep/src/irrlicht/CParticlePointEmitter.cpp new file mode 100644 index 0000000..56a4bc1 --- /dev/null +++ b/src/dep/src/irrlicht/CParticlePointEmitter.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticlePointEmitter.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticlePointEmitter::CParticlePointEmitter( + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, video::SColor minStartColor, + video::SColor maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) + : Direction(direction), MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + MaxAngleDegrees(maxAngleDegrees), Time(0), Emitted(0) +{ + +} + + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticlePointEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if (Time > everyWhatMillisecond) + { + Time = 0; + Particle.startTime = now; + Particle.vector = Direction; + + if (MaxAngleDegrees) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees, core::vector3df(0,0,0)); + Particle.vector = tgt; + } + + if (MaxLifeTime - MinLifeTime == 0) + Particle.endTime = now + MinLifeTime; + else + Particle.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); + + Particle.color = MinStartColor.getInterpolated( + MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); + + Particle.startColor = Particle.color; + Particle.startVector = Particle.vector; + outArray = &Particle; + return 1; + } + + return 0; +} + + +//! Writes attributes of the object. +void CParticlePointEmitter::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Direction", Direction); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + + +//! Reads attributes of the object. +s32 CParticlePointEmitter::deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); + + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + + return in->findAttribute("MaxAngleDegrees"); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticlePointEmitter.h b/src/dep/src/irrlicht/CParticlePointEmitter.h new file mode 100644 index 0000000..fde6cc3 --- /dev/null +++ b/src/dep/src/irrlicht/CParticlePointEmitter.h @@ -0,0 +1,90 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_POINT_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_POINT_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! A default point emitter +class CParticlePointEmitter : public IParticlePointEmitter +{ +public: + + //! constructor + CParticlePointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + video::SColor minStartColor = video::SColor(255,0,0,0), + video::SColor maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles. + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles emitted per second. + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles emitted per second. + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum start color. + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum start color. + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Gets direction the emitter emits particles. + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets minimum number of particles emitted per second. + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets maximum number of particles emitted per second. + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets minimum start color. + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets maximum start color. + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual s32 deserializeAttributes(s32 startIndex, io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + SParticle Particle; + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + s32 MaxAngleDegrees; + + u32 Time; + u32 Emitted; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleRingEmitter.cpp b/src/dep/src/irrlicht/CParticleRingEmitter.cpp new file mode 100644 index 0000000..408c08e --- /dev/null +++ b/src/dep/src/irrlicht/CParticleRingEmitter.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleRingEmitter.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleRingEmitter::CParticleRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) + : Center(center), Radius(radius), RingThickness(ringThickness), + Direction(direction), MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), MinStartColor(minStartColor), + MaxStartColor(maxStartColor), MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleRingEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; i Particles; + + core::vector3df Center; + f32 Radius; + f32 RingThickness; + + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; + + f32 MinimumDistance; + f32 MaximumDistance; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleRotationAffector.cpp b/src/dep/src/irrlicht/CParticleRotationAffector.cpp new file mode 100644 index 0000000..51808e1 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleRotationAffector.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleRotationAffector.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleRotationAffector::CParticleRotationAffector( const core::vector3df& speed, const core::vector3df& pivotPoint ) + : PivotPoint(pivotPoint), Speed(speed), LastTime(0) +{ +} + + +//! Affects an array of particles. +void CParticleRotationAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if( LastTime == 0 ) + { + LastTime = now; + return; + } + + f32 timeDelta = ( now - LastTime ) / 1000.0f; + LastTime = now; + + if( !Enabled ) + return; + + for(u32 i=0; i + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleSphereEmitter::CParticleSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) + : Center(center), Radius(radius), Direction(direction), MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), Time(0), Emitted(0), + MaxAngleDegrees(maxAngleDegrees) +{ +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleSphereEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? (f32)MinParticlesPerSecond + (os::Randomizer::rand() % pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; i Particles; + + core::vector3df Center; + f32 Radius; + + core::vector3df Direction; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CParticleSystemSceneNode.cpp b/src/dep/src/irrlicht/CParticleSystemSceneNode.cpp new file mode 100644 index 0000000..dd3706d --- /dev/null +++ b/src/dep/src/irrlicht/CParticleSystemSceneNode.cpp @@ -0,0 +1,638 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleSystemSceneNode.h" +#include "os.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "IVideoDriver.h" + +#include "CParticleAnimatedMeshSceneNodeEmitter.h" +#include "CParticleBoxEmitter.h" +#include "CParticleCylinderEmitter.h" +#include "CParticleMeshEmitter.h" +#include "CParticlePointEmitter.h" +#include "CParticleRingEmitter.h" +#include "CParticleSphereEmitter.h" +#include "CParticleAttractionAffector.h" +#include "CParticleFadeOutAffector.h" +#include "CParticleGravityAffector.h" +#include "CParticleRotationAffector.h" +#include "SViewFrustum.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter, + ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) + : IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale), + Emitter(0), LastEmitTime(0), ParticlesAreGlobal(true) +{ + #ifdef _DEBUG + setDebugName("CParticleSystemSceneNode"); + #endif + + if (createDefaultEmitter) + { + IParticleEmitter* e = createBoxEmitter(); + setEmitter(e); + e->drop(); + } + + setParticleSize(); +} + + + +//! destructor +CParticleSystemSceneNode::~CParticleSystemSceneNode() +{ + if (Emitter) + Emitter->drop(); + + removeAllAffectors(); +} + + + +//! Sets the particle emitter, which creates the particles. +void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) +{ + if (Emitter) + Emitter->drop(); + + Emitter = emitter; + + if (Emitter) + Emitter->grab(); +} + + + +//! Adds new particle effector to the particle system. +void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) +{ + affector->grab(); + AffectorList.push_back(affector); +} + + + +//! Removes all particle affectors in the particle system. +void CParticleSystemSceneNode::removeAllAffectors() +{ + core::list::Iterator it = AffectorList.begin(); + while (it != AffectorList.end()) + { + (*it)->drop(); + it = AffectorList.erase(it); + } +} + + +//! Returns the material based on the zero based index i. +video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i) +{ + return Buffer.Material; +} + + + +//! Returns amount of materials used by this scene node. +u32 CParticleSystemSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Creates a particle emitter for an animated mesh scene node +IParticleAnimatedMeshSceneNodeEmitter* +CParticleSystemSceneNode::createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) +{ + return new CParticleAnimatedMeshSceneNodeEmitter( node, + useNormalDirection, direction, normalDirectionModifier, + mbNumber, everyMeshVertex, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees ); +} + + + +//! Creates a box particle emitter. +IParticleBoxEmitter* CParticleSystemSceneNode::createBoxEmitter( + const core::aabbox3df& box, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) +{ + return new CParticleBoxEmitter(box, direction, minParticlesPerSecond, + maxParticlesPerSecond, minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees); +} + + +//! Creates a particle emitter for emitting from a cylinder +IParticleCylinderEmitter* CParticleSystemSceneNode::createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) +{ + return new CParticleCylinderEmitter( center, radius, normal, length, + outlineOnly, direction, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees ); +} + + +//! Creates a mesh particle emitter. +IParticleMeshEmitter* CParticleSystemSceneNode::createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) +{ + return new CParticleMeshEmitter( mesh, useNormalDirection, direction, + normalDirectionModifier, mbNumber, everyMeshVertex, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees ); +} + + + +//! Creates a point particle emitter. +IParticlePointEmitter* CParticleSystemSceneNode::createPointEmitter( + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) +{ + return new CParticlePointEmitter(direction, minParticlesPerSecond, + maxParticlesPerSecond, minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees); +} + + +//! Creates a ring particle emitter. +IParticleRingEmitter* CParticleSystemSceneNode::createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees ) +{ + return new CParticleRingEmitter( center, radius, ringThickness, direction, + minParticlesPerSecond, maxParticlesPerSecond, minStartColor, + maxStartColor, lifeTimeMin, lifeTimeMax, maxAngleDegrees ); +} + + +//! Creates a sphere particle emitter. +IParticleSphereEmitter* CParticleSystemSceneNode::createSphereEmitter( + const core::vector3df& center, f32 radius, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees) +{ + return new CParticleSphereEmitter(center, radius, direction, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees); +} + + + +//! Creates a point attraction affector. This affector modifies the positions of the +//! particles and attracts them to a specified point at a specified speed per second. +IParticleAttractionAffector* CParticleSystemSceneNode::createAttractionAffector( + const core::vector3df& point, f32 speed, bool attract, + bool affectX, bool affectY, bool affectZ ) +{ + return new CParticleAttractionAffector( point, speed, attract, affectX, affectY, affectZ ); +} + + +//! Creates a fade out particle affector. +IParticleFadeOutAffector* CParticleSystemSceneNode::createFadeOutParticleAffector( + const video::SColor& targetColor, u32 timeNeededToFadeOut) +{ + return new CParticleFadeOutAffector(targetColor, timeNeededToFadeOut); +} + + +//! Creates a gravity affector. +IParticleGravityAffector* CParticleSystemSceneNode::createGravityAffector( + const core::vector3df& gravity, u32 timeForceLost) +{ + return new CParticleGravityAffector(gravity, timeForceLost); +} + + +//! Creates a rotation affector. This affector rotates the particles around a specified pivot +//! point. The speed represents Degrees of rotation per second. +IParticleRotationAffector* CParticleSystemSceneNode::createRotationAffector( + const core::vector3df& speed, const core::vector3df& pivotPoint ) +{ + return new CParticleRotationAffector( speed, pivotPoint ); +} + + + +//! pre render event +void CParticleSystemSceneNode::OnRegisterSceneNode() +{ + doParticleSystem(os::Timer::getTime()); + + if (IsVisible && (Particles.size() != 0)) + { + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); + } +} + + + +//! render +void CParticleSystemSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + +#if 0 + // calculate vectors for letting particles look to camera + core::vector3df view(camera->getTarget() - camera->getAbsolutePosition()); + view.normalize(); + + core::vector3df horizontal = camera->getUpVector().crossProduct(view); + horizontal.normalize(); + horizontal *= 0.5f * ParticleSize.Width; + + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * ParticleSize.Height; + + view *= -1.0f; + +#else + + const core::matrix4 &m = camera->getViewFrustum()->Matrices [ video::ETS_VIEW ]; + + f32 f; + + f = 0.5f * ParticleSize.Width; + const core::vector3df horizontal ( m[0] * f, m[4] * f, m[8] * f ); + + f = -0.5f * ParticleSize.Height; + const core::vector3df vertical ( m[1] * f, m[5] * f, m[9] * f ); + + const core::vector3df view ( -m[2], -m[6] , -m[10] ); + +#endif + + // reallocate arrays, if they are too small + reallocateBuffers(); + + // create particle vertex data + s32 idx = 0; + for (u32 i=0; isetTransform(video::ETS_WORLD, mat); + + driver->setMaterial(Buffer.Material); + + driver->drawVertexPrimitiveList(Buffer.getVertices(), Particles.size()*4, + Buffer.getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES); + + // for debug purposes only: + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial deb_m; + deb_m.Lighting = false; + driver->setMaterial(deb_m); + driver->draw3DBox(Buffer.BoundingBox, video::SColor(0,255,255,255)); + } +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CParticleSystemSceneNode::getBoundingBox() const +{ + return Buffer.getBoundingBox(); +} + + + +void CParticleSystemSceneNode::doParticleSystem(u32 time) +{ + if (LastEmitTime==0) + { + LastEmitTime = time; + return; + } + + u32 now = time; + u32 timediff = time - LastEmitTime; + LastEmitTime = time; + + // run emitter + + if (Emitter && IsVisible) + { + SParticle* array = 0; + s32 newParticles = Emitter->emitt(now, timediff, array); + + if (newParticles && array) + { + s32 j=Particles.size(); + if (newParticles > 16250-j) + newParticles=16250-j; + Particles.set_used(j+newParticles); + for (s32 i=j; i::Iterator ait = AffectorList.begin(); + for (; ait != AffectorList.end(); ++ait) + (*ait)->affect(now, Particles.pointer(), Particles.size()); + + if (ParticlesAreGlobal) + Buffer.BoundingBox.reset(AbsoluteTransformation.getTranslation()); + else + Buffer.BoundingBox.reset(core::vector3df(0,0,0)); + + // animate all particles + f32 scale = (f32)timediff; + + for (s32 i=0; i<(s32)Particles.size();) + { + if (now > Particles[i].endTime) + Particles.erase(i); + else + { + Particles[i].pos += (Particles[i].vector * scale); + Buffer.BoundingBox.addInternalPoint(Particles[i].pos); + ++i; + } + } + + f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height; + m *= 0.5f; + Buffer.BoundingBox.MaxEdge.X += m; + Buffer.BoundingBox.MaxEdge.Y += m; + Buffer.BoundingBox.MaxEdge.Z += m; + + Buffer.BoundingBox.MinEdge.X -= m; + Buffer.BoundingBox.MinEdge.Y -= m; + Buffer.BoundingBox.MinEdge.Z -= m; + + if (ParticlesAreGlobal) + { + core::matrix4 absinv = AbsoluteTransformation; + absinv.makeInverse(); + absinv.transformBox(Buffer.BoundingBox); + } +} + + +//! Sets if the particles should be global. If it is, the particles are affected by +//! the movement of the particle system scene node too, otherwise they completely +//! ignore it. Default is true. +void CParticleSystemSceneNode::setParticlesAreGlobal(bool global) +{ + ParticlesAreGlobal = global; +} + + + +//! Sets the size of all particles. +void CParticleSystemSceneNode::setParticleSize(const core::dimension2d &size) +{ + ParticleSize = size; +} + + +void CParticleSystemSceneNode::reallocateBuffers() +{ + if (Particles.size() * 4 > Buffer.getVertexCount() || + Particles.size() * 6 > Buffer.getIndexCount()) + { + u32 oldSize = Buffer.getVertexCount(); + Buffer.Vertices.set_used(Particles.size() * 4); + + u32 i; + + // fill remaining vertices + for (i=oldSize; iaddBool("GlobalParticles", ParticlesAreGlobal); + out->addFloat("ParticleWidth", ParticleSize.Width); + out->addFloat("ParticleHeight", ParticleSize.Height); + + // write emitter + + E_PARTICLE_EMITTER_TYPE type = EPET_COUNT; + if (Emitter) + type = Emitter->getType(); + + out->addEnum("Emitter", (s32)type, ParticleEmitterTypeNames); + + if (Emitter) + Emitter->serializeAttributes(out, options); + + // write affectors + + E_PARTICLE_AFFECTOR_TYPE atype = EPAT_NONE; + + for (core::list::ConstIterator it = AffectorList.begin(); + it != AffectorList.end(); ++it) + { + atype = (*it)->getType(); + + out->addEnum("Affector", (s32)atype, ParticleAffectorTypeNames); + + (*it)->serializeAttributes(out); + } + + // add empty affector to make it possible to add further affectors + + if (options && options->Flags & io::EARWF_FOR_EDITOR) + out->addEnum("Affector", EPAT_NONE, ParticleAffectorTypeNames); +} + + +//! Reads attributes of the scene node. +void CParticleSystemSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IParticleSystemSceneNode::deserializeAttributes(in, options); + + ParticlesAreGlobal = in->getAttributeAsBool("GlobalParticles"); + ParticleSize.Width = in->getAttributeAsFloat("ParticleWidth"); + ParticleSize.Height = in->getAttributeAsFloat("ParticleHeight"); + + // read emitter + + int emitterIdx = in->findAttribute("Emitter"); + if (emitterIdx == -1) + return; + + if (Emitter) + Emitter->drop(); + Emitter = 0; + + E_PARTICLE_EMITTER_TYPE type = (E_PARTICLE_EMITTER_TYPE) + in->getAttributeAsEnumeration("Emitter", ParticleEmitterTypeNames); + + switch(type) + { + case EPET_POINT: + Emitter = createPointEmitter(); + break; + case EPET_BOX: + Emitter = createBoxEmitter(); + break; + default: + break; + } + + u32 idx = 0; + + if (Emitter) + idx = Emitter->deserializeAttributes(idx, in); + + ++idx; + + // read affectors + + removeAllAffectors(); + u32 cnt = in->getAttributeCount(); + + while(idx < cnt) + { + const char* name = in->getAttributeName(idx); + + if (!name || strcmp("Affector", name)) + return; + + E_PARTICLE_AFFECTOR_TYPE atype = + (E_PARTICLE_AFFECTOR_TYPE)in->getAttributeAsEnumeration(idx, ParticleAffectorTypeNames); + + IParticleAffector* aff = 0; + + switch(atype) + { + case EPAT_FADE_OUT: + aff = createFadeOutParticleAffector(); + break; + case EPAT_GRAVITY: + aff = createGravityAffector(); + break; + case EPAT_NONE: + default: + break; + } + + ++idx; + + if (aff) + { + idx = aff->deserializeAttributes(idx, in, options); + ++idx; + addAffector(aff); + aff->drop(); + } + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CParticleSystemSceneNode.h b/src/dep/src/irrlicht/CParticleSystemSceneNode.h new file mode 100644 index 0000000..f706f87 --- /dev/null +++ b/src/dep/src/irrlicht/CParticleSystemSceneNode.h @@ -0,0 +1,209 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ +#define __C_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ + +#include "IParticleSystemSceneNode.h" +#include "irrArray.h" +#include "irrList.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! A particle system scene node. +/** A scene node controlling a particle system. The behavior of the particles +can be controlled by setting the right particle emitters and affectors. +*/ +class CParticleSystemSceneNode : public IParticleSystemSceneNode +{ +public: + + //! constructor + CParticleSystemSceneNode(bool createDefaultEmitter, + ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale); + + //! destructor + virtual ~CParticleSystemSceneNode(); + + //! Sets the particle emitter, which creates the particles. + virtual void setEmitter(IParticleEmitter* emitter); + + //! Adds new particle affector to the particle system. + virtual void addAffector(IParticleAffector* affector); + + //! Removes all particle affectors in the particle system. + virtual void removeAllAffectors(); + + //! Returns the material based on the zero based index i. + virtual video::SMaterial& getMaterial(u32 i); + + //! Returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Creates a particle emitter for an animated mesh scene node + virtual IParticleAnimatedMeshSceneNodeEmitter* createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ); + + //! Creates a box particle emitter. + virtual IParticleBoxEmitter* createBoxEmitter( + const core::aabbox3df& box = core::aabbox3d(-10,0,-10,5,30,10), + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Creates a particle emitter for emitting from a cylinder + virtual IParticleCylinderEmitter* createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly = false, const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + u32 minParticlesPerSecond = 5, u32 maxParticlesPersSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ); + + //! Creates a mesh particle emitter. + virtual IParticleMeshEmitter* createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0 ); + + //! Creates a point particle emitter. + virtual IParticlePointEmitter* createPointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Creates a ring particle emitter. + virtual IParticleRingEmitter* createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Creates a sphere particle emitter. + virtual IParticleSphereEmitter* createSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0); + + //! Creates a point attraction affector. This affector modifies the positions of the + //! particles and attracts them to a specified point at a specified speed per second. + virtual IParticleAttractionAffector* createAttractionAffector( + const core::vector3df& point, f32 speed = 1.0f, bool attract = true, + bool affectX = true, bool affectY = true, bool affectZ = true); + + //! Creates a fade out particle affector. + virtual IParticleFadeOutAffector* createFadeOutParticleAffector( + const video::SColor& targetColor = video::SColor(0,0,0,0), + u32 timeNeededToFadeOut = 1000); + + //! Creates a gravity affector. + virtual IParticleGravityAffector* createGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000); + + //! Creates a rotation affector. This affector rotates the particles + //! around a specified pivot point. The speed is in Degrees per second. + virtual IParticleRotationAffector* createRotationAffector( + const core::vector3df& speed = core::vector3df(5.0f,5.0f,5.0f), + const core::vector3df& pivotPoint = core::vector3df(0.0f,0.0f,0.0f) ); + + //! Sets the size of all particles. + virtual void setParticleSize( + const core::dimension2d &size = core::dimension2d(5.0f, 5.0f)); + + //! Sets if the particles should be global. If they are, the particles are affected by + //! the movement of the particle system scene node too, otherwise they completely + //! ignore it. Default is true. + virtual void setParticlesAreGlobal(bool global); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_PARTICLE_SYSTEM; } + +private: + + void doParticleSystem(u32 time); + void reallocateBuffers(); + + core::list AffectorList; + IParticleEmitter* Emitter; + core::array Particles; + core::dimension2d ParticleSize; + u32 LastEmitTime; + s32 MaxParticles; + + SMeshBuffer Buffer; + + enum E_PARTICLES_PRIMITIVE + { + EPP_POINT=0, + EPP_BILLBOARD, + EPP_POINTSPRITE + }; + E_PARTICLES_PRIMITIVE ParticlePrimitive; + + bool ParticlesAreGlobal; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CQ3LevelMesh.cpp b/src/dep/src/irrlicht/CQ3LevelMesh.cpp new file mode 100644 index 0000000..50a8941 --- /dev/null +++ b/src/dep/src/irrlicht/CQ3LevelMesh.cpp @@ -0,0 +1,1844 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + +#include "CQ3LevelMesh.h" +#include "ISceneManager.h" +#include "os.h" +#include "SMeshBufferLightMap.h" +#include "irrString.h" +#include "ILightSceneNode.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr) +: Textures(0), LightMaps(0), + Vertices(0), Faces(0), Planes(0), Nodes(0), Leafs(0), LeafFaces(0), + MeshVerts(0), Brushes(0), Driver(driver), FileSystem(fs), SceneManager ( smgr ) +{ + #ifdef _DEBUG + IReferenceCounted::setDebugName("CQ3LevelMesh"); + #endif + + for ( s32 i = 0; i!= quake3::E_Q3_MESH_SIZE; ++i ) + { + Mesh[i] = 0; + } + + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + // load default shaders + InitShader (); +} + + +//! destructor +CQ3LevelMesh::~CQ3LevelMesh() +{ + delete [] Textures; + delete [] LightMaps; + delete [] Vertices; + delete [] Faces; + delete [] Planes; + delete [] Nodes; + delete [] Leafs; + delete [] LeafFaces; + delete [] MeshVerts; + delete [] Brushes; + + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); + + for ( s32 i = 0; i!= quake3::E_Q3_MESH_SIZE; ++i ) + { + if (Mesh[i]) + Mesh[i]->drop(); + } + + ReleaseShader(); + ReleaseEntity(); +} + + +//! loads a level from a .bsp-File. Also tries to load all needed textures. Returns true if successful. +bool CQ3LevelMesh::loadFile(io::IReadFile* file) +{ + if (!file) + return false; + + LevelName = file->getFileName(); + + tBSPHeader header; + file->read(&header, sizeof(tBSPHeader)); + + #ifdef __BIG_ENDIAN__ + header.strID = os::Byteswap::byteswap(header.strID); + header.version = os::Byteswap::byteswap(header.version); + #endif + + if (header.strID != 0x50534249 || header.version != 0x2e) + { + os::Printer::log("Could not load .bsp file, unknown header.", file->getFileName(), ELL_ERROR); + return false; + } + + // now read lumps + + file->read(&Lumps[0], sizeof(tBSPLump)*kMaxLumps); + + #ifdef __BIG_ENDIAN__ + for (int i=0;idrop (); + Mesh[index] = 0; + } +} + + +//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. +IMesh* CQ3LevelMesh::getMesh(s32 frameInMs, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + return Mesh[frameInMs]; +} + + +void CQ3LevelMesh::loadTextures(tBSPLump* l, io::IReadFile* file) +{ + NumTextures = l->length / sizeof(tBSPTexture); + Textures = new tBSPTexture[NumTextures]; + + file->seek(l->offset); + file->read(Textures, l->length); + + #ifdef __BIG_ENDIAN__ + for (int i=0;ilength / sizeof(tBSPLightmap); + LightMaps = new tBSPLightmap[NumLightMaps]; + + file->seek(l->offset); + file->read(LightMaps, l->length); +} + + +void CQ3LevelMesh::loadVerts(tBSPLump* l, io::IReadFile* file) +{ + NumVertices = l->length / sizeof(tBSPVertex); + Vertices = new tBSPVertex[NumVertices]; + + file->seek(l->offset); + file->read(Vertices, l->length); + + #ifdef __BIG_ENDIAN__ + for (int i=0;ilength / sizeof(tBSPFace); + Faces = new tBSPFace[NumFaces]; + + file->seek(l->offset); + file->read(Faces, l->length); + + #ifdef __BIG_ENDIAN__ + for ( s32 i=0;i entity; + entity.set_used ( l->length + 2 ); + entity[l->length + 1 ] = 0; + + file->seek(l->offset); + file->read ( entity.pointer(), l->length); + + parser_parse ( entity.pointer(), l->length, &CQ3LevelMesh::scriptcallback_entity ); +} + + +// load shaders named in bsp +void CQ3LevelMesh::loadShaders(tBSPLump* l, io::IReadFile* file) +{ + u32 files = l->length / sizeof(tBSPShader); + + file->seek ( l->offset ); + + tBSPShader def; + for ( u32 i = 0; i!= files; ++i ) + { + file->read ( &def, sizeof ( def ) ); + getShader ( def.strName, 1 ); + } +} + + +void CQ3LevelMesh::loadModels(tBSPLump* l, io::IReadFile* file) +{ + // ignore +} + + +void CQ3LevelMesh::loadMeshVerts(tBSPLump* l, io::IReadFile* file) +{ + NumMeshVerts = l->length / sizeof(s32); + MeshVerts = new s32[NumMeshVerts]; + + file->seek(l->offset); + file->read(MeshVerts, l->length); + + #ifdef __BIG_ENDIAN__ + for (int i=0;i= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + } while ( isQ3WhiteSpace ( symbol ) ); + + // first symbol, one symbol + switch ( symbol ) + { + case 0: + Parser.tokenresult = Q3_TOKEN_EOF; + return; + + case '/': + // comment or divide + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + if ( isQ3WhiteSpace ( symbol ) ) + { + Parser.tokenresult = Q3_TOKEN_MATH_DIVIDE; + return; + } + else + if ( symbol == '*' ) + { + // C-style comment in quake? + } + else + if ( symbol == '/' ) + { + // skip to eol + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + } while ( symbol != '\n' ); + Parser.tokenresult = Q3_TOKEN_COMMENT; + return; + } + // take /[name] as valid token..?!?!?. mhmm, maybe + break; + + case '\n': + Parser.tokenresult = Q3_TOKEN_EOL; + return; + case '{': + Parser.tokenresult = Q3_TOKEN_START_LIST; + return; + case '}': + Parser.tokenresult = Q3_TOKEN_END_LIST; + return; + + case '"': + // string literal + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + if ( symbol != '"' ) + Parser.token.append ( symbol ); + } while ( symbol != '"' ); + Parser.tokenresult = Q3_TOKEN_ENTITY; + return; + } + + // user identity + Parser.token.append ( symbol ); + + // continue till whitespace + bool notisWhite = true; + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + + notisWhite = ! isQ3WhiteSpace ( symbol ); + if ( notisWhite ) + { + Parser.token.append ( symbol ); + } + + Parser.index += 1; + + } while ( notisWhite ); + + Parser.tokenresult = Q3_TOKEN_TOKEN; + return; +} + + +/* + parse entity & shader + calls callback on content in {} +*/ +void CQ3LevelMesh::parser_parse ( const void * data, const u32 size, CQ3LevelMesh::tParserCallback callback ) +{ + Parser.source = (const c8*) data; + Parser.sourcesize = size; + Parser.index = 0; + + quake3::SVarGroupList *groupList; + + s32 active; + s32 last; + + quake3::SVariable entity; + + groupList = new quake3::SVarGroupList (); + + groupList->VariableGroup.push_back ( quake3::SVarGroup () ); + active = last = 0; + + do + { + parser_nextToken (); + + switch ( Parser.tokenresult ) + { + case Q3_TOKEN_START_LIST: + { + //stack = core::min_ ( stack + 1, 7 ); + + groupList->VariableGroup.push_back ( quake3::SVarGroup () ); + last = active; + active = groupList->VariableGroup.size() - 1; + entity.clear (); + } break; + + // a unregisterd variable is finished + case Q3_TOKEN_EOL: + { + if ( entity.isValid() ) + { + groupList->VariableGroup[active].Variable.push_back ( entity ); + entity.clear (); + } + } break; + + case Q3_TOKEN_TOKEN: + case Q3_TOKEN_ENTITY: + { + Parser.token.make_lower(); + + // store content based on line-delemiter + if ( 0 == entity.isValid() ) + { + entity.name = Parser.token; + entity.content = ""; + + } + else + { + if ( entity.content.size() ) + { + entity.content += " "; + } + entity.content += Parser.token; + } + } break; + + case Q3_TOKEN_END_LIST: + { + //stack = core::max_ ( stack - 1, 0 ); + + // close tag for first + if ( active == 1 ) + { + (this->*callback) ( groupList ); + + // new group + groupList->drop (); + groupList = new quake3::SVarGroupList (); + groupList->VariableGroup.push_back ( quake3::SVarGroup () ); + last = 0; + } + + active = last; + entity.clear(); + + } break; + + } + + } while ( Parser.tokenresult != Q3_TOKEN_EOF ); + + groupList->drop (); +} + + +/* + this loader applies only textures for stage 1 & 2 +*/ +s32 CQ3LevelMesh::setShaderMaterial ( video::SMaterial &material, const tBSPFace * face ) const +{ + material.MaterialType = video::EMT_SOLID; + material.Wireframe = false; + material.Lighting = false; + material.BackfaceCulling = true; + material.setTexture(0, 0); + material.setTexture(1, 0); + material.setTexture(2, 0); + material.setTexture(3, 0); + material.ZBuffer = true; + material.ZWriteEnable = true; + material.MaterialTypeParam = 0.f; + + s32 shaderState = -1; + + if ( face->textureID >= 0 ) + { + material.setTexture(0, Tex [ face->textureID ].Texture); + shaderState = Tex [ face->textureID ].ShaderID; + } + + if ( face->lightmapID >= 0 ) + { + material.setTexture(1, Lightmap [ face->lightmapID ]); + material.MaterialType = quake3::defaultLightMap; + } + + // store shader ID + material.MaterialTypeParam2 = (f32) shaderState; + + const quake3::SShader *shader = getShader ( shaderState ); + if ( 0 == shader ) + return shaderState; + + const quake3::SVarGroup *group; + + s32 index; + + // generic + group = shader->getGroup ( 1 ); + if ( group ) + { + material.BackfaceCulling = quake3::getBackfaceCulling ( group->get ( "cull" ) ); + + if ( group->isDefined ( "surfaceparm", "nolightmap" ) ) + { + material.MaterialType = video::EMT_SOLID; + material.setTexture(1, 0); + } + + } + + // try to get the best of the 8 texture stages.. + + // texture 1, texture 2 + u32 startPos; + for ( s32 g = 2; g <= 3; ++g ) + { + group = shader->getGroup ( g ); + if ( 0 == group ) + continue; + + startPos = 0; + + index = group->getIndex ( "depthwrite" ); + if ( index >= 0 ) + { + material.ZBuffer = true; + } + + quake3::SBlendFunc blendfunc; + quake3::getBlendFunc ( group->get ( "blendfunc" ), blendfunc ); + quake3::getBlendFunc ( group->get ( "alphafunc" ), blendfunc ); + + material.MaterialType = blendfunc.type; + material.MaterialTypeParam = blendfunc.param; + + // try if we can match better + shaderState |= (material.MaterialType == video::EMT_SOLID ) ? 0x00020000 : 0; + } + + //material.BackfaceCulling = false; + + if ( shader->VarGroup->VariableGroup.size () <= 4 ) + { + shaderState |= 0x00010000; + } + + material.MaterialTypeParam2 = (f32) shaderState; + return shaderState; +} + +//! constructs a mesh from the quake 3 level file. +void CQ3LevelMesh::constructMesh2() +{ + s32 i, j, k; + + s32 *index; + + video::S3DVertex2TCoords temp[3]; + + video::SMaterial material; + + SToBuffer item; + + core::array < SToBuffer > toBuffer; + + const s32 mesh0size = (NumTextures+1) * (NumLightMaps+1); + for ( i=0; i < mesh0size; ++i) + { + scene::SMeshBufferLightMap* buffer = new scene::SMeshBufferLightMap(); + + Mesh[quake3::E_Q3_MESH_GEOMETRY]->addMeshBuffer(buffer); + buffer->drop(); + } + + for ( i=0; i NumLightMaps-1) + { + Faces[i].lightmapID = -1; + } + + // there are lightmapsids and textureid with -1 + const s32 tmp_index = ((Faces[i].lightmapID+1) * (NumTextures+1)) + (Faces[i].textureID+1); + buffer = (SMeshBufferLightMap*) Mesh[quake3::E_Q3_MESH_GEOMETRY]->getMeshBuffer(tmp_index); + buffer->getMaterial() = material; + } + else + { + buffer = (SMeshBufferLightMap*) Mesh[ toBuffer[g].index ]->getMeshBuffer ( material ); + //buffer = 0; + if ( 0 == buffer ) + { + buffer = new scene::SMeshBufferLightMap(); + Mesh[ toBuffer[g].index ]->addMeshBuffer ( buffer ); + buffer->drop (); + buffer->getMaterial() = material; + } + } + + + switch(Faces[i].type) + { + case 4: // billboards + break; + case 2: // patches + createCurvedSurface2(buffer, i, PatchTesselation,toBuffer[g].takeVertexColor); + break; + + case 1: // normal polygons + case 3: // mesh vertices + + index = MeshVerts + face->meshVertIndex; + k = buffer->getVertexCount(); + + for ( j = 0; j < face->numMeshVerts; j += 1 ) + { + buffer->Indices.push_back( k + index [j] ); + } + + for ( j = 0; j != face->numOfVerts; ++j ) + { + copy ( &temp[0], &Vertices[ j + face->vertexIndex ], toBuffer[g].takeVertexColor ); + buffer->Vertices.push_back( temp[0] ); + } + break; + + } // end switch + } + } +} + + +//! constructs a mesh from the quake 3 level file. +void CQ3LevelMesh::constructMesh() +{ + // reserve buffer. + s32 i; // new ISO for scoping problem with some compilers + + for (i=0; i<(NumTextures+1) * (NumLightMaps+1); ++i) + { + scene::SMeshBufferLightMap* buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP_M4; + buffer->Material.Wireframe = false; + buffer->Material.Lighting = false; + + Mesh[0]->addMeshBuffer(buffer); + + buffer->drop(); + } + + // go through all faces and add them to the buffer. + + video::S3DVertex2TCoords temp[3]; + + for (i=0; i NumLightMaps-1) + Faces[i].lightmapID = -1; + + // there are lightmapsids and textureid with -1 + s32 meshBufferIndex = ((Faces[i].lightmapID+1) * (NumTextures+1)) + (Faces[i].textureID+1); + SMeshBufferLightMap* meshBuffer = ((SMeshBufferLightMap*)Mesh[0]->getMeshBuffer(meshBufferIndex)); + + switch(Faces[i].type) + { + //case 3: // mesh vertices + case 1: // normal polygons + { + for (s32 tf=0; tfgetVertexCount(); + s32 vidxes[3]; + + vidxes[0] = MeshVerts[Faces[i].meshVertIndex + tf +0] + + Faces[i].vertexIndex; + vidxes[1] = MeshVerts[Faces[i].meshVertIndex + tf +1] + + Faces[i].vertexIndex; + vidxes[2] = MeshVerts[Faces[i].meshVertIndex + tf +2] + + Faces[i].vertexIndex; + + // add all three vertices + copy ( &temp[0], &Vertices[ vidxes[0] ], 0 ); + copy ( &temp[1], &Vertices[ vidxes[1] ], 0 ); + copy ( &temp[2], &Vertices[ vidxes[2] ], 0 ); + + meshBuffer->Vertices.push_back( temp[0] ); + meshBuffer->Vertices.push_back( temp[1] ); + meshBuffer->Vertices.push_back( temp[2] ); + + // add indexes + + meshBuffer->Indices.push_back(idx); + meshBuffer->Indices.push_back(idx+1); + meshBuffer->Indices.push_back(idx+2); + } + } + break; + case 2: // curved surfaces + createCurvedSurface(meshBuffer, i); + break; + + case 4: // billboards + break; + } // end switch + } +} + + +// helper method for creating curved surfaces, sent in by Dean P. Macri. +inline f32 CQ3LevelMesh::Blend( const f64 s[3], const f64 t[3], const tBSPVertex *v[9], int offset) +{ + f64 res = 0.0; + f32 *ptr; + + for( int i=0; i<3; i++ ) + for( int j=0; j<3; j++ ) + { + ptr = (f32 *)( (char*)v[i*3+j] + offset ); + res += s[i] * t[j] * (*ptr); + } + + return (f32) res; +} + + +void CQ3LevelMesh::S3DVertex2TCoords_64::copyto ( video::S3DVertex2TCoords &dest ) const +{ + dest.Pos.X = core::round_( (f32) Pos.X ); + dest.Pos.Y = core::round_( (f32) Pos.Y ); + dest.Pos.Z = core::round_( (f32) Pos.Z ); + //dest.Pos.X = (f32) Pos.X; + //dest.Pos.Y = (f32) Pos.Y; + //dest.Pos.Z = (f32) Pos.Z; + + dest.Normal.X = (f32) Normal.X; + dest.Normal.Y = (f32) Normal.Y; + dest.Normal.Z = (f32) Normal.Z; + dest.Normal.normalize(); + + dest.Color = Color.toSColor(); + + dest.TCoords.X = (f32) TCoords.X; + dest.TCoords.Y = (f32) TCoords.Y; + + dest.TCoords2.X = (f32) TCoords2.X; + dest.TCoords2.Y = (f32) TCoords2.Y; +} + + +void CQ3LevelMesh::copy ( S3DVertex2TCoords_64 * dest, const tBSPVertex * source, s32 vertexcolor ) const +{ + //dest->Pos.X = core::round ( source->vPosition[0] ); + //dest->Pos.Y = core::round ( source->vPosition[2] ); + //dest->Pos.Z = core::round ( source->vPosition[1] ); + dest->Pos.X = source->vPosition[0]; + dest->Pos.Y = source->vPosition[2]; + dest->Pos.Z = source->vPosition[1]; + + dest->Normal.X = source->vNormal[0]; + dest->Normal.Y = source->vNormal[2]; + dest->Normal.Z = source->vNormal[1]; + dest->Normal.normalize (); + + dest->TCoords.X = source->vTextureCoord[0]; + dest->TCoords.Y = source->vTextureCoord[1]; + dest->TCoords2.X = source->vLightmapCoord[0]; + dest->TCoords2.Y = source->vLightmapCoord[1]; + + if ( vertexcolor ) + { + u32 a = core::s32_min ( source->color[3] * quake3::defaultModulate, 255 ); + u32 r = core::s32_min ( source->color[0] * quake3::defaultModulate, 255 ); + u32 g = core::s32_min ( source->color[1] * quake3::defaultModulate, 255 ); + u32 b = core::s32_min ( source->color[2] * quake3::defaultModulate, 255 ); + + dest->Color.set (a * 1.f/255.f, r * 1.f/255.f, + g * 1.f/255.f, b * 1.f/255.f); + } + else + { + dest->Color.set ( 1.f, 1.f, 1.f, 1.f ); + } +} + + +inline void CQ3LevelMesh::copy ( video::S3DVertex2TCoords * dest, const tBSPVertex * source, s32 vertexcolor ) const +{ + dest->Pos.X = core::round_( source->vPosition[0] ); + dest->Pos.Y = core::round_( source->vPosition[2] ); + dest->Pos.Z = core::round_( source->vPosition[1] ); + + //dest->Pos.X = source->vPosition[0]; + //dest->Pos.Y = source->vPosition[2]; + //dest->Pos.Z = source->vPosition[1]; + + dest->Normal.X = source->vNormal[0]; + dest->Normal.Y = source->vNormal[2]; + dest->Normal.Z = source->vNormal[1]; + dest->Normal.normalize(); + + dest->TCoords.X = source->vTextureCoord[0]; + dest->TCoords.Y = source->vTextureCoord[1]; + dest->TCoords2.X = source->vLightmapCoord[0]; + dest->TCoords2.Y = source->vLightmapCoord[1]; + + if ( vertexcolor ) + { + u32 a = core::s32_min ( source->color[3] * quake3::defaultModulate, 255 ); + u32 r = core::s32_min ( source->color[0] * quake3::defaultModulate, 255 ); + u32 g = core::s32_min ( source->color[1] * quake3::defaultModulate, 255 ); + u32 b = core::s32_min ( source->color[2] * quake3::defaultModulate, 255 ); + + dest->Color.color = a << 24 | r << 16 | g << 8 | b; + } + else + { + dest->Color.color = 0xFFFFFFFF; + } +} + + +void CQ3LevelMesh::SBezier::tesselate ( s32 level ) +{ + //Calculate how many vertices across/down there are + s32 j, k; + + u32 idx = Patch->Vertices.size(); + + column[0].set_used ( level + 1 ); + column[1].set_used ( level + 1 ); + column[2].set_used ( level + 1 ); + + const f64 w = 0.0 + core::reciprocal ( (f32) level ); + + //Tesselate along the columns + for( j = 0; j <= level; ++j) + { + const f64 f = w * (f64) j; + + column[0][j] = control[0].getInterpolated_quadratic(control[3], control[6], f ); + column[1][j] = control[1].getInterpolated_quadratic(control[4], control[7], f ); + column[2][j] = control[2].getInterpolated_quadratic(control[5], control[8], f ); + } + + //Tesselate across the rows to get final vertices + video::S3DVertex2TCoords v; + S3DVertex2TCoords_64 f; + for( j = 0; j <= level; ++j) + { + for( k = 0; k <= level; ++k) + { + f = column[0][j].getInterpolated_quadratic( column[1][j], column[2][j], w * (f64) k ); + f.copyto ( v ); + Patch->Vertices.push_back ( v ); + } + } + + // connect + for( j = 0; j < level; ++j) + { + for( k = 0; k < level; ++k) + { + const s32 inx = idx + ( k * ( level + 1 ) ) + j; + + Patch->Indices.push_back ( inx + 0 ); + Patch->Indices.push_back ( inx + (level + 1 ) + 0 ); + Patch->Indices.push_back ( inx + (level + 1 ) + 1 ); + + Patch->Indices.push_back ( inx + 0 ); + Patch->Indices.push_back ( inx + (level + 1 ) + 1 ); + Patch->Indices.push_back ( inx + 1 ); + } + } +} + + +/*! + no subdivision +*/ +void CQ3LevelMesh::createCurvedSurface3(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor) +{ + tBSPFace * face = &Faces[faceIndex]; + u32 j,k,m; + + // number of control points across & up + const u32 controlWidth = face->size[0]; + const u32 controlHeight = face->size[1]; + + video::S3DVertex2TCoords v; + + m = meshBuffer->Vertices.size (); + for ( j = 0; j!= controlHeight * controlWidth; ++j ) + { + copy ( &v, &Vertices [ face->vertexIndex + j ], storevertexcolor ); + meshBuffer->Vertices.push_back ( v ); + } + + for ( j = 0; j!= controlHeight - 1; ++j ) + { + for ( k = 0; k!= controlWidth - 1; ++k ) + { + meshBuffer->Indices.push_back ( m + k + 0 ); + meshBuffer->Indices.push_back ( m + k + controlWidth + 0 ); + meshBuffer->Indices.push_back ( m + k + controlWidth + 1 ); + + meshBuffer->Indices.push_back ( m + k + 0 ); + meshBuffer->Indices.push_back ( m + k + controlWidth + 1 ); + meshBuffer->Indices.push_back ( m + k + 1 ); + } + m += controlWidth; + } +} + + +/*! +*/ +void CQ3LevelMesh::createCurvedSurface2(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor) +{ + tBSPFace * face = &Faces[faceIndex]; + u32 j,k; + + // number of control points across & up + const u32 controlWidth = face->size[0]; + const u32 controlHeight = face->size[1]; + + // number of biquadratic patches + const u32 biquadWidth = (controlWidth - 1)/2; + const u32 biquadHeight = (controlHeight -1)/2; + + // Create space for a temporary array of the patch's control points + core::array controlPoint; + controlPoint.set_used ( controlWidth * controlHeight ); + + for( j = 0; j < controlPoint.size(); ++j) + { + copy ( &controlPoint[j], &Vertices [ face->vertexIndex + j ], storevertexcolor ); + } + + // create a temporary patch + Bezier.Patch = new scene::SMeshBufferLightMap(); + + //Loop through the biquadratic patches + for( j = 0; j < biquadHeight; ++j) + { + for( k = 0; k < biquadWidth; ++k) + { + // set up this patch + const s32 inx = j*controlWidth*2 + k*2; + + // setup bezier control points for this patch + Bezier.control[0] = controlPoint[ inx + 0]; + Bezier.control[1] = controlPoint[ inx + 1]; + Bezier.control[2] = controlPoint[ inx + 2]; + Bezier.control[3] = controlPoint[ inx + controlWidth + 0 ]; + Bezier.control[4] = controlPoint[ inx + controlWidth + 1 ]; + Bezier.control[5] = controlPoint[ inx + controlWidth + 2 ]; + Bezier.control[6] = controlPoint[ inx + controlWidth * 2 + 0]; + Bezier.control[7] = controlPoint[ inx + controlWidth * 2 + 1]; + Bezier.control[8] = controlPoint[ inx + controlWidth * 2 + 2]; + + Bezier.tesselate ( patchTesselation ); + } + } + + // stitch together with existing geometry + // TODO: only border needs to be checked + const u32 bsize = Bezier.Patch->getVertexCount(); + const u32 msize = meshBuffer->getVertexCount(); +/* + for ( j = 0; j!= bsize; ++j ) + { + const core::vector3df &v = Bezier.Patch->Vertices[j].Pos; + + for ( k = 0; k!= msize; ++k ) + { + const core::vector3df &m = meshBuffer->Vertices[k].Pos; + + if ( !v.equals ( m, tolerance ) ) + continue; + + meshBuffer->Vertices[k].Pos = v; + //Bezier.Patch->Vertices[j].Pos = m; + } + } +*/ + + // add Patch to meshbuffer + for ( j = 0; j!= bsize; ++j ) + { + meshBuffer->Vertices.push_back ( Bezier.Patch->Vertices[j] ); + } + + // add indices to meshbuffer + for ( j = 0; j!= Bezier.Patch->getIndexCount(); ++j ) + { + meshBuffer->Indices.push_back ( msize + Bezier.Patch->Indices[j] ); + } + + delete Bezier.Patch; +} + + +void CQ3LevelMesh::createCurvedSurface(SMeshBufferLightMap* meshBuffer, s32 i) +{ + // this implementation for loading curved surfaces was + // sent in by Dean P. Macri. It was a little bit modified + // by me afterwards. + s32 idx; + s32 cpidx[9]; + + const tBSPVertex *v[9]; + video::S3DVertex2TCoords currentVertex[4]; + + for( s32 row=0; rowgetVertexCount(); + ct[0] = (1.0-t)*(1.0-t); + ct[1] = 2.0 * (1.0 - t) * t; + ct[2] = t * t; + nxt[0] = (1.0-t-tstep)*(1.0-t-tstep); + nxt[1] = 2.0 * (1.0 - t - tstep) * (t+tstep); + nxt[2] = (t+tstep) * (t+tstep); + + // Vert 1 + currentVertex[0].Color.set(255,255,255,255); + currentVertex[0].Pos.X = floorf( Blend( cs, ct, v, (char*)&v[0]->vPosition[0] - (char*)v[0])+ 0.5f); + currentVertex[0].Pos.Y = floorf( Blend( cs, ct, v, (char*)&v[0]->vPosition[2] - (char*)v[0])+ 0.5f); + currentVertex[0].Pos.Z = floorf( Blend( cs, ct, v, (char*)&v[0]->vPosition[1] - (char*)v[0])+ 0.5f); + currentVertex[0].Normal.X = Blend( cs, ct, v, (char*)&v[0]->vNormal[0] - (char*)v[0]); + currentVertex[0].Normal.Y = Blend( cs, ct, v, (char*)&v[0]->vNormal[2] - (char*)v[0]); + currentVertex[0].Normal.Z = Blend( cs, ct, v, (char*)&v[0]->vNormal[1] - (char*)v[0]); + currentVertex[0].TCoords.X = Blend( cs, ct, v, (char*)&v[0]->vTextureCoord[0] - (char*)v[0]); + currentVertex[0].TCoords.Y = Blend( cs, ct, v, (char*)&v[0]->vTextureCoord[1] - (char*)v[0]); + currentVertex[0].TCoords2.X = Blend( cs, ct, v, (char*)&v[0]->vLightmapCoord[0] - (char*)v[0]); + currentVertex[0].TCoords2.Y = Blend( cs, ct, v, (char*)&v[0]->vLightmapCoord[1] - (char*)v[0]); + // Vert 2 + currentVertex[1].Color.set(255,255,255,255); + currentVertex[1].Pos.X = floorf( Blend( cs, nxt, v, (char*)&v[0]->vPosition[0] - (char*)v[0])+ 0.5f); + currentVertex[1].Pos.Y = floorf( Blend( cs, nxt, v, (char*)&v[0]->vPosition[2] - (char*)v[0])+ 0.5f); + currentVertex[1].Pos.Z = floorf( Blend( cs, nxt, v, (char*)&v[0]->vPosition[1] - (char*)v[0])+ 0.5f); + currentVertex[1].Normal.X = Blend( cs, nxt, v, (char*)&v[0]->vNormal[0] - (char*)v[0]); + currentVertex[1].Normal.Y = Blend( cs, nxt, v, (char*)&v[0]->vNormal[2] - (char*)v[0]); + currentVertex[1].Normal.Z = Blend( cs, nxt, v, (char*)&v[0]->vNormal[1] - (char*)v[0]); + currentVertex[1].TCoords.X = Blend( cs, nxt, v, (char*)&v[0]->vTextureCoord[0] - (char*)v[0]); + currentVertex[1].TCoords.Y = Blend( cs, nxt, v, (char*)&v[0]->vTextureCoord[1] - (char*)v[0]); + currentVertex[1].TCoords2.X = Blend( cs, nxt, v, (char*)&v[0]->vLightmapCoord[0] - (char*)v[0]); + currentVertex[1].TCoords2.Y = Blend( cs, nxt, v, (char*)&v[0]->vLightmapCoord[1] - (char*)v[0]); + // Vert 3 + currentVertex[2].Color.set(255,255,255,255); + currentVertex[2].Pos.X = floorf( Blend( nxs, ct, v, (char*)&v[0]->vPosition[0] - (char*)v[0])+ 0.5f); + currentVertex[2].Pos.Y = floorf( Blend( nxs, ct, v, (char*)&v[0]->vPosition[2] - (char*)v[0])+ 0.5f); + currentVertex[2].Pos.Z = floorf( Blend( nxs, ct, v, (char*)&v[0]->vPosition[1] - (char*)v[0])+ 0.5f); + currentVertex[2].Normal.X = Blend( nxs, ct, v, (char*)&v[0]->vNormal[0] - (char*)v[0]); + currentVertex[2].Normal.Y = Blend( nxs, ct, v, (char*)&v[0]->vNormal[2] - (char*)v[0]); + currentVertex[2].Normal.Z = Blend( nxs, ct, v, (char*)&v[0]->vNormal[1] - (char*)v[0]); + currentVertex[2].TCoords.X = Blend( nxs, ct, v, (char*)&v[0]->vTextureCoord[0] - (char*)v[0]); + currentVertex[2].TCoords.Y = Blend( nxs, ct, v, (char*)&v[0]->vTextureCoord[1] - (char*)v[0]); + currentVertex[2].TCoords2.X = Blend( nxs, ct, v, (char*)&v[0]->vLightmapCoord[0] - (char*)v[0]); + currentVertex[2].TCoords2.Y = Blend( nxs, ct, v, (char*)&v[0]->vLightmapCoord[1] - (char*)v[0]); + // Vert 4 + currentVertex[3].Color.set(255,255,255,255); + currentVertex[3].Pos.X = floorf(Blend( nxs, nxt, v, (char*)&v[0]->vPosition[0] - (char*)v[0])+ 0.5f); + currentVertex[3].Pos.Y = floorf(Blend( nxs, nxt, v, (char*)&v[0]->vPosition[2] - (char*)v[0])+ 0.5f); + currentVertex[3].Pos.Z = floorf(Blend( nxs, nxt, v, (char*)&v[0]->vPosition[1] - (char*)v[0])+ 0.5f); + currentVertex[3].Normal.X = Blend( nxs, nxt, v, (char*)&v[0]->vNormal[0] - (char*)v[0]); + currentVertex[3].Normal.Y = Blend( nxs, nxt, v, (char*)&v[0]->vNormal[2] - (char*)v[0]); + currentVertex[3].Normal.Z = Blend( nxs, nxt, v, (char*)&v[0]->vNormal[1] - (char*)v[0]); + currentVertex[3].TCoords.X = Blend( nxs, nxt, v, (char*)&v[0]->vTextureCoord[0] - (char*)v[0]); + currentVertex[3].TCoords.Y = Blend( nxs, nxt, v, (char*)&v[0]->vTextureCoord[1] - (char*)v[0]); + currentVertex[3].TCoords2.X = Blend( nxs, nxt, v, (char*)&v[0]->vLightmapCoord[0] - (char*)v[0]); + currentVertex[3].TCoords2.Y = Blend( nxs, nxt, v, (char*)&v[0]->vLightmapCoord[1] - (char*)v[0]); + // Put the vertices in the mesh buffer + meshBuffer->Vertices.push_back(currentVertex[0]); + meshBuffer->Vertices.push_back(currentVertex[2]); + meshBuffer->Vertices.push_back(currentVertex[1]); + + meshBuffer->Vertices.push_back(currentVertex[1]); + meshBuffer->Vertices.push_back(currentVertex[2]); + meshBuffer->Vertices.push_back(currentVertex[3]); + + // add indexes + meshBuffer->Indices.push_back(idx); + meshBuffer->Indices.push_back(idx+1); + meshBuffer->Indices.push_back(idx+2); + // add indexes + meshBuffer->Indices.push_back(idx+3); + meshBuffer->Indices.push_back(idx+4); + meshBuffer->Indices.push_back(idx+5); + } + } + } + } +} + + +//! get's an interface to the entities +const quake3::tQ3EntityList & CQ3LevelMesh::getEntityList () +{ + Entity.sort(); + return Entity; +} + + +/*! +*/ +const quake3::SShader * CQ3LevelMesh::getShader ( u32 index ) const +{ + index &= 0xFFFF; + + if ( index < Shader.size () ) + { + return &Shader[index]; + } + + return 0; +} + + +//! loads the shader definition +// either from file ( we assume /scripts on fileNameIsValid == 0 ) +const quake3::SShader * CQ3LevelMesh::getShader ( const c8 * filename, s32 fileNameIsValid ) +{ + quake3::SShader search; + search.name = filename; + + s32 index; + + //! is Shader already in cache? + index = Shader.linear_search ( search ); + if ( index >= 0 ) + { + return &Shader[index]; + } + + core::stringc loadFile; + + if ( 0 == fileNameIsValid ) + { + // extract the shader name from the last path component in filename + // "scripts/[name].shader" + core::stringc cut ( filename ); + + s32 end = cut.findLast ( '/' ); + s32 start = cut.findLast ( '/', end - 1 ); + + loadFile = "scripts"; + loadFile.append ( cut.subString ( start, end - start ) ); + loadFile.append ( ".shader" ); + } + else + { + loadFile = filename; + } + + // already loaded the file ? + index = ShaderFile.binary_search ( loadFile ); + if ( index >= 0 ) + return 0; + + if ( !FileSystem->existFile ( loadFile.c_str () ) ) + return 0; + + io::IReadFile *file = FileSystem->createAndOpenFile ( loadFile.c_str () ); + if ( 0 == file ) + return 0; + + core::stringc message; + message = loadFile + " for " + core::stringc ( filename ); + os::Printer::log("Loaded shader", message.c_str(), ELL_INFORMATION); + + // add file to loaded files + ShaderFile.push_back ( loadFile ); + + // load script + core::array script; + const long len = file->getSize (); + + script.set_used ( len + 2 ); + script[ len + 1 ] = 0; + + file->seek( 0 ); + file->read ( script.pointer(), len ); + file->drop (); + + // start a parser instance + parser_parse ( script.pointer(), len, &CQ3LevelMesh::scriptcallback_shader ); + + // search again + index = Shader.linear_search ( search ); + if ( index >= 0 ) + return &Shader[index]; + + return 0; +} + + +//! adding default shaders +void CQ3LevelMesh::InitShader () +{ + ReleaseShader (); + + quake3::SShader element; + + quake3::SVarGroup group; + quake3::SVariable variable; + + variable.name = "noshader"; + group.Variable.push_back ( variable ); + + element.VarGroup = new quake3::SVarGroupList (); + element.VarGroup->VariableGroup.push_back ( group ); + element.name = element.VarGroup->VariableGroup[0].Variable[0].name.c_str (); + Shader.push_back ( element ); + + // load common named shader + getShader ( "scripts/common.shader", 1 ); +} + + +//!. script callback for shaders +//! i'm having troubles with the reference counting, during callback.. resorting.. +void CQ3LevelMesh::ReleaseShader () +{ + for ( u32 i = 0; i!= Shader.size(); ++i ) + { + Shader[i].VarGroup->drop (); + } + Shader.clear (); + ShaderFile.clear(); +} + +void CQ3LevelMesh::ReleaseEntity () +{ + for ( u32 i = 0; i!= Entity.size(); ++i ) + { + Entity[i].VarGroup->drop (); + } + Entity.clear (); + +} + + +// entity only has only one valid level.. and no assoziative name.. +void CQ3LevelMesh::scriptcallback_entity ( quake3::SVarGroupList *& grouplist ) +{ + quake3::SEntity element; + + if ( grouplist->VariableGroup.size () != 2 ) + return; + + + element.name = grouplist->VariableGroup[1].get ( "classname" ); + + grouplist->grab (); + element.VarGroup = grouplist; + element.id = Shader.size(); + + Entity.push_back ( element ); +} + + +//!. script callback for shaders +void CQ3LevelMesh::scriptcallback_shader ( quake3::SVarGroupList *& grouplist ) +{ + quake3::SShader element; + + // TODO: There might be something wrong with this fix, but it avoids a core dump... + if (grouplist->VariableGroup[0].Variable.size()==0) + return; + // end fix + + grouplist->grab (); + + element.VarGroup = grouplist; + element.name = element.VarGroup->VariableGroup[0].Variable[0].name.c_str (); + element.id = Shader.size(); + + Shader.push_back ( element ); +} + + +//! loads the textures +void CQ3LevelMesh::loadTextures() +{ + if (!Driver) + return; + + core::stringc s; + core::stringc extensions[2]; + extensions[0] = ".jpg"; + extensions[1] = ".tga"; + + // load textures + + core::array tex; + tex.set_used(NumTextures+1); + + tex[0] = 0; + + s32 t;// new ISO for scoping problem with some compilers + + for (t=1; t<(NumTextures+1); ++t) + { + tex[t] = 0; + + if ( !tex[t] ) + { + for (s32 e=0; e<2; ++e) + { + s = Textures[t-1].strName; + s.append(extensions[e]); + if (FileSystem->existFile(s.c_str())) + { + tex[t] = Driver->getTexture(s.c_str()); + break; + } + } + } + if (!tex[t]) + { + os::Printer::log("Q3: no texmap for texturename ", Textures[t-1].strName, ELL_WARNING); + } + } + + // load lightmaps. + core::array lig; + lig.set_used(NumLightMaps+1); + + lig[0] = 0; + c8 lightmapname[255]; + core::dimension2d lmapsize(128,128); + + //bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + //Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + video::IImage* lmapImg; + for (t=1; t<(NumLightMaps+1); ++t) + { + sprintf(lightmapname, "%s.lightmap.%d", LevelName.c_str(), t); + + // lightmap is a CTexture::R8G8B8 format + lmapImg = Driver->createImageFromData( + video::ECF_R8G8B8, + lmapsize, + LightMaps[t-1].imageBits, true, false ); + + lig[t] = Driver->addTexture ( lightmapname, lmapImg ); + lmapImg->drop (); + + } + //Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + + // attach textures to materials. + for (s32 l=0; lgetMeshBuffer(l*(NumTextures+1) + t); + b->Material.setTexture(1, lig[l]); + b->Material.setTexture(0, tex[t]); + + if (!b->Material.getTexture(1)) + b->Material.MaterialType = video::EMT_SOLID; + + if (!b->Material.getTexture(0)) + b->Material.MaterialType = video::EMT_SOLID; + } + } +} + +// delete all buffers without geometry in it. +void CQ3LevelMesh::cleanMeshes () +{ + // delete all buffers without geometry in it. + for ( u32 g = 0; g < quake3::E_Q3_MESH_SIZE; ++g ) + { + u32 i = 0; + bool texture0important = ( g == 0 ); + while(i < Mesh[g]->MeshBuffers.size()) + { + if (Mesh[g]->MeshBuffers[i]->getVertexCount() == 0 || + Mesh[g]->MeshBuffers[i]->getIndexCount() == 0 || + ( texture0important && Mesh[g]->MeshBuffers[i]->getMaterial().getTexture(0) == 0 ) + ) + { + // delete Meshbuffer + Mesh[g]->MeshBuffers[i]->drop(); + Mesh[g]->MeshBuffers.erase(i); + } + else + ++i; + } + } + +} + +// recalculate bounding boxes +void CQ3LevelMesh::calcBoundingBoxes () +{ + // create bounding box + for ( u32 g = 0; g != quake3::E_Q3_MESH_SIZE; ++g ) + { + for ( u32 j=0; j < Mesh[g]->MeshBuffers.size(); ++j) + { + ((SMeshBufferLightMap*)Mesh[g]->MeshBuffers[j])->recalculateBoundingBox(); + } + + Mesh[g]->recalculateBoundingBox(); + } + +} + +/* +//! loads a texture +video::ITexture* CQ3LevelMesh::loadTexture ( const tStringList &stringList ) +{ + static const char * extension[2] = + { + ".jpg", + ".tga" + }; + + core::stringc loadFile; + for ( u32 i = 0; i!= stringList.size (); ++i ) + { + for ( u32 g = 0; g != 2 ; ++g ) + { + cutFilenameExtension ( loadFile, stringList[i] ).append ( extension[g] ); + + if ( FileSystem->existFile ( loadFile.c_str() ) ) + { + video::ITexture* t = Driver->getTexture( loadFile.c_str() ); + if ( t ) + return t; + } + } + } + return 0; +} +*/ + +//! loads the textures +void CQ3LevelMesh::loadTextures2() +{ + if (!Driver) + return; + + s32 t; + + // load lightmaps. + Lightmap.set_used(NumLightMaps+1); + + c8 lightmapname[255]; + core::dimension2d lmapsize(128,128); + + video::IImage* lmapImg; + for ( t = 0; t < NumLightMaps ; ++t) + { + sprintf(lightmapname, "%s.lightmap.%d", LevelName.c_str(), t); + + // lightmap is a CTexture::R8G8B8 format + lmapImg = Driver->createImageFromData( + video::ECF_R8G8B8, + lmapsize, + LightMaps[t].imageBits, true, false ); + + Lightmap[t] = Driver->addTexture ( lightmapname, lmapImg ); + lmapImg->drop (); + + } + + // load textures + Tex.set_used( NumTextures+1 ); + + const quake3::SShader * shader; + + core::stringc list; + core::stringc check; + quake3::tTexArray textureArray; + + for ( t=0; t< NumTextures; ++t) + { + Tex[t].ShaderID = -1; + Tex[t].Texture = 0; + + list = ""; + + // get a shader ( if one exists ) + shader = getShader ( Textures[t].strName, 0 ); + if ( shader ) + { + Tex[t].ShaderID = shader->id; + + // if texture name == stage1 Texture map + const quake3::SVarGroup * group; + + group = shader->getGroup ( 2 ); + if ( group ) + { + if ( core::cutFilenameExtension ( check, group->get ( "map" ) ) == Textures[t].strName ) + { + list += check; + } + else + if ( check == "$lightmap" ) + { + // we check if lightmap is in stage 1 and texture in stage 2 + group = shader->getGroup ( 3 ); + if ( group ) + list += group->get ( "map" ); + } + } + } + else + { + // no shader, take it + list += Textures[t].strName; + } + + u32 pos = 0; + quake3::getTextures ( textureArray, list, pos, FileSystem, Driver ); + + Tex[t].Texture = textureArray[0]; + } +} + + +//! Returns an axis aligned bounding box of the mesh. +//! \return A bounding box of this mesh is returned. +const core::aabbox3d& CQ3LevelMesh::getBoundingBox() const +{ + return Mesh[0]->getBoundingBox(); +} + +void CQ3LevelMesh::setBoundingBox( const core::aabbox3df& box) +{ + Mesh[0]->setBoundingBox(box); //? +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CQ3LevelMesh::getMeshType() const +{ + return scene::EAMT_BSP; +} + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BSP_LOADER_ diff --git a/src/dep/src/irrlicht/CQ3LevelMesh.h b/src/dep/src/irrlicht/CQ3LevelMesh.h new file mode 100644 index 0000000..95ff959 --- /dev/null +++ b/src/dep/src/irrlicht/CQ3LevelMesh.h @@ -0,0 +1,443 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Q3_LEVEL_MESH_H_INCLUDED__ +#define __C_Q3_LEVEL_MESH_H_INCLUDED__ + +#include "IQ3LevelMesh.h" +#include "IReadFile.h" +#include "IFileSystem.h" +#include "SMesh.h" +#include "SMeshBufferLightMap.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "ISceneManager.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + class CQ3LevelMesh : public IQ3LevelMesh + { + public: + + //! constructor + CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr); + + //! destructor + virtual ~CQ3LevelMesh(); + + //! loads a level from a .bsp-File. Also tries to load all needed textures. Returns true if successful. + bool loadFile(io::IReadFile* file); + + //! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. + virtual u32 getFrameCount() const; + + //! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. + virtual IMesh* getMesh(s32 frameInMs, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1); + + virtual void releaseMesh ( s32 index ); + + //! Returns an axis aligned bounding box of the mesh. + //! \return A bounding box of this mesh is returned. + virtual const core::aabbox3d& getBoundingBox() const; + + virtual void setBoundingBox( const core::aabbox3df& box); + + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! loads the shader definition + virtual const quake3::SShader * getShader ( const c8 * filename, s32 fileNameIsValid ); + + //! returns a already loaded Shader + virtual const quake3::SShader * getShader ( u32 index ) const; + + + //! get's an interface to the entities + virtual const quake3::tQ3EntityList & getEntityList (); + + + + //Link to held meshes? ... + + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return 0; + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return 0; + } + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const + { + return 0; + } + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + return; + } + + + + + private: + + //! constructs a mesh from the quake 3 level file. + void constructMesh(); + + //! loads the textures + void loadTextures(); + + void constructMesh2(); + + void loadTextures2(); + + struct STexShader + { + video::ITexture* Texture; + s32 ShaderID; + }; + + core::array< STexShader > Tex; + core::array Lightmap; + + enum eLumps + { + kEntities = 0, // Stores player/object positions, etc... + kTextures, // Stores texture information + kPlanes, // Stores the splitting planes + kNodes, // Stores the BSP nodes + kLeafs, // Stores the leafs of the nodes + kLeafFaces, // Stores the leaf's indices into the faces + kLeafBrushes, // Stores the leaf's indices into the brushes + kModels, // Stores the info of world models + kBrushes, // Stores the brushes info (for collision) + kBrushSides, // Stores the brush surfaces info + kVertices, // Stores the level vertices + kMeshVerts, // Stores the model vertices offsets + kShaders, // Stores the shader files (blending, anims..) + kFaces, // Stores the faces for the level + kLightmaps, // Stores the lightmaps for the level + kLightVolumes, // Stores extra world lighting information + kVisData, // Stores PVS and cluster info (visibility) + kMaxLumps // A constant to store the number of lumps + }; + + struct tBSPLump + { + s32 offset; + s32 length; + }; + + struct tBSPHeader + { + s32 strID; // This should always be 'IBSP' + s32 version; // This should be 0x2e for Quake 3 files + }; + + struct tBSPVertex + { + f32 vPosition[3]; // (x, y, z) position. + f32 vTextureCoord[2]; // (u, v) texture coordinate + f32 vLightmapCoord[2]; // (u, v) lightmap coordinate + f32 vNormal[3]; // (x, y, z) normal vector + u8 color[4]; // RGBA color for the vertex + }; + + struct tBSPFace + { + s32 textureID; // The index into the texture array + s32 effect; // The index for the effects (or -1 = n/a) + s32 type; // 1=polygon, 2=patch, 3=mesh, 4=billboard + s32 vertexIndex; // The index into this face's first vertex + s32 numOfVerts; // The number of vertices for this face + s32 meshVertIndex; // The index into the first meshvertex + s32 numMeshVerts; // The number of mesh vertices + s32 lightmapID; // The texture index for the lightmap + s32 lMapCorner[2]; // The face's lightmap corner in the image + s32 lMapSize[2]; // The size of the lightmap section + f32 lMapPos[3]; // The 3D origin of lightmap. + f32 lMapBitsets[2][3]; // The 3D space for s and t unit vectors. + f32 vNormal[3]; // The face normal. + s32 size[2]; // The bezier patch dimensions. + }; + + struct tBSPTexture + { + c8 strName[64]; // The name of the texture w/o the extension + u32 flags; // The surface flags (unknown) + u32 contents; // The content flags (unknown) + }; + + struct tBSPLightmap + { + u8 imageBits[128][128][3]; // The RGB data in a 128x128 image + }; + + struct tBSPNode + { + s32 plane; // The index into the planes array + s32 front; // The child index for the front node + s32 back; // The child index for the back node + s32 mins[3]; // The bounding box min position. + s32 maxs[3]; // The bounding box max position. + }; + + struct tBSPLeaf + { + s32 cluster; // The visibility cluster + s32 area; // The area portal + s32 mins[3]; // The bounding box min position + s32 maxs[3]; // The bounding box max position + s32 leafface; // The first index into the face array + s32 numOfLeafFaces; // The number of faces for this leaf + s32 leafBrush; // The first index for into the brushes + s32 numOfLeafBrushes; // The number of brushes for this leaf + }; + + struct tBSPPlane + { + f32 vNormal[3]; // Plane normal. + f32 d; // The plane distance from origin + }; + + struct tBSPVisData + { + s32 numOfClusters; // The number of clusters + s32 bytesPerCluster; // Bytes (8 bits) in the cluster's bitset + c8 *pBitsets; // Array of bytes holding the cluster vis. + }; + + struct tBSPBrush + { + s32 brushSide; // The starting brush side for the brush + s32 numOfBrushSides; // Number of brush sides for the brush + s32 textureID; // The texture index for the brush + }; + + struct tBSPBrushSide + { + s32 plane; // The plane index + s32 textureID; // The texture index + }; + + struct tBSPModel + { + f32 min[3]; // The min position for the bounding box + f32 max[3]; // The max position for the bounding box. + s32 faceIndex; // The first face index in the model + s32 numOfFaces; // The number of faces in the model + s32 brushIndex; // The first brush index in the model + s32 numOfBrushes; // The number brushes for the model + }; + + struct tBSPShader + { + c8 strName[64]; // The name of the shader file + s32 brushIndex; // The brush index for this shader + s32 unknown; // This is 99% of the time 5 + }; + + struct tBSPLights + { + u8 ambient[3]; // This is the ambient color in RGB + u8 directional[3]; // This is the directional color in RGB + u8 direction[2]; // The direction of the light: [phi,theta] + }; + + void loadTextures (tBSPLump* l, io::IReadFile* file); // Load the textures + void loadLightmaps (tBSPLump* l, io::IReadFile* file); // Load the lightmaps + void loadVerts (tBSPLump* l, io::IReadFile* file); // Load the vertices + void loadFaces (tBSPLump* l, io::IReadFile* file); // Load the faces + void loadPlanes (tBSPLump* l, io::IReadFile* file); // Load the Planes of the BSP + void loadNodes (tBSPLump* l, io::IReadFile* file); // load the Nodes of the BSP + void loadLeafs (tBSPLump* l, io::IReadFile* file); // load the Leafs of the BSP + void loadLeafFaces (tBSPLump* l, io::IReadFile* file); // load the Faces of the Leafs of the BSP + void loadVisData (tBSPLump* l, io::IReadFile* file); // load the visibility data of the clusters + void loadEntities (tBSPLump* l, io::IReadFile* file); // load the entities + void loadModels (tBSPLump* l, io::IReadFile* file); // load the models + void loadMeshVerts (tBSPLump* l, io::IReadFile* file); // load the mesh vertices + void loadBrushes (tBSPLump* l, io::IReadFile* file); // load the brushes of the BSP + void loadBrushSides (tBSPLump* l, io::IReadFile* file); // load the brushsides of the BSP + void loadLeafBrushes(tBSPLump* l, io::IReadFile* file); // load the brushes of the leaf + void loadShaders (tBSPLump* l, io::IReadFile* file); // load the shaders + + // second parameter i is the zero based index of the current face. + void createCurvedSurface(SMeshBufferLightMap* meshBuffer, s32 i); + + //bi-quadratic bezier patches + void createCurvedSurface2 ( SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor + ); + + void createCurvedSurface3 ( SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor + ); + + f32 Blend( const f64 s[3], const f64 t[3], const tBSPVertex *v[9], int offset); + + struct S3DVertex2TCoords_64 + { + core::vector3d Pos; + core::vector3d Normal; + video::SColorf Color; + core::vector2d TCoords; + core::vector2d TCoords2; + + void copyto ( video::S3DVertex2TCoords &dest ) const; + + S3DVertex2TCoords_64() {} + S3DVertex2TCoords_64(const core::vector3d& pos, const core::vector3d& normal, const video::SColorf& color, + const core::vector2d& tcoords, const core::vector2d& tcoords2) + : Pos(pos), Normal(normal), Color(color), TCoords(tcoords), TCoords2(tcoords2) {} + + S3DVertex2TCoords_64 getInterpolated_quadratic(const S3DVertex2TCoords_64& v2, const S3DVertex2TCoords_64& v3, const f64 d) const + { + return S3DVertex2TCoords_64 ( + Pos.getInterpolated_quadratic ( v2.Pos, v3.Pos, d ), + Normal.getInterpolated_quadratic ( v2.Normal, v3.Normal, d ), + Color.getInterpolated_quadratic ( v2.Color, v3.Color, (f32) d ), + TCoords.getInterpolated_quadratic ( v2.TCoords, v3.TCoords, d ), + TCoords2.getInterpolated_quadratic ( v2.TCoords2, v3.TCoords2, d ) + ); + } + }; + + inline void copy ( video::S3DVertex2TCoords * dest, const tBSPVertex * source, s32 vertexcolor ) const; + void copy ( S3DVertex2TCoords_64 * dest, const tBSPVertex * source, s32 vertexcolor ) const; + + + struct SBezier + { + SMeshBufferLightMap *Patch; + S3DVertex2TCoords_64 control[9]; + + void tesselate(s32 level); + + private: + s32 Level; + + core::array column[3]; + + }; + SBezier Bezier; + + s32 PatchTesselation; + + tBSPLump Lumps[kMaxLumps]; + + tBSPTexture* Textures; + s32 NumTextures; + + tBSPLightmap* LightMaps; + s32 NumLightMaps; + + tBSPVertex* Vertices; + s32 NumVertices; + + tBSPFace* Faces; + s32 NumFaces; + + tBSPPlane* Planes; + s32 NumPlanes; + + tBSPNode* Nodes; + s32 NumNodes; + + tBSPLeaf* Leafs; + s32 NumLeafs; + + s32 *LeafFaces; + s32 NumLeafFaces; + + s32 *MeshVerts; // The vertex offsets for a mesh + s32 NumMeshVerts; + + tBSPBrush* Brushes; + s32 NumBrushes; + + scene::SMesh* Mesh[quake3::E_Q3_MESH_SIZE]; + video::IVideoDriver* Driver; + core::stringc LevelName; + io::IFileSystem* FileSystem; // needs because there are no file extenstions stored in .bsp files. + + // Additional content + scene::ISceneManager* SceneManager; + enum eToken + { + Q3_TOKEN_UNRESOLVED = 0, + Q3_TOKEN_EOF = 1, + Q3_TOKEN_START_LIST, + Q3_TOKEN_END_LIST, + Q3_TOKEN_ENTITY, + Q3_TOKEN_TOKEN, + Q3_TOKEN_EOL, + Q3_TOKEN_COMMENT, + Q3_TOKEN_MATH_DIVIDE, + Q3_TOKEN_MATH_ADD, + Q3_TOKEN_MATH_MULTIPY + }; + struct SQ3Parser + { + const c8 *source; + u32 sourcesize; + u32 index; + core::stringc token; + u32 tokenresult; + }; + SQ3Parser Parser; + + + typedef void ( CQ3LevelMesh::*tParserCallback ) ( quake3::SVarGroupList *& groupList ); + void parser_parse ( const void * data, u32 size, tParserCallback callback ); + void parser_nextToken (); + + void dumpVarGroup ( const quake3::SVarGroup * group, s32 stack ) const; + + void scriptcallback_entity ( quake3::SVarGroupList *& grouplist ); + quake3::tQ3EntityList Entity; + + void scriptcallback_shader ( quake3::SVarGroupList *& grouplist ); + core::array < quake3::SShader > Shader; + quake3::tStringList ShaderFile; + void InitShader (); + void ReleaseShader (); + void ReleaseEntity (); + + + s32 setShaderMaterial ( video::SMaterial & material, const tBSPFace * face ) const; + + struct SToBuffer + { + s32 takeVertexColor; + u32 index; + }; + + void cleanMeshes (); + void calcBoundingBoxes (); + + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CQuake3ShaderSceneNode.cpp b/src/dep/src/irrlicht/CQuake3ShaderSceneNode.cpp new file mode 100644 index 0000000..3126a9f --- /dev/null +++ b/src/dep/src/irrlicht/CQuake3ShaderSceneNode.cpp @@ -0,0 +1,704 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CQuake3ShaderSceneNode.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" + +namespace irr +{ +namespace scene +{ + + +CQuake3ShaderSceneNode::CQuake3ShaderSceneNode( + scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id, + io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer, + const quake3::SShader * shader) + : scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f ) +{ + #ifdef _DEBUG + core::stringc dName = "CQuake3ShaderSceneNode "; + dName += Shader->name; + + setDebugName( dName.c_str() ); + #endif + + // name the Scene Node + this->Name = Shader->name; + + // clone meshbuffer to modifiable buffer + cloneBuffer ( static_cast< scene::SMeshBufferLightMap *> ( buffer ) ); + + // load all Textures in all stages + loadTextures ( fileSystem ); +} + +/* +*/ +CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode () +{ +} + +/* + create single copies +*/ +void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer ) +{ + Original.Material = buffer->Material; + MeshBuffer.Material = buffer->Material; + + Original.Indices = buffer->Indices; + MeshBuffer.Indices = buffer->Indices; + + const u32 vsize = buffer->Vertices.size (); + + Original.Vertices.set_used ( vsize ); + MeshBuffer.Vertices.set_used ( vsize ); + for ( u32 i = 0; i!= vsize; ++i ) + { + const video::S3DVertex2TCoords * src = &buffer->Vertices[i]; + Original.Vertices[i] = *src; + + video::S3DVertex * d = &MeshBuffer.Vertices[i]; + + d->Pos = src->Pos; + d->Color = 0xFFFFFFFF; //src->Color; + d->Normal = src->Normal; + d->TCoords = src->TCoords; + } + + MeshBuffer.recalculateBoundingBox (); + // used for sorting + MeshBuffer.Material.setTexture(0, (video::ITexture*) Shader); +} + + + +/* + load the textures for all stages +*/ +void CQuake3ShaderSceneNode::loadTextures ( io::IFileSystem * fileSystem ) +{ + const quake3::SVarGroup *group; + u32 i; + + // clear all stages and prefill empty + Q3Texture.clear (); + for ( i = 0; i != Shader->VarGroup->VariableGroup.size (); ++i ) + { + Q3Texture.push_back ( SQ3Texture() ); + } + + u32 pos; + + // get texture map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size (); ++i ) + { + group = Shader->getGroup ( i ); + + const core::stringc &mapname = group->get ( "map" ); + if ( 0 == mapname.size () ) + continue; + + // our lightmap is passed in material.Texture[2] + if ( mapname == "$lightmap" ) + { + Q3Texture [i].Texture.push_back ( Original.getMaterial().getTexture(1) ); + } + else + { + pos = 0; + quake3::getTextures ( Q3Texture [i].Texture, mapname, pos, fileSystem, SceneManager->getVideoDriver() ); + } + } + + // get anim map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size (); ++i ) + { + if ( Q3Texture [i].Texture.size() ) + continue; + + group = Shader->getGroup ( i ); + + const core::stringc &animmap = group->get ( "animmap" ); + if ( 0 == animmap.size () ) + continue; + + // first parameter is frequency + pos = 0; + Q3Texture [i].TextureFrequency = core::max_ ( 0.0001f, quake3::getAsFloat ( animmap, pos ) ); + + quake3::getTextures ( Q3Texture [i].Texture, animmap, pos,fileSystem, SceneManager->getVideoDriver() ); + } + + // get clamp map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size (); ++i ) + { + if ( Q3Texture [i].Texture.size() ) + continue; + + group = Shader->getGroup ( i ); + + const core::stringc &clampmap = group->get ( "clampmap" ); + if ( 0 == clampmap.size () ) + continue; + + Q3Texture [i].TextureAddressMode = video::ETC_CLAMP; + pos = 0; + quake3::getTextures ( Q3Texture [i].Texture, clampmap, pos,fileSystem, SceneManager->getVideoDriver() ); + } +} + +/* + Register each texture stage, if first is visible +*/ +void CQuake3ShaderSceneNode::OnRegisterSceneNode() +{ + PassedCulling = 0; + StageCall = 0; + if ( !IsVisible) + return; + + u32 first = 1; + for ( u32 i = 1; i < Q3Texture.size(); ++i ) + { + if ( 0 == Q3Texture [ i ].Texture.size() && i >= 2 ) + continue; + + scene::E_SCENE_NODE_RENDER_PASS time = (scene::E_SCENE_NODE_RENDER_PASS) ( scene::ESNRP_SHADER_0 + i ); + if ( first ) + { + setAutomaticCulling ( scene::EAC_BOX ); + PassedCulling = SceneManager->registerNodeForRendering(this, time ); + setAutomaticCulling ( scene::EAC_OFF ); + first = 0; + } + else + if ( PassedCulling ) + { + SceneManager->registerNodeForRendering(this, time ); + } + } +} + +/* + render in multipass technique +*/ +void CQuake3ShaderSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + const u32 stage = SceneManager->getSceneNodeRenderPass() - scene::ESNRP_SHADER_0; + + video::SMaterial material; + + const quake3::SVarGroup *group; + + // generic stage + group = Shader->getGroup ( 1 ); + material.BackfaceCulling = quake3::getBackfaceCulling ( group->get ( "cull" ) ); + + // advance current stage + core::matrix4 texture; + animate ( stage, texture ); + + // stage 1 finished, no drawing stage ( vertex transform only ) + if ( stage == 1 ) + return; + + // current stage + group = Shader->getGroup ( stage ); + + + SQ3Texture &q = Q3Texture [ stage]; + + material.Lighting = false; + material.setTexture(0, q.Texture [ q.TextureIndex ]); + material.setTexture(1, 0); + material.ZBuffer = quake3::getDepthFunction ( group->get ( "depthfunc" ) ); + material.ZWriteEnable = (0 == StageCall ); + material.NormalizeNormals = false; + + quake3::SBlendFunc blendfunc; + quake3::getBlendFunc ( group->get ( "blendfunc" ), blendfunc ); + quake3::getBlendFunc ( group->get ( "alphafunc" ), blendfunc ); + + material.MaterialType = blendfunc.type; + material.MaterialTypeParam = blendfunc.param; + +/* + if ( textureTransform ) + { + transformtex ( texture, q.TextureAddressMode ); + } +*/ + material.TextureLayer[0].TextureWrap = q.TextureAddressMode; + material.TextureLayer[1].TextureWrap = material.TextureLayer[0].TextureWrap; + driver->setTransform ( video::ETS_TEXTURE_0, texture ); + + driver->setMaterial( material ); + + if ( 0 == StageCall ) + { + driver->setTransform(video::ETS_WORLD, core::matrix4() ); + } + + driver->drawMeshBuffer( &MeshBuffer ); + + StageCall += 1; +} + + +/*! +*/ +void CQuake3ShaderSceneNode::vertextransform_wave ( f32 dt, quake3::SModifierFunction &function ) +{ + function.wave = core::reciprocal ( function.wave ); + + const f32 phase = function.phase; + + const u32 vsize = MeshBuffer.Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original.Vertices[i]; + video::S3DVertex &dst = MeshBuffer.Vertices[i]; + + f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave; + function.phase = phase + wavephase; + + const f32 f = function.evaluate ( dt ); + + dst.Pos.X = src.Pos.X + f * src.Normal.X; + dst.Pos.Y = src.Pos.Y + f * src.Normal.Y; + dst.Pos.Z = src.Pos.Z + f * src.Normal.Z; + } +} + +/*! +*/ +void CQuake3ShaderSceneNode::vertextransform_bulge ( f32 dt, quake3::SModifierFunction &function ) +{ + function.func = 0; + function.wave = core::reciprocal ( function.bulgewidth ); + + dt *= function.bulgespeed * 0.1f; + const f32 phase = function.phase; + + const u32 vsize = MeshBuffer.Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original.Vertices[i]; + video::S3DVertex &dst = MeshBuffer.Vertices[i]; + + f32 wavephase = (Original.Vertices[i].TCoords.X ) * function.wave; + function.phase = phase + wavephase; + + const f32 f = function.evaluate ( dt ); + + dst.Pos.X = src.Pos.X + f * src.Normal.X; + dst.Pos.Y = src.Pos.Y + f * src.Normal.Y; + dst.Pos.Z = src.Pos.Z + f * src.Normal.Z; + } +} + +/*! +*/ +void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModifierFunction &function ) +{ + const core::matrix4 &m = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ]; + const core::vector3df view ( -m[2], -m[6] , -m[10] ); + + const u32 vsize = MeshBuffer.Vertices.size(); + + core::aabbox3df box; + u32 g; + + for ( u32 i = 0; i < vsize; i += 4 ) + { + // in pairs of 4 + box.reset ( Original.Vertices[i].Pos ); + for ( g = 1; g != 4; ++g ) + { + box.addInternalPoint ( Original.Vertices[i + g].Pos ); + } + + core::vector3df c = box.getCenter (); + f32 sh = 0.5f * ( box.MaxEdge.Z - box.MinEdge.Z ); + f32 sv = 0.5f * ( box.MaxEdge.Y - box.MinEdge.Y ); + + const core::vector3df h ( m[0] * sh, m[4] * sh, m[8] * sh ); + const core::vector3df v ( m[1] * sv, m[5] * sv, m[9] * sv ); + + MeshBuffer.Vertices[ i + 0 ].Pos = c + h + v; + MeshBuffer.Vertices[ i + 1 ].Pos = c - h - v; + MeshBuffer.Vertices[ i + 2 ].Pos = c + h - v; + MeshBuffer.Vertices[ i + 3 ].Pos = c - h + v; + + MeshBuffer.Vertices[ i + 0 ].Normal = view; + MeshBuffer.Vertices[ i + 1 ].Normal = view; + MeshBuffer.Vertices[ i + 2 ].Normal = view; + MeshBuffer.Vertices[ i + 3 ].Normal = view; + } +} + +/* + Generate Vertex Color +*/ +void CQuake3ShaderSceneNode::rgbgen ( f32 dt, quake3::SModifierFunction &function ) +{ + u32 i; + const u32 vsize = MeshBuffer.Vertices.size(); + + switch ( function.masterfunc1 ) + { + case 6: + //identity + for ( i = 0; i != vsize; ++i ) + MeshBuffer.Vertices[i].Color = 0xFFFFFFFF; + break; + case 7: + // vertex + for ( i = 0; i != vsize; ++i ) + MeshBuffer.Vertices[i].Color = Original.Vertices[i].Color; + break; + case 5: + { + // wave + f32 f = function.evaluate ( dt ) * 255.f; + s32 value = core::clamp ( core::floor32 ( f ), 0, 255 ); + value |= value << 8; + value |= value << 16; + + for ( i = 0; i != vsize; ++i ) + MeshBuffer.Vertices[i].Color = value; + } break; + } +} + +/* + Generate Texture Coordinates +*/ +u32 CQuake3ShaderSceneNode::tcgen ( f32 dt, quake3::SModifierFunction &function, core::matrix4 &texture ) +{ + u32 ret = 0; + u32 i; + const u32 vsize = MeshBuffer.Vertices.size(); + + switch ( function.tcgen ) + { + case 8: + // tcgen texture + for ( i = 0; i != vsize; ++i ) + MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords; + break; + case 9: + // tcgen lightmap + for ( i = 0; i != vsize; ++i ) + MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords2; + break; + case 10: + { + // tcgen environment ( D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR ) + + // using eye linear, sphere map may be cooler;-) + // modelmatrix is identity + const core::matrix4 &view = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ]; + const core::matrix4 &viewinverse = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ SViewFrustum::ETS_VIEW_MODEL_INVERSE_3 ]; + + // eyePlane + core::vector3df eyePlaneS; + core::vector3df eyePlaneT; + + viewinverse.transformVect ( eyePlaneS, core::vector3df ( 1.f, 0.f, 0.f ) ); + viewinverse.transformVect ( eyePlaneT, core::vector3df ( 0.f, 1.f, 0.f ) ); + + eyePlaneS.normalize (); + eyePlaneT.normalize (); + + core::vector3df v; + for ( i = 0; i != vsize; ++i ) + { + // vertex in eye space + view.transformVect ( v, Original.Vertices[i].Pos ); + v.normalize(); + + MeshBuffer.Vertices[i].TCoords.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f; + MeshBuffer.Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f ); + } + + ret = 0; + + } break; + } + + return ret; +} + + + +/* + Transform Texture Coordinates +*/ +void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode ) +{ + u32 i; + const u32 vsize = MeshBuffer.Vertices.size(); + + f32 tx1; + f32 ty1; + + if ( addressMode ) + { + for ( i = 0; i != vsize; ++i ) + { + core::vector2df &tx = MeshBuffer.Vertices[i].TCoords; + + tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; + ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; + + tx.X = tx1; + tx.Y = ty1; + } + } + else + { + + for ( i = 0; i != vsize; ++i ) + { + core::vector2df &tx = MeshBuffer.Vertices[i].TCoords; + + tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; + ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; + + tx.X = tx1 <= 0.f ? 0.f : tx1 >= 1.f ? 1.f : tx1; + tx.Y = ty1 <= 0.f ? 0.f : ty1 >= 1.f ? 1.f : ty1; + + //tx.X = core::clamp ( tx1, 0.f, 1.f ); + //tx.Y = core::clamp ( ty1, 0.f, 1.f ); + } + } +} + + + + +/* + Texture & Vertex Transform Animator + + Return a Texture Transformation for this stage + Vertex transformation are called if found + +*/ +u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture ) +{ + const f32 dt = TimeAbs; + + const quake3::SVarGroup *group = Shader->getGroup ( stage ); + + // select current texture + if ( Q3Texture [ stage ].TextureFrequency != 0.f ) + { + s32 v = core::floor32 ( dt * Q3Texture [ stage ].TextureFrequency ); + Q3Texture [ stage ].TextureIndex = v % Q3Texture [ stage ].Texture.size(); + } + + + core::matrix4 texturem; + core::matrix4 m2; + quake3::SModifierFunction function; + + f32 f0; + f32 f1; + u32 textureMatrixFound = 0; + + // walk group for all modifiers + for ( u32 g = 0; g != group->Variable.size (); ++g ) + { + const quake3::SVariable &v = group->Variable[g]; + + // get the modifier + static const c8 * modifierList[] = + { + "tcmod","deformvertexes","rgbgen","tcgen","map" + }; + + u32 pos = 0; + function.masterfunc0 = quake3::isEqual ( v.name, pos, modifierList, 5 ); + + if ( -2 == function.masterfunc0 ) + continue; + + switch ( function.masterfunc0 ) + { + //tcmod + case 0: + if ( 0 == textureMatrixFound ) + { + texturem.makeIdentity (); + textureMatrixFound = 1; + } + m2.makeIdentity (); + break; + } + + // get the modifier function + static const c8 * funclist[] = + { + "scroll","scale","rotate","stretch","turb", + "wave","identity","vertex", + "texture","lightmap","environment","$lightmap", + "bulge","autosprite","autosprite2" + }; + + pos = 0; + function.masterfunc1 = quake3::isEqual ( v.content, pos, funclist, 14 ); + + switch ( function.masterfunc1 ) + { + case 0: + // scroll + f0 = quake3::getAsFloat ( v.content, pos ) * dt; + f1 = quake3::getAsFloat ( v.content, pos ) * dt; + m2.setTextureTranslate ( f0, f1 ); + break; + case 1: + // scale + f0 = quake3::getAsFloat ( v.content, pos ); + f1 = quake3::getAsFloat ( v.content, pos ); + m2.setTextureScale ( f0, f1 ); + break; + case 2: + //rotate + m2.setTextureRotationCenter ( quake3::getAsFloat ( v.content, pos ) * core::DEGTORAD * dt ); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + { + // turb == sin, default == sin + function.func = 0; + + if ( function.masterfunc1 == 5 && function.masterfunc0 == 1) + { + // deformvertexes, wave + function.wave = quake3::getAsFloat ( v.content, pos ); + } + + if ( function.masterfunc1 == 3 || + function.masterfunc1 == 4 || + function.masterfunc1 == 5 + ) + { + // stretch, wave, tub + quake3::getModifierFunc ( function, v.content, pos ); + } + + switch ( function.masterfunc1 ) + { + case 3: + // stretch + f0 = core::reciprocal ( function.evaluate ( dt ) ); + m2.setTextureScaleCenter ( f0, f0 ); + break; + case 4: + // turb + f0 = function.evaluate ( dt ); + function.freq *= 2.f; + f1 = function.evaluate ( dt ); + m2.setTextureTranslate ( f1, f0 ); + break; + case 5: + if ( function.masterfunc0 == 1 ) + vertextransform_wave ( dt, function ); + else + rgbgen ( dt, function ); + break; + case 6: + case 7: + rgbgen ( dt, function ); + break; + } + + } break; + case 8: + case 9: + case 10: + // "texture","lightmap","environment" + function.tcgen = function.masterfunc1; + break; + case 11: + // map == lightmap, tcgen == lightmap + function.tcgen = 9; + break; + case 12: + // deformvertexes bulge + function.bulgewidth = quake3::getAsFloat ( v.content, pos ); + function.bulgeheight = quake3::getAsFloat ( v.content, pos ); + function.bulgespeed = quake3::getAsFloat ( v.content, pos ); + + vertextransform_bulge ( dt, function ); + break; + + case 13: + case 14: + // deformvertexes autosprite + vertextransform_autosprite ( dt, function); + break; + + } // func + + switch ( function.masterfunc0 ) + { + case 0: + texturem *= m2; + break; + } + + } // group + + // texture coordinate modifier + textureMatrixFound += tcgen ( dt, function, texturem ); + + if ( textureMatrixFound ) + { + texturem.getTransposed ( texture ); + } + + return textureMatrixFound; +} + + +void CQuake3ShaderSceneNode::OnAnimate(u32 timeMs) +{ + TimeAbs = f32( timeMs ) * ( 1.f/1000.f); +} + +const core::aabbox3d& CQuake3ShaderSceneNode::getBoundingBox() const +{ + return MeshBuffer.getBoundingBox (); +} + + +u32 CQuake3ShaderSceneNode::getMaterialCount() const +{ + return Q3Texture.size(); +} + +video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i) +{ + video::SMaterial& m = MeshBuffer.getMaterial(); + m.setTexture(0, 0); + if ( Q3Texture [ i ].TextureIndex ) + m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]); + return m; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CQuake3ShaderSceneNode.h b/src/dep/src/irrlicht/CQuake3ShaderSceneNode.h new file mode 100644 index 0000000..3cb8221 --- /dev/null +++ b/src/dep/src/irrlicht/CQuake3ShaderSceneNode.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_QUAKE3_SCENE_NODE_H_INCLUDED__ +#define __C_QUAKE3_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IQ3Shader.h" +#include "IFileSystem.h" +#include "SMeshBuffer.h" +#include "SMeshBufferLightMap.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a quake3 shader. +class CQuake3ShaderSceneNode : public scene::ISceneNode +{ +public: + + CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr,s32 id, + io::IFileSystem *fileSystem,IMeshBuffer *buffer, + const quake3::SShader * shader + ); + + virtual ~CQuake3ShaderSceneNode (); + + virtual void OnRegisterSceneNode(); + virtual void render(); + virtual void OnAnimate(u32 timeMs); + virtual const core::aabbox3d& getBoundingBox() const; + + virtual u32 getMaterialCount() const; + virtual video::SMaterial& getMaterial(u32 i); + +private: + SMeshBuffer MeshBuffer; + SMeshBufferLightMap Original; + const quake3::SShader * Shader; + + struct SQ3Texture + { + SQ3Texture () : + TextureIndex ( 0 ), + TextureFrequency(0.f), + TextureAddressMode( video::ETC_REPEAT ) {} + + quake3::tTexArray Texture; + + u32 TextureIndex; + f32 TextureFrequency; + video::E_TEXTURE_CLAMP TextureAddressMode; // Wrapping/Clamping + }; + + core::array< SQ3Texture > Q3Texture; + + void loadTextures ( io::IFileSystem * fileSystem ); + void cloneBuffer ( scene::SMeshBufferLightMap * buffer ); + + void vertextransform_wave ( f32 dt, quake3::SModifierFunction &function ); + void vertextransform_bulge( f32 dt, quake3::SModifierFunction &function ); + void vertextransform_autosprite( f32 dt, quake3::SModifierFunction &function ); + + void rgbgen ( f32 dt, quake3::SModifierFunction &function ); + u32 tcgen ( f32 dt, quake3::SModifierFunction &function, core::matrix4 &texture ); + + void transformtex ( const core::matrix4 &m, const u32 clamp ); + + f32 TimeAbs; + u32 animate( u32 stage, core::matrix4 &texture ); + + + s32 PassedCulling; + s32 StageCall; + +}; + + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CReadFile.cpp b/src/dep/src/irrlicht/CReadFile.cpp new file mode 100644 index 0000000..42452d4 --- /dev/null +++ b/src/dep/src/irrlicht/CReadFile.cpp @@ -0,0 +1,117 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CReadFile.h" + +namespace irr +{ +namespace io +{ + + +CReadFile::CReadFile(const c8* fileName) +: File(0), FileSize(0) +{ + #ifdef _DEBUG + setDebugName("CReadFile"); + #endif + + Filename = fileName; + openFile(); +} + + + +CReadFile::~CReadFile() +{ + if (File) + fclose(File); +} + + + +//! returns how much was read +s32 CReadFile::read(void* buffer, u32 sizeToRead) +{ + if (!isOpen()) + return 0; + + return fread(buffer, 1, sizeToRead, File); +} + + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CReadFile::seek(long finalPos, bool relativeMovement) +{ + if (!isOpen()) + return false; + + return fseek(File, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET) == 0; +} + + + +//! returns size of file +long CReadFile::getSize() const +{ + return FileSize; +} + + + +//! returns where in the file we are. +long CReadFile::getPos() const +{ + return ftell(File); +} + + + +//! opens the file +void CReadFile::openFile() +{ + if (Filename.size() == 0) // bugfix posted by rt + { + File = 0; + return; + } + + File = fopen(Filename.c_str(), "rb"); + + if (File) + { + // get FileSize + + fseek(File, 0, SEEK_END); + FileSize = getPos(); + fseek(File, 0, SEEK_SET); + } +} + + +//! returns name of file +const c8* CReadFile::getFileName() const +{ + return Filename.c_str(); +} + + + +IReadFile* createReadFile(const c8* fileName) +{ + CReadFile* file = new CReadFile(fileName); + if (file->isOpen()) + return file; + + file->drop(); + return 0; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CReadFile.h b/src/dep/src/irrlicht/CReadFile.h new file mode 100644 index 0000000..dc0b0a9 --- /dev/null +++ b/src/dep/src/irrlicht/CReadFile.h @@ -0,0 +1,67 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_READ_FILE_H_INCLUDED__ +#define __C_READ_FILE_H_INCLUDED__ + +#include +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for reading a real file from disk. + */ + class CReadFile : public IReadFile + { + public: + + CReadFile(const wchar_t* fileName); + CReadFile(const c8* fileName); + + virtual ~CReadFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! changes position in file, returns true if successful + //! if relativeMovement==true, the pos is changed relative to current pos, + //! otherwise from begin of file + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns if file is open + virtual bool isOpen() const + { + return File != 0; + } + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const c8* getFileName() const; + + private: + + //! opens the file + void openFile(); + + core::stringc Filename; + FILE* File; + long FileSize; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSTLMeshFileLoader.cpp b/src/dep/src/irrlicht/CSTLMeshFileLoader.cpp new file mode 100644 index 0000000..783df56 --- /dev/null +++ b/src/dep/src/irrlicht/CSTLMeshFileLoader.cpp @@ -0,0 +1,266 @@ +// Copyright (C) 2007 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_STL_LOADER_ + +#include "CSTLMeshFileLoader.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "coreutil.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CSTLMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".stl")!=0; +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) +{ + const long filesize = file->getSize(); + if (filesize < 6) // we need a header + return 0; + + const u32 WORD_BUFFER_LENGTH = 512; + + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer( new SMeshBuffer() ); + + core::vector3df vertex[3]; + core::vector3df normal; + + c8 buffer[WORD_BUFFER_LENGTH]; + + bool binary = false; + file->read(buffer, 5); + if (strncmp("solid", buffer, 5)) + binary = true; + // read/skip header + u32 binFaceCount = 0; + if (binary) + { + file->seek(80); + file->read(&binFaceCount, 4); +#ifdef __BIG_ENDIAN__ + binFaceCount = os::Byteswap::byteswap(binFaceCount); +#endif + } + else + goNextLine(file); + + u16 attrib=0; + core::stringc token; + token.reserve(32); + + while (file->getPos() < filesize) + { + if (!binary) + { + if (getNextToken(file, token) != "facet") + { + if (token=="endsolid") + break; + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "normal") + { + mesh->drop(); + return 0; + } + } + getNextVector(file, normal, binary); + if (!binary) + { + if (getNextToken(file, token) != "outer") + { + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "loop") + { + mesh->drop(); + return 0; + } + } + for (u32 i=0; i<3; ++i) + { + if (!binary) + { + if (getNextToken(file, token) != "vertex") + { + mesh->drop(); + return 0; + } + } + getNextVector(file, vertex[i], binary); + } + if (!binary) + { + if (getNextToken(file, token) != "endloop") + { + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "endfacet") + { + mesh->drop(); + return 0; + } + } + else + { + file->read(&attrib, 2); +#ifdef __BIG_ENDIAN__ + attrib = os::Byteswap::byteswap(attrib); +#endif + } + + SMeshBuffer* mb = reinterpret_cast(mesh->getMeshBuffer(mesh->getMeshBufferCount()-1)); + u32 vCount = mb->getVertexCount(); + video::SColor color(0xffffffff); + if (attrib & 0x8000) + color = video::A1R5G5B5toA8R8G8B8(attrib); + mb->Vertices.push_back(video::S3DVertex(vertex[0],normal,color, core::vector2df())); + mb->Vertices.push_back(video::S3DVertex(vertex[1],normal,color, core::vector2df())); + mb->Vertices.push_back(video::S3DVertex(vertex[2],normal,color, core::vector2df())); + mb->Indices.push_back(vCount); + mb->Indices.push_back(vCount+1); + mb->Indices.push_back(vCount+2); + } // end while (file->getPos() < filesize) + + // Create the Animated mesh if there's anything in the mesh + SAnimatedMesh* pAM = 0; + if ( 0 != mesh->getMeshBufferCount() ) + { + mesh->recalculateBoundingBox(); + pAM = new SAnimatedMesh(); + pAM->Type = EAMT_OBJ; + pAM->addMesh(mesh); + pAM->recalculateBoundingBox(); + } + + mesh->drop(); + + return pAM; +} + + +//! Read RGB color +const c8* CSTLMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const c8* const pBufEnd) const +{ + const u32 COLOR_BUFFER_LENGTH = 16; + c8 colStr[COLOR_BUFFER_LENGTH]; + + color.setAlpha(255); + color.setRed((s32)(core::fast_atof(colStr) * 255.0f)); + color.setGreen((s32)(core::fast_atof(colStr) * 255.0f)); + color.setBlue((s32)(core::fast_atof(colStr) * 255.0f)); + return bufPtr; +} + + +//! Read 3d vector of floats +void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const +{ + if (binary) + { + file->read(&vec.X, 4); + file->read(&vec.Y, 4); + file->read(&vec.Z, 4); +#ifdef __BIG_ENDIAN__ + vec.X = os::Byteswap::byteswap(vec.X); + vec.Y = os::Byteswap::byteswap(vec.Y); + vec.Z = os::Byteswap::byteswap(vec.Z); +#endif + } + else + { + goNextWord(file); + core::stringc tmp; + + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.X); + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.Y); + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.Z); + } +} + + +//! Read next word +const core::stringc& CSTLMeshFileLoader::getNextToken(io::IReadFile* file, core::stringc& token) const +{ + goNextWord(file); + u8 c; + token = ""; + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (core::isspace(c)) + break; + token.append(c); + } + return token; +} + + +//! skip to next word +void CSTLMeshFileLoader::goNextWord(io::IReadFile* file) const +{ + u8 c; + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (!core::isspace(c)) + { + file->seek(-1, true); + break; + } + } +} + + +//! Read until line break is reached and stop at the next non-space character +void CSTLMeshFileLoader::goNextLine(io::IReadFile* file) const +{ + u8 c; + // look for newline characters + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (c=='\n' || c=='\r') + break; + } +} + + +} // end namespace scene +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_STL_LOADER_ + diff --git a/src/dep/src/irrlicht/CSTLMeshFileLoader.h b/src/dep/src/irrlicht/CSTLMeshFileLoader.h new file mode 100644 index 0000000..679e0f2 --- /dev/null +++ b/src/dep/src/irrlicht/CSTLMeshFileLoader.h @@ -0,0 +1,52 @@ +// Copyright (C) 2007 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_STL_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_STL_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "irrString.h" +#include "SColor.h" +#include "vector3d.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading STL meshes. +class CSTLMeshFileLoader : public IMeshLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (i.e. ".stl") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + // skips to the first non-space character available + void goNextWord(io::IReadFile* file) const; + // returns the next word + const core::stringc& getNextToken(io::IReadFile* file, core::stringc& token) const; + // skip to next printable character after the first line break + void goNextLine(io::IReadFile* file) const; + + //! Read RGB color + const c8* readColor(const c8* pBufPtr, video::SColor& color, const c8* const pBufEnd) const; + //! Read 3d vector of floats + void getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSTLMeshWriter.cpp b/src/dep/src/irrlicht/CSTLMeshWriter.cpp new file mode 100644 index 0000000..899f7d3 --- /dev/null +++ b/src/dep/src/irrlicht/CSTLMeshWriter.cpp @@ -0,0 +1,246 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ + +#include "CSTLMeshWriter.h" +#include "os.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IAttributes.h" +#include "ISceneManager.h" +#include "IMeshCache.h" +#include "IWriteFile.h" + +namespace irr +{ +namespace scene +{ + +CSTLMeshWriter::CSTLMeshWriter(scene::ISceneManager* smgr) + : SceneManager(smgr) +{ + if (SceneManager) + SceneManager->grab(); +} + + +CSTLMeshWriter::~CSTLMeshWriter() +{ + if (SceneManager) + SceneManager->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CSTLMeshWriter::getType() const +{ + return EMWT_STL; +} + + +//! writes a mesh +bool CSTLMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + os::Printer::log("Writing mesh", file->getFileName()); + + if (flags & scene::EMWF_WRITE_COMPRESSED) + return writeMeshBinary(file, mesh, flags); + else + return writeMeshASCII(file, mesh, flags); +} + + +bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + // write STL MESH header + + file->write("binary ",7); + const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh)); + const s32 sizeleft = 73-name.size(); // 80 byte header + if (sizeleft<0) + file->write(name.c_str(),73); + else + { + char* buf = new char[80]; + memset(buf, 0, 80); + file->write(name.c_str(),name.size()); + file->write(buf,sizeleft); + delete [] buf; + } + u32 facenum = 0; + for (u32 j=0; jgetMeshBufferCount(); ++j) + facenum += mesh->getMeshBuffer(j)->getIndexCount()/3; + file->write(&facenum,4); + + // write mesh buffers + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + const u16 indexCount = buffer->getIndexCount(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + const u16 attributes = 0; + for (u32 j=0; jgetIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos); + file->write(&tmpplane.Normal, 12); + file->write(&vtx[buffer->getIndices()[j]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12); + file->write(&attributes, 2); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + const u16 attributes = 0; + for (u32 j=0; jgetIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos); + file->write(&tmpplane.Normal, 12); + file->write(&vtx[buffer->getIndices()[j]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12); + file->write(&attributes, 2); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + const u16 attributes = 0; + for (u32 j=0; jgetIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos); + file->write(&tmpplane.Normal, 12); + file->write(&vtx[buffer->getIndices()[j]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12); + file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12); + file->write(&attributes, 2); + } + } + break; + } + } + } + return true; +} + + +bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + // write STL MESH header + + file->write("solid ",6); + const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh)); + file->write(name.c_str(),name.size()); + file->write("\n\n",2); + + // write mesh buffers + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + const u16 indexCount = buffer->getIndexCount(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jgetIndices()[j]].Pos, + vtx[buffer->getIndices()[j+1]].Pos, + vtx[buffer->getIndices()[j+2]].Pos); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jgetIndices()[j]].Pos, + vtx[buffer->getIndices()[j+1]].Pos, + vtx[buffer->getIndices()[j+2]].Pos); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jgetIndices()[j]].Pos, + vtx[buffer->getIndices()[j+1]].Pos, + vtx[buffer->getIndices()[j+2]].Pos); + } + break; + } + file->write("\n",1); + } + } + + file->write("endsolid ",9); + file->write(name.c_str(),name.size()); + + return true; +} + + +void CSTLMeshWriter::getVectorAsStringLine(const core::vector3df& v, core::stringc& s) const +{ + s = v.X; + s += " "; + s += v.Y; + s += " "; + s += v.Z; + s += "\n"; +} + + +void CSTLMeshWriter::writeFace(io::IWriteFile* file, + const core::vector3df& v1, + const core::vector3df& v2, + const core::vector3df& v3) +{ + core::stringc tmp; + file->write("facet normal ",13); + getVectorAsStringLine(core::plane3df(v1,v2,v3).Normal, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" outer loop\n",13); + file->write(" vertex ",11); + getVectorAsStringLine(v1, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" vertex ",11); + getVectorAsStringLine(v2, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" vertex ",11); + getVectorAsStringLine(v3, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" endloop\n",10); + file->write("endfacet\n",9); +} + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CSTLMeshWriter.h b/src/dep/src/irrlicht/CSTLMeshWriter.h new file mode 100644 index 0000000..0a0fd0d --- /dev/null +++ b/src/dep/src/irrlicht/CSTLMeshWriter.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_STL_MESH_WRITER_H_INCLUDED__ +#define __IRR_STL_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + class IMeshBuffer; + class ISceneManager; + + //! class to write meshes, implementing a STL writer + class CSTLMeshWriter : public IMeshWriter + { + public: + + CSTLMeshWriter(scene::ISceneManager* smgr); + virtual ~CSTLMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + protected: + // write binary format + bool writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags); + + // write text format + bool writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags); + + // create vector output with line end into string + void getVectorAsStringLine(const core::vector3df& v, + core::stringc& s) const; + + // write face information to file + void writeFace(io::IWriteFile* file, const core::vector3df& v1, + const core::vector3df& v2, const core::vector3df& v3); + + scene::ISceneManager* SceneManager; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CSceneCollisionManager.cpp b/src/dep/src/irrlicht/CSceneCollisionManager.cpp new file mode 100644 index 0000000..7a20501 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneCollisionManager.cpp @@ -0,0 +1,737 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneCollisionManager.h" +#include "ISceneNode.h" +#include "ICameraSceneNode.h" +#include "ITriangleSelector.h" +#include "SViewFrustum.h" + +#include "os.h" +#include "irrMath.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneCollisionManager::CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver) +: SceneManager(smanager), Driver(driver) +{ + #ifdef _DEBUG + setDebugName("CSceneCollisionManager"); + #endif + + if (Driver) + Driver->grab(); +} + + + +//! destructor +CSceneCollisionManager::~CSceneCollisionManager() +{ + if (Driver) + Driver->drop(); +} + + + +//! Returns the scene node, which is currently visible under the overgiven +//! screencoordinates, viewed from the currently active camera. +ISceneNode* CSceneCollisionManager::getSceneNodeFromScreenCoordinatesBB( + core::position2d pos, s32 idBitMask, bool bNoDebugObjects) +{ + core::line3d ln = getRayFromScreenCoordinates(pos, 0); + + if ( ln.start == ln.end ) + return 0; + + return getSceneNodeFromRayBB(ln, idBitMask, bNoDebugObjects); +} + + + +//! Returns the nearest scene node which collides with a 3d ray and +//! which id matches a bitmask. +ISceneNode* CSceneCollisionManager::getSceneNodeFromRayBB(core::line3d ray, + s32 idBitMask, + bool bNoDebugObjects) +{ + ISceneNode* best = 0; + f32 dist = 9999999999.0f; + + getPickedNodeBB(SceneManager->getRootSceneNode(), ray, + idBitMask, bNoDebugObjects, dist, best); + + return best; +} + + +//! recursive method for going through all scene nodes +void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, + const core::line3df& ray, + s32 bits, + bool bNoDebugObjects, + f32& outbestdistance, + ISceneNode*& outbestnode) +{ + core::vector3df edges[8]; + + const core::list& children = root->getChildren(); + + core::list::ConstIterator it = children.begin(); + for (; it != children.end(); ++it) + { + ISceneNode* current = *it; + + if (current->isVisible() && + (bNoDebugObjects ? !current->isDebugObject() : true) && + (bits==0 || (bits != 0 && (current->getID() & bits)))) + { + // get world to object space transform + core::matrix4 mat; + if (!current->getAbsoluteTransformation().getInverse(mat)) + continue; + + // transform vector from world space to object space + core::line3df line(ray); + mat.transformVect(line.start); + mat.transformVect(line.end); + + const core::aabbox3df& box = current->getBoundingBox(); + + // do intersection test in object space + if (box.intersectsWithLine(line)) + { + box.getEdges(edges); + f32 distance = 0.0f; + + for (s32 e=0; e<8; ++e) + { + f32 t = edges[e].getDistanceFromSQ(line.start); + if (t > distance) + distance = t; + } + + if (distance < outbestdistance) + { + outbestnode = current; + outbestdistance = distance; + } + } + } + + getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode); + } +} + + + +//! Returns the scene node, at which the overgiven camera is looking at and +//! which id matches the bitmask. +ISceneNode* CSceneCollisionManager::getSceneNodeFromCameraBB( + ICameraSceneNode* camera, s32 idBitMask, bool bNoDebugObjects) +{ + if (!camera) + return 0; + + core::vector3df start = camera->getAbsolutePosition(); + core::vector3df end = camera->getTarget(); + + end = start + ((end - start).normalize() * camera->getFarValue()); + core::line3d line(start, end); + + return getSceneNodeFromRayBB(line, idBitMask, bNoDebugObjects); +} + + + +//! Finds the collision point of a line and lots of triangles, if there is one. +bool CSceneCollisionManager::getCollisionPoint(const core::line3d& ray, + ITriangleSelector* selector, core::vector3df& outIntersection, + core::triangle3df& outTriangle) +{ + if (!selector) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + s32 totalcnt = selector->getTriangleCount(); + Triangles.set_used(totalcnt); + + s32 cnt = 0; + selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray); + + const core::vector3df linevect = ray.getVector().normalize(); + core::vector3df intersection; + f32 nearest = 9999999999999.0f; + bool found = false; + const f32 raylength = ray.getLengthSQ(); + + for (s32 i=0; i trianglePlane = triangle.getPlane(); + + // only check front facing polygons + if ( !trianglePlane.isFrontFacing(colData->normalizedVelocity) ) + return; + + // get interval of plane intersection + + f32 t1, t0; + bool embeddedInPlane = false; + + // calculate signed distance from sphere position to triangle plane + f32 signedDistToTrianglePlane = trianglePlane.getDistanceTo( + colData->basePoint); + + f32 normalDotVelocity = + trianglePlane.Normal.dotProduct(colData->velocity); + + if ( core::iszero ( normalDotVelocity ) ) + { + // sphere is traveling parallel to plane + + if (fabs(signedDistToTrianglePlane) >= 1.0f) + return; // no collision possible + else + { + // sphere is embedded in plane + embeddedInPlane = true; + t0 = 0.0; + t1 = 1.0; + } + } + else + { + normalDotVelocity = core::reciprocal ( normalDotVelocity ); + + // N.D is not 0. Calculate intersection interval + t0 = (-1.f - signedDistToTrianglePlane) * normalDotVelocity; + t1 = (1.f - signedDistToTrianglePlane) * normalDotVelocity; + + // Swap so t0 < t1 + if (t0 > t1) { f32 tmp = t1; t1 = t0; t0 = tmp; } + + // check if at least one value is within the range + if (t0 > 1.0f || t1 < 0.0f) + return; // both t values are outside 1 and 0, no collision possible + + // clamp to 0 and 1 + t0 = core::clamp ( t0, 0.f, 1.f ); + t1 = core::clamp ( t1, 0.f, 1.f ); + } + + // at this point we have t0 and t1, if there is any intersection, it + // is between this interval + core::vector3df collisionPoint; + bool foundCollision = false; + f32 t = 1.0f; + + // first check the easy case: Collision within the triangle; + // if this happens, it must be at t0 and this is when the sphere + // rests on the front side of the triangle plane. This can only happen + // if the sphere is not embedded in the triangle plane. + + if (!embeddedInPlane) + { + core::vector3df planeIntersectionPoint = + (colData->basePoint - trianglePlane.Normal) + + (colData->velocity * t0); + + if (triangle.isPointInsideFast(planeIntersectionPoint)) + { + foundCollision = true; + t = t0; + collisionPoint = planeIntersectionPoint; + } + } + + // if we havent found a collision already we will have to sweep + // the sphere against points and edges of the triangle. Note: A + // collision inside the triangle will always happen before a + // vertex or edge collision. + + if (!foundCollision) + { + core::vector3df velocity = colData->velocity; + core::vector3df base = colData->basePoint; + + f32 velocitySqaredLength = velocity.getLengthSQ(); + f32 a,b,c; + f32 newT; + + // for each edge or vertex a quadratic equation has to be solved: + // a*t^2 + b*t + c = 0. We calculate a,b, and c for each test. + + // check against points + a = velocitySqaredLength; + + // p1 + b = 2.0f * (velocity.dotProduct(base - triangle.pointA)); + c = (triangle.pointA-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointA; + } + + // p2 + if (!foundCollision) + { + b = 2.0f * (velocity.dotProduct(base - triangle.pointB)); + c = (triangle.pointB-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointB; + } + } + + // p3 + if (!foundCollision) + { + b = 2.0f * (velocity.dotProduct(base - triangle.pointC)); + c = (triangle.pointC-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointC; + } + } + + // check against edges: + + // p1 --- p2 + core::vector3df edge = triangle.pointB - triangle.pointA; + core::vector3df baseToVertex = triangle.pointA - base; + f32 edgeSqaredLength = edge.getLengthSQ(); + f32 edgeDotVelocity = edge.dotProduct(velocity); + f32 edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2.f *velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1.f -baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT - edgeDotBaseToVertex) / edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointA + (edge*f); + } + } + + // p2 --- p3 + edge = triangle.pointC-triangle.pointB; + baseToVertex = triangle.pointB - base; + edgeSqaredLength = edge.getLengthSQ(); + edgeDotVelocity = edge.dotProduct(velocity); + edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2*velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1-baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT-edgeDotBaseToVertex) / + edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointB + (edge*f); + } + } + + + // p3 --- p1 + edge = triangle.pointA-triangle.pointC; + baseToVertex = triangle.pointC - base; + edgeSqaredLength = edge.getLengthSQ(); + edgeDotVelocity = edge.dotProduct(velocity); + edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2*velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1-baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT-edgeDotBaseToVertex) / + edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointC + (edge*f); + } + } + }// end no collision found + + // set result: + if (foundCollision) + { + // distance to collision is t + f32 distToCollision = t*colData->velocity.getLength(); + + // does this triangle qualify for closest hit? + if (!colData->foundCollision || + distToCollision < colData->nearestDistance) + { + colData->nearestDistance = distToCollision; + colData->intersectionPoint = collisionPoint; + colData->foundCollision = true; + colData->intersectionTriangle = triangle; + ++colData->triangleHits; + } + + }// end found collision +} + + + +//! Collides a moving ellipsoid with a 3d world with gravity and returns +//! the resulting new position of the ellipsoid. +core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( + ITriangleSelector* selector, const core::vector3df &position, + const core::vector3df& radius, const core::vector3df& velocity, + f32 slidingSpeed, + const core::vector3df& gravity, + core::triangle3df& triout, bool& outFalling) +{ + if (!selector || radius.X == 0.0f || radius.Y == 0.0f || radius.Z == 0.0f) + return position; + + // This code is based on the paper "Improved Collision detection and Response" + // by Kasper Fauerby, but some parts are modified. + + SCollisionData colData; + colData.R3Position = position; + colData.R3Velocity = velocity; + colData.eRadius = radius; + colData.nearestDistance = 9999999999999.0f; + colData.selector = selector; + colData.slidingSpeed = slidingSpeed; + colData.triangleHits = 0; + + core::vector3df eSpacePosition = colData.R3Position / colData.eRadius; + core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius; + + // iterate until we have our final position + + core::vector3df finalPos = collideWithWorld( + 0, colData, eSpacePosition, eSpaceVelocity); + + outFalling = false; + + // add gravity + + if (gravity != core::vector3df(0,0,0)) + { + colData.R3Position = finalPos * colData.eRadius; + colData.R3Velocity = gravity; + colData.triangleHits = 0; + + eSpaceVelocity = gravity/colData.eRadius; + + finalPos = collideWithWorld(0, colData, + finalPos, eSpaceVelocity); + + outFalling = (colData.triangleHits == 0); + } + + if (colData.triangleHits) + { + triout = colData.intersectionTriangle; + triout.pointA *= colData.eRadius; + triout.pointB *= colData.eRadius; + triout.pointC *= colData.eRadius; + } + + finalPos *= colData.eRadius; + return finalPos; +} + +core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth, + SCollisionData &colData, core::vector3df pos, core::vector3df vel) +{ + f32 veryCloseDistance = colData.slidingSpeed; + + if (recursionDepth > 5) + return pos; + + colData.velocity = vel; + colData.normalizedVelocity = vel; + colData.normalizedVelocity.normalize(); + colData.basePoint = pos; + colData.foundCollision = false; + colData.nearestDistance = 9999999999999.0f; + + //------------------ collide with world + + // get all triangles with which we might collide + core::aabbox3d box(colData.R3Position); + box.addInternalPoint(colData.R3Position + colData.R3Velocity); + box.MinEdge -= colData.eRadius; + box.MaxEdge += colData.eRadius; + + s32 totalTriangleCnt = colData.selector->getTriangleCount(); + Triangles.set_used(totalTriangleCnt); + + core::matrix4 scaleMatrix; + scaleMatrix.setScale( + core::vector3df(1.0f / colData.eRadius.X, + 1.0f / colData.eRadius.Y, + 1.0f / colData.eRadius.Z) + ); + + s32 triangleCnt = 0; + colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix); + //colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, &scaleMatrix); + + for (s32 i=0; i= veryCloseDistance) + { + core::vector3df v = vel; + v.setLength( colData.nearestDistance - veryCloseDistance ); + newBasePoint = colData.basePoint + v; + + v.normalize(); + colData.intersectionPoint -= (v * veryCloseDistance); + } + + // calculate sliding plane + + core::vector3df slidePlaneOrigin = colData.intersectionPoint; + core::vector3df slidePlaneNormal = newBasePoint - colData.intersectionPoint; + slidePlaneNormal.normalize(); + core::plane3d slidingPlane(slidePlaneOrigin, slidePlaneNormal); + + core::vector3df newDestinationPoint = + destinationPoint - + (slidePlaneNormal * slidingPlane.getDistanceTo(destinationPoint)); + + // generate slide vector + + core::vector3df newVelocityVector = newDestinationPoint - + colData.intersectionPoint; + + if (newVelocityVector.getLength() < veryCloseDistance) + return newBasePoint; + + return collideWithWorld(recursionDepth+1, colData, + newBasePoint, newVelocityVector); +} + + +//! Returns a 3d ray which would go through the 2d screen coodinates. +core::line3d CSceneCollisionManager::getRayFromScreenCoordinates( + core::position2d pos, ICameraSceneNode* camera) +{ + core::line3d ln(0,0,0,0,0,0); + + if (!SceneManager) + return ln; + + if (!camera) + camera = SceneManager->getActiveCamera(); + + if (!camera) + return ln; + + const scene::SViewFrustum* f = camera->getViewFrustum(); + + core::vector3df farLeftUp = f->getFarLeftUp(); + core::vector3df lefttoright = f->getFarRightUp() - farLeftUp; + core::vector3df uptodown = f->getFarLeftDown() - farLeftUp; + + core::rect viewPort = Driver->getViewPort(); + core::dimension2d screenSize(viewPort.getWidth(), viewPort.getHeight()); + + f32 dx = pos.X / (f32)screenSize.Width; + f32 dy = pos.Y / (f32)screenSize.Height; + + if (camera->isOrthogonal()) + ln.start = f->cameraPosition + (lefttoright * (dx-0.5f)) + (uptodown * (dy-0.5f)); + else + ln.start = f->cameraPosition; + + ln.end = farLeftUp + (lefttoright * dx) + (uptodown * dy); + + return ln; +} + + + +//! Calculates 2d screen position from a 3d position. +core::position2d CSceneCollisionManager::getScreenCoordinatesFrom3DPosition( + core::vector3df pos3d, ICameraSceneNode* camera) +{ + core::position2d pos2d(-1000,-1000); + + if (!SceneManager || !Driver) + return pos2d; + + if (!camera) + camera = SceneManager->getActiveCamera(); + + if (!camera) + return pos2d; + + core::rect viewPort = Driver->getViewPort(); + core::dimension2d dim(viewPort.getWidth(), viewPort.getHeight()); + + dim.Width /= 2; + dim.Height /= 2; + + f32 transformedPos[4]; + + core::matrix4 trans = camera->getProjectionMatrix(); + trans *= camera->getViewMatrix(); + + transformedPos[0] = pos3d.X; + transformedPos[1] = pos3d.Y; + transformedPos[2] = pos3d.Z; + transformedPos[3] = 1.0f; + + trans.multiplyWith1x4Matrix(transformedPos); + + if (transformedPos[3] < 0) + return core::position2d(-10000,-10000); + + f32 zDiv = transformedPos[3] == 0.0f ? 1.0f : + (1.0f / transformedPos[3]); + + pos2d.X = (s32)(dim.Width * transformedPos[0] * zDiv) + dim.Width; + pos2d.Y = ((s32)(dim.Height - (dim.Height * (transformedPos[1] * zDiv)))); + + return pos2d; +} + +inline bool CSceneCollisionManager::getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root) +{ + // check if solution exists + f32 determinant = b*b - 4.0f*a*c; + + // if determinant is negative, no solution + if (determinant < 0.0f) return false; + + // calculate two roots: (if det==0 then x1==x2 + // but lets disregard that slight optimization) + // burningwater: sqrt( 0) is an illegal operation.... smth should be done... + + f32 sqrtD = (f32)sqrt(determinant); + + f32 r1 = (-b - sqrtD) / (2*a); + f32 r2 = (-b + sqrtD) / (2*a); + + // sort so x1 <= x2 + if (r1 > r2) { f32 tmp=r2; r2=r1; r1=tmp; } + + // get lowest root + if (r1 > 0 && r1 < maxR) + { + *root = r1; + return true; + } + + // its possible that we want x2, this can happen if x1 < 0 + if (r2 > 0 && r2 < maxR) + { + *root = r2; + return true; + } + + return false; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneCollisionManager.h b/src/dep/src/irrlicht/CSceneCollisionManager.h new file mode 100644 index 0000000..0194914 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneCollisionManager.h @@ -0,0 +1,126 @@ +#ifndef __C_SCENE_COLLISION_MANAGER_H_INCLUDED__ +#define __C_SCENE_COLLISION_MANAGER_H_INCLUDED__ + +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "ISceneCollisionManager.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + + //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes. + class CSceneCollisionManager : public ISceneCollisionManager + { + public: + + //! constructor + CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver); + + //! destructor + virtual ~CSceneCollisionManager(); + + //! Returns the scene node, which is currently visible under the overgiven + //! screencoordinates, viewed from the currently active camera. + virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(core::position2d pos, + s32 idBitMask=0, bool bNoDebugObjects = false); + + //! Returns the nearest scene node which collides with a 3d ray and + //! which id matches a bitmask. + virtual ISceneNode* getSceneNodeFromRayBB(core::line3d ray, s32 idBitMask=0, + bool bNoDebugObjects = false); + + //! Returns the scene node, at which the overgiven camera is looking at and + //! which id matches the bitmask. + virtual ISceneNode* getSceneNodeFromCameraBB(ICameraSceneNode* camera, s32 idBitMask=0, + bool bNoDebugObjects = false); + + //! Finds the collision point of a line and lots of triangles, if there is one. + virtual bool getCollisionPoint(const core::line3d& ray, + ITriangleSelector* selector, core::vector3df& outCollisionPoint, + core::triangle3df& outTriangle); + + //! Collides a moving ellipsoid with a 3d world with gravity and returns + //! the resulting new position of the ellipsoid. + virtual core::vector3df getCollisionResultPosition( + ITriangleSelector* selector, + const core::vector3df &ellipsoidPosition, const core::vector3df& ellipsoidRadius, + const core::vector3df& ellipsoidDirectionAndSpeed, + core::triangle3df& triout, + bool& outFalling, + f32 slidingSpeed, + const core::vector3df& gravityDirectionAndSpeed); + + //! Returns a 3d ray which would go through the 2d screen coodinates. + virtual core::line3d getRayFromScreenCoordinates( + core::position2d pos, ICameraSceneNode* camera = 0); + + //! Calculates 2d screen position from a 3d position. + virtual core::position2d getScreenCoordinatesFrom3DPosition( + core::vector3df pos, ICameraSceneNode* camera=0); + + private: + + //! recursive method for going through all scene nodes + void getPickedNodeBB(ISceneNode* root, + const core::line3df& ray, + s32 bits, + bool bNoDebugObjects, + f32& outbestdistance, + ISceneNode*& outbestnode); + + struct SCollisionData + { + core::vector3df eRadius; + + core::vector3df R3Velocity; + core::vector3df R3Position; + + core::vector3df velocity; + core::vector3df normalizedVelocity; + core::vector3df basePoint; + + bool foundCollision; + f32 nearestDistance; + core::vector3df intersectionPoint; + + core::triangle3df intersectionTriangle; + s32 triangleHits; + + f32 slidingSpeed; + + ITriangleSelector* selector; + }; + + void testTriangleIntersection(SCollisionData* colData, + const core::triangle3df& triangle); + + //! recursive method for doing collision response + core::vector3df collideEllipsoidWithWorld(ITriangleSelector* selector, + const core::vector3df &position, + const core::vector3df& radius, const core::vector3df& velocity, + f32 slidingSpeed, + const core::vector3df& gravity, core::triangle3df& triout, + bool& outFalling); + + core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData, + core::vector3df pos, core::vector3df vel); + + inline bool getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root); + + ISceneManager* SceneManager; + video::IVideoDriver* Driver; + core::array Triangles; // triangle buffer + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneManager.cpp b/src/dep/src/irrlicht/CSceneManager.cpp new file mode 100644 index 0000000..e1a8103 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneManager.cpp @@ -0,0 +1,2239 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CSceneManager.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "SAnimatedMesh.h" +#include "CMeshCache.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" +#include "ISceneUserDataSerializer.h" +#include "IGUIEnvironment.h" +#include "IMaterialRenderer.h" + +#include "os.h" + +#include "CGeometryCreator.h" + +#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ +#include "CIrrMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ +#include "CBSPMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ +#include "CMD2MeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ +#include "CMS3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_3DS_LOADER_ +#include "C3DSMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_X_LOADER_ +#include "CXMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OCT_LOADER_ +#include "COCTLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_CSM_LOADER_ +#include "CCSMLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ +#include "CLMTSMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ +#include "CMY3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ +#include "CColladaFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ +#include "CDMFLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ +#include "COgreMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ +#include "COBJMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ +#include "CMD3MeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_B3D_LOADER_ +#include "CB3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_STL_LOADER_ +#include "CSTLMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_ +#include "CColladaMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_IRR_WRITER_ +#include "CIrrMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ +#include "CSTLMeshWriter.h" +#endif + +#include "CCubeSceneNode.h" +#include "CSphereSceneNode.h" +#include "CAnimatedMeshSceneNode.h" +#include "COctTreeSceneNode.h" +#include "CCameraSceneNode.h" +#include "CCameraMayaSceneNode.h" +#include "CCameraFPSSceneNode.h" +#include "CLightSceneNode.h" +#include "CBillboardSceneNode.h" +#include "CMeshSceneNode.h" +#include "CSkyBoxSceneNode.h" +#include "CSkyDomeSceneNode.h" +#include "CParticleSystemSceneNode.h" +#include "CDummyTransformationSceneNode.h" +#include "CWaterSurfaceSceneNode.h" +#include "CTerrainSceneNode.h" +#include "CEmptySceneNode.h" +#include "CTextSceneNode.h" +#include "CDefaultSceneNodeFactory.h" + +#include "CSceneCollisionManager.h" +#include "CMeshManipulator.h" +#include "CTriangleSelector.h" +#include "COctTreeTriangleSelector.h" +#include "CTriangleBBSelector.h" +#include "CMetaTriangleSelector.h" +#include "CTerrainTriangleSelector.h" + +#include "CSceneNodeAnimatorRotation.h" +#include "CSceneNodeAnimatorFlyCircle.h" +#include "CSceneNodeAnimatorFlyStraight.h" +#include "CSceneNodeAnimatorTexture.h" +#include "CSceneNodeAnimatorCollisionResponse.h" +#include "CSceneNodeAnimatorDelete.h" +#include "CSceneNodeAnimatorFollowSpline.h" +#include "CDefaultSceneNodeAnimatorFactory.h" + +#include "CQuake3ShaderSceneNode.h" + +//! Enable debug features +#define SCENEMANAGER_DEBUG + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, + gui::ICursorControl* cursorControl, IMeshCache* cache, + gui::IGUIEnvironment* gui) +: ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui), + CursorControl(cursorControl), CollisionManager(0), MeshManipulator(0), + ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0), + MeshCache(cache), CurrentRendertime(ESNRP_COUNT), + IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type") +{ + #ifdef _DEBUG + ISceneManager::setDebugName("CSceneManager ISceneManager"); + ISceneNode::setDebugName("CSceneManager ISceneNode"); + #endif + + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + if (CursorControl) + CursorControl->grab(); + + if ( GUIEnvironment ) + GUIEnvironment->grab(); + + // create mesh cache if not there already + if (!MeshCache) + MeshCache = new CMeshCache(); + else + MeshCache->grab(); + + // create collision manager + CollisionManager = new CSceneCollisionManager(this, Driver); + + // create manipulator + MeshManipulator = new CMeshManipulator(); + + // add file format loaders + + #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + MeshLoaderList.push_back(new CIrrMeshFileLoader(Driver, this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + MeshLoaderList.push_back(new CBSPMeshFileLoader(FileSystem, Driver, this)); + #endif + #ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + MeshLoaderList.push_back(new CMD2MeshFileLoader()); + #endif + #ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ + MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_3DS_LOADER_ + MeshLoaderList.push_back(new C3DSMeshFileLoader(MeshManipulator,FileSystem, Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_X_LOADER_ + MeshLoaderList.push_back(new CXMeshFileLoader(this)); + #endif + #ifdef _IRR_COMPILE_WITH_OCT_LOADER_ + MeshLoaderList.push_back(new COCTLoader(Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_CSM_LOADER_ + MeshLoaderList.push_back(new CCSMLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ + MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters)); + #endif + #ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ + MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this)); + #endif + #ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ + MeshLoaderList.push_back(new CColladaFileLoader(Driver, this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_DMF_LOADER_ + MeshLoaderList.push_back(new CDMFLoader(Driver, this)); + #endif + #ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ + MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ + MeshLoaderList.push_back(new COBJMeshFileLoader(FileSystem, Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + MeshLoaderList.push_back(new CMD3MeshFileLoader(FileSystem, Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_B3D_LOADER_ + MeshLoaderList.push_back(new CB3DMeshFileLoader(this)); + #endif + #ifdef _IRR_COMPILE_WITH_STL_LOADER_ + MeshLoaderList.push_back(new CSTLMeshFileLoader()); + #endif + + // factories + ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this); + registerSceneNodeFactory(factory); + factory->drop(); + + ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this); + registerSceneNodeAnimatorFactory(animatorFactory); + animatorFactory->drop(); +} + + + +//! destructor +CSceneManager::~CSceneManager() +{ + clearDeletionList(); + + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); + + if (CursorControl) + CursorControl->drop(); + + if (CollisionManager) + CollisionManager->drop(); + + if (MeshManipulator) + MeshManipulator->drop(); + + if ( GUIEnvironment ) + GUIEnvironment->drop (); + + u32 i; + + for (i=0; idrop(); + + if (ActiveCamera) + ActiveCamera->drop(); + + if (MeshCache) + MeshCache->drop(); + + for (i=0; idrop(); + + for (i=0; idrop(); +} + + +//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. +IAnimatedMesh* CSceneManager::getMesh(const c8* filename) +{ + IAnimatedMesh* msh = MeshCache->getMeshByFilename(filename); + if (msh) + return msh; + + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + if (!file) + { + os::Printer::log("Could not load mesh, because file could not be opened.", filename, ELL_ERROR); + return 0; + } + + core::stringc name = filename; + name.make_lower(); + s32 count = MeshLoaderList.size(); + for (s32 i=count-1; i>=0; --i) + { + if (MeshLoaderList[i]->isALoadableFileExtension(name.c_str())) + { + // reset file to avoid side effects of previous calls to createMesh + file->seek(0); + msh = MeshLoaderList[i]->createMesh(file); + if (msh) + { + MeshCache->addMesh(filename, msh); + msh->drop(); + break; + } + } + } + + file->drop(); + + if (!msh) + os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR); + else + os::Printer::log("Loaded mesh", filename, ELL_INFORMATION); + + return msh; +} + + +//! returns the video driver +video::IVideoDriver* CSceneManager::getVideoDriver() +{ + return Driver; +} + +//! returns the GUI Environment +gui::IGUIEnvironment* CSceneManager::getGUIEnvironment () +{ + return GUIEnvironment; +} + + +//! Adds a text scene node, which is able to display +//! 2d text at a position in three dimensional space +ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font, + const wchar_t* text, video::SColor color, ISceneNode* parent, + const core::vector3df& position, s32 id) +{ + if (!font) + return 0; + + if (!parent) + parent = this; + + ITextSceneNode* t = new CTextSceneNode(parent, this, id, font, + getSceneCollisionManager(), position, text, color); + t->drop(); + + return t; +} + +//! Adds a text scene node, which uses billboards +ITextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font, + const wchar_t* text, ISceneNode* parent, + const core::dimension2d& size, + const core::vector3df& position, s32 id, + video::SColor shade_top, video::SColor shade_down) +{ + if (!font) + return 0; + + if (!parent) + parent = this; + + ITextSceneNode* node = new CBillboardTextSceneNode(parent, this, id, font, text, position, size, + shade_top, shade_down); + node->drop(); + + return node; + +} + + +//! Adds a scene node, which can render a quake3 shader +ISceneNode* CSceneManager::addQuake3SceneNode( IMeshBuffer* meshBuffer, + const quake3::SShader * shader, + ISceneNode* parent, + s32 id + ) + +{ + if ( 0 == shader ) + return 0; + + if (!parent) + parent = this; + + CQuake3ShaderSceneNode* node = new CQuake3ShaderSceneNode ( parent, this, id, FileSystem, meshBuffer, shader ); + node->drop(); + + return node; + +} + + +//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size. +//! the returned pointer must not be dropped. +ISceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CCubeSceneNode(size, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + +//! Adds a sphere scene node for test purposes to the scene. +ISceneNode* CSceneManager::addSphereSceneNode(f32 radius, s32 polyCount, ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CSphereSceneNode(radius, polyCount, polyCount, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! adds a scene node for rendering a static mesh +//! the returned pointer must not be dropped. +IMeshSceneNode* CSceneManager::addMeshSceneNode(IMesh* mesh, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + IMeshSceneNode* node = new CMeshSceneNode(mesh, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a scene node for rendering a animated water surface mesh. +ISceneNode* CSceneManager::addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 waveLength, + ISceneNode* parent, s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!mesh) + return 0; + + if (!parent) + parent = this; + + ISceneNode* node = new CWaterSurfaceSceneNode(waveHeight, waveSpeed, waveLength, + mesh, parent, this, id, position, rotation, scale); + + node->drop(); + + return node; +} + + + +//! adds a scene node for rendering an animated mesh model +IAnimatedMeshSceneNode* CSceneManager::addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + IAnimatedMeshSceneNode* node = + new CAnimatedMeshSceneNode(mesh, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a scene node for rendering using a octtree to the scene graph. This a good method for rendering +//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much +//! faster then a bsp tree. +ISceneNode* CSceneManager::addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, + s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && (!mesh || !mesh->getFrameCount())) + return 0; + + return addOctTreeSceneNode(mesh ? mesh->getMesh(0) : 0, + parent, id, minimalPolysPerNode, + alsoAddIfMeshPointerZero); +} + + + +//! Adss a scene node for rendering using a octtree. This a good method for rendering +//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much +//! faster then a bsp tree. +ISceneNode* CSceneManager::addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent, + s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + COctTreeSceneNode* node = new COctTreeSceneNode(parent, this, id, minimalPolysPerNode); + + if (mesh) + node->createTree(mesh); + + node->drop(); + + return node; +} + + +//! Adds a camera scene node to the tree and sets it as active camera. +//! \param position: Position of the space relative to its parent where the camera will be placed. +//! \param lookat: Position where the camera will look at. Also known as target. +//! \param parent: Parent scene node of the camera. Can be null. If the parent moves, +//! the camera will move too. +//! \return Returns pointer to interface to camera +ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent, + const core::vector3df& position, const core::vector3df& lookat, s32 id) +{ + if (!parent) + parent = this; + + ICameraSceneNode* node = new CCameraSceneNode(parent, this, id, position, lookat); + node->drop(); + + setActiveCamera(node); + + return node; +} + + + +//! Adds a camera scene node which is able to be controlle with the mouse similar +//! like in the 3D Software Maya by Alias Wavefront. +//! The returned pointer must not be dropped. +ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent, + f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id) +{ + if (!parent) + parent = this; + + ICameraSceneNode* node = new CCameraMayaSceneNode(parent, this, id, rotateSpeed, + zoomSpeed, translationSpeed); + node->drop(); + + setActiveCamera(node); + + return node; +} + + + +//! Adds a camera scene node which is able to be controled with the mouse and keys +//! like in most first person shooters (FPS): +ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent, + f32 rotateSpeed, f32 moveSpeed, s32 id, + SKeyMap* keyMapArray, s32 keyMapSize, bool noVerticalMovement,f32 jumpSpeed) +{ + if (!parent) + parent = this; + + ICameraSceneNode* node = new CCameraFPSSceneNode(parent, this, CursorControl, + id, rotateSpeed, moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement); + node->drop(); + + setActiveCamera(node); + + return node; +} + + + +//! Adds a dynamic light scene node. The light will cast dynamic light on all +//! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING +//! turned on. (This is the default setting in most scene nodes). +ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent, + const core::vector3df& position, video::SColorf color, f32 range, s32 id) +{ + if (!parent) + parent = this; + + ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range); + node->drop(); + + return node; +} + + + +//! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element, +//! which always looks to the camera. It is usually used for things like explosions, fire, +//! lensflares and things like that. +IBillboardSceneNode* CSceneManager::addBillboardSceneNode(ISceneNode* parent, + const core::dimension2d& size, const core::vector3df& position, s32 id, + video::SColor shade_top, video::SColor shade_down + ) +{ + if (!parent) + parent = this; + + IBillboardSceneNode* node = new CBillboardSceneNode(parent, this, id, position, size, + shade_top, shade_down); + node->drop(); + + return node; +} + + + +//! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and +//! is drawn around the camera position. +ISceneNode* CSceneManager::addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CSkyBoxSceneNode(top, bottom, left, right, + front, back, parent, this, id); + + node->drop(); + return node; +} + + +//! Adds a skydome scene node. A skydome is a large (half-) sphere with a +//! panoramic texture on it and is drawn around the camera position. +ISceneNode* CSceneManager::addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes, u32 vertRes, f64 texturePercentage, + f64 spherePercentage, ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CSkyDomeSceneNode(texture, horiRes, vertRes, + texturePercentage, spherePercentage, parent, this, id); + + node->drop(); + return node; +} + + +//! Adds a particle system scene node. +IParticleSystemSceneNode* CSceneManager::addParticleSystemSceneNode( + bool withDefaultEmitter, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) +{ + if (!parent) + parent = this; + + IParticleSystemSceneNode* node = new CParticleSystemSceneNode(withDefaultEmitter, + parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNode( + const char* heightMapFileName, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 smoothFactor, + bool addAlsoIfHeightmapEmpty) +{ + io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName); + + ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id, + position, rotation, scale, vertexColor, maxLOD, patchSize, + smoothFactor, addAlsoIfHeightmapEmpty); + + if (file) + file->drop(); + + return terrain; +} + +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNode( + io::IReadFile* heightMapFile, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, + s32 smoothFactor, + bool addAlsoIfHeightmapEmpty) +{ + if (!parent) + parent = this; + + if (!heightMapFile && !addAlsoIfHeightmapEmpty) + { + os::Printer::log("Could not load terrain, because file could not be opened.", + heightMapFile->getFileName(), ELL_ERROR); + return 0; + } + + CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, FileSystem, id, + maxLOD, patchSize, position, rotation, scale); + + if (!node->loadHeightMap(heightMapFile, vertexColor, smoothFactor)) + { + if (!addAlsoIfHeightmapEmpty) + { + node->remove(); + node->drop(); + return 0; + } + } + + node->drop(); + return node; +} + + +//! Adds an empty scene node. +ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CEmptySceneNode(parent, this, id); + node->drop(); + + return node; +} + + +//! Adds a dummy transformation scene node to the scene graph. +IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode( + ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + IDummyTransformationSceneNode* node = new CDummyTransformationSceneNode( + parent, this, id); + node->drop(); + + return node; +} + +//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly +//! and looks like a plane with some hills on it. It is uses mostly for quick +//! tests of the engine only. You can specify how many hills there should be +//! on the plane and how high they should be. Also you must specify a name for +//! the mesh, because the mesh is added to the mesh pool, and can be retrieved +//! again using ISceneManager::getMesh with the name as parameter. +IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name, + const core::dimension2d& tileSize, + const core::dimension2d& tileCount, + video::SMaterial* material, f32 hillHeight, + const core::dimension2d& countHills, + const core::dimension2d& textureRepeatCount) +{ + if (!name || MeshCache->isMeshLoaded(name)) + return 0; + + IMesh* mesh = CGeometryCreator::createHillPlaneMesh(tileSize, + tileCount, material, hillHeight, countHills, + textureRepeatCount); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + return 0; + + animatedMesh->addMesh(mesh); + animatedMesh->recalculateBoundingBox(); + mesh->drop(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + +//! Adds a terrain mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name, + video::IImage* texture, video::IImage* heightmap, + const core::dimension2d& stretchSize, + f32 maxHeight, + const core::dimension2d& defaultVertexBlockSize) +{ + if (!name || MeshCache->isMeshLoaded(name)) + return 0; + + IMesh* mesh = CGeometryCreator::createTerrainMesh(texture, heightmap, + stretchSize, maxHeight, getVideoDriver(), + defaultVertexBlockSize); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + return 0; + + animatedMesh->addMesh(mesh); + animatedMesh->recalculateBoundingBox(); + mesh->drop(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + +//! Adds an arrow mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name, + video::SColor vtxColor0, video::SColor vtxColor1, + u32 tesselationCylinder, u32 tesselationCone, f32 height, + f32 cylinderHeight, f32 width0,f32 width1) +{ + if (!name || MeshCache->isMeshLoaded(name)) + return 0; + + IMesh* mesh = CGeometryCreator::createArrowMesh( tesselationCylinder, + tesselationCone, height, cylinderHeight, width0,width1, + vtxColor0, vtxColor1); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + return 0; + + animatedMesh->addMesh(mesh); + animatedMesh->recalculateBoundingBox(); + mesh->drop(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + + +//! Adds a static sphere mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name, + f32 radius, u32 polyCountX, u32 polyCountY) +{ + if (!name || MeshCache->isMeshLoaded(name)) + return 0; + + IMesh* mesh = CGeometryCreator::createSphereMesh( radius, polyCountX, polyCountY); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + return 0; + + animatedMesh->addMesh(mesh); + animatedMesh->recalculateBoundingBox(); + mesh->drop(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + + +//! Returns the root scene node. This is the scene node wich is parent +//! of all scene nodes. The root scene node is a special scene node which +//! only exists to manage all scene nodes. It is not rendered and cannot +//! be removed from the scene. +//! \return Returns a pointer to the root scene node. +ISceneNode* CSceneManager::getRootSceneNode() +{ + return this; +} + + + +//! Returns the current active camera. +//! \return The active camera is returned. Note that this can be NULL, if there +//! was no camera created yet. +ICameraSceneNode* CSceneManager::getActiveCamera() +{ + return ActiveCamera; +} + + + +//! Sets the active camera. The previous active camera will be deactivated. +//! \param camera: The new camera which should be active. +void CSceneManager::setActiveCamera(ICameraSceneNode* camera) +{ + if (ActiveCamera) + ActiveCamera->drop(); + + ActiveCamera = camera; + + if (ActiveCamera) + ActiveCamera->grab(); +} + + + + +//! renders the node. +void CSceneManager::render() +{ +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSceneManager::getBoundingBox() const +{ + _IRR_DEBUG_BREAK_IF(true) // Bounding Box of Scene Manager wanted. + + // should never be used. + return *((core::aabbox3d*)0); +} + + + +//! returns if node is culled +bool CSceneManager::isCulled(const ISceneNode* node) +{ + const ICameraSceneNode* cam = getActiveCamera(); + if (!cam) + return false; + + switch ( node->getAutomaticCulling() ) + { + // can be seen by a bounding box ? + case scene::EAC_BOX: + { + core::aabbox3d tbox = node->getBoundingBox(); + node->getAbsoluteTransformation().transformBox(tbox); + return !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() )); + } + + // can be seen by a bounding sphere + case scene::EAC_FRUSTUM_SPHERE: + { // requires bbox diameter + } + break; + + // can be seen by cam pyramid planes ? + case scene::EAC_FRUSTUM_BOX: + { + SViewFrustum frust = *cam->getViewFrustum(); + + //transform the frustum to the node's current absolute transformation + core::matrix4 invTrans(node->getAbsoluteTransformation()); + invTrans.makeInverse(); + frust.transform(invTrans); + + core::vector3df edges[8]; + node->getBoundingBox().getEdges(edges); + + for (s32 i=0; igetMaterialCount(); + + taken = 0; + for (u32 i=0; igetMaterialRenderer(node->getMaterial(i).MaterialType); + if (rnd && rnd->isTransparent()) + { + // register as transparent node + TransparentNodeEntry e(node, camWorldPos); + TransparentNodeList.push_back(e); + taken = 1; + break; + } + } + + // not transparent, register as solid + if ( 0 == taken ) + { + SolidNodeList.push_back( node ); + taken = 1; + } + } + break; + case ESNRP_SHADOW: + if (!isCulled(node)) + { + ShadowNodeList.push_back(node); + taken = 1; + } + break; + case ESNRP_SHADER_0: + case ESNRP_SHADER_1: + case ESNRP_SHADER_2: + case ESNRP_SHADER_3: + case ESNRP_SHADER_4: + case ESNRP_SHADER_5: + case ESNRP_SHADER_6: + case ESNRP_SHADER_7: + case ESNRP_SHADER_8: + case ESNRP_SHADER_9: + case ESNRP_SHADER_10: + if ( !isCulled(node) ) + { + ShaderNodeList[ time - ESNRP_SHADER_0].push_back( ShaderNodeEntry ( node,time - ESNRP_SHADER_0 )); + taken = 1; + } break; + + case ESNRP_COUNT: // ignore this one + break; + } + +#ifdef SCENEMANAGER_DEBUG + s32 index = Parameters.findAttribute ( "calls" ); + Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 ); + + if ( 0 == taken ) + { + index = Parameters.findAttribute ( "culled" ); + Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 ); + } +#endif + + return taken; +} + +//! This method is called just before the rendering process of the whole scene. +//! draws all scene nodes +void CSceneManager::drawAll() +{ + if (!Driver) + return; + + // reset attributes + Parameters.setAttribute ( "culled", 0 ); + Parameters.setAttribute ( "calls", 0 ); + Parameters.setAttribute ( "drawn", 0 ); + + // reset all transforms + video::IVideoDriver* driver = getVideoDriver(); + if ( driver ) + { + core::matrix4 identity; + driver->setTransform ( video::ETS_PROJECTION, identity ); + driver->setTransform ( video::ETS_VIEW, identity ); + driver->setTransform ( video::ETS_WORLD, identity ); + driver->setTransform ( video::ETS_TEXTURE_0, identity ); + driver->setTransform ( video::ETS_TEXTURE_1, identity ); + driver->setTransform ( video::ETS_TEXTURE_2, identity ); + driver->setTransform ( video::ETS_TEXTURE_3, identity ); + } + + // do animations and other stuff. + OnAnimate(os::Timer::getTime()); + + /*! + First Scene Node for prerendering should be the active camera + consistent Camera is needed for culling + */ + camWorldPos.set(0,0,0); + if ( ActiveCamera ) + { + ActiveCamera->OnRegisterSceneNode(); + camWorldPos = ActiveCamera->getAbsolutePosition(); + } + + // let all nodes register themselves + OnRegisterSceneNode(); + + u32 i; // new ISO for scoping problem in some compilers + + //render camera scenes + { + CurrentRendertime = ESNRP_CAMERA; + for (i=0; irender(); + + CameraList.set_used(0); + } + + //render lights scenes + { + CurrentRendertime = ESNRP_LIGHT; + + Driver->deleteAllDynamicLights(); + + Driver->setAmbientLight(AmbientLight); + + LightList.sort (); // on distance to camera + + u32 maxLights = core::min_ ( Driver->getMaximalDynamicLightAmount (), LightList.size () ); + for (i=0; i< maxLights; ++i) + LightList[i].node->render(); + + LightList.set_used(0); + } + + // render skyboxes + { + CurrentRendertime = ESNRP_SKY_BOX; + + for (i=0; irender(); + + SkyBoxList.set_used(0); + } + + + // render default objects + { + CurrentRendertime = ESNRP_SOLID; + SolidNodeList.sort(); // sort by textures + + for (i=0; irender(); + + Parameters.setAttribute ( "drawn", (s32) SolidNodeList.size () ); + + SolidNodeList.set_used(0); + } + + // render shadows + { + CurrentRendertime = ESNRP_SHADOW; + for (i=0; irender(); + + if (!ShadowNodeList.empty()) + Driver->drawStencilShadow(true,ShadowColor, ShadowColor, + ShadowColor, ShadowColor); + + ShadowNodeList.set_used(0); + } + + // render transparent objects. + { + CurrentRendertime = ESNRP_TRANSPARENT; + TransparentNodeList.sort(); // sort by distance from camera + + for (i=0; irender(); + + TransparentNodeList.set_used(0); + } + + // render shader objects. + { + for ( u32 g = 0; g!= ESNRP_SHADER_10 - ESNRP_SHADER_0 + 1; ++g ) + { + CurrentRendertime = (scene::E_SCENE_NODE_RENDER_PASS) (ESNRP_SHADER_0 + g); + + const u32 size = ShaderNodeList[g].size (); + if ( 0 == size ) + continue; + + ShaderNodeList[g].sort(); // sort by textures + for (i=0; i< size; ++i) + ShaderNodeList[g][i].node->render(); + + ShaderNodeList[g].set_used(0); + } + } + + clearDeletionList(); + + CurrentRendertime = ESNRP_COUNT; +} + + +//! Sets the color of stencil buffers shadows drawn by the scene manager. +void CSceneManager::setShadowColor(video::SColor color) +{ + ShadowColor = color; +} + + +//! Returns the current color of shadows. +video::SColor CSceneManager::getShadowColor() const +{ + return ShadowColor; +} + + + +//! creates a rotation animator, which rotates the attached scene node around itself. +ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotation(os::Timer::getTime(), + rotationPerSecond); + + return anim; +} + + + +//! creates a fly circle animator, which lets the attached scene node fly around a center. +ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator( + const core::vector3df& normal, f32 radius, f32 speed, + const core::vector3df& direction) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(os::Timer::getTime(), normal, + radius, speed, direction); + return anim; +} + + +//! Creates a fly straight animator, which lets the attached scene node +//! fly or move along a line between two points. +ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint, + endPoint, timeForWay, loop, os::Timer::getTime()); + + return anim; +} + + +//! Creates a texture animator, which switches the textures of the target scene +//! node based on a list of textures. +ISceneNodeAnimator* CSceneManager::createTextureAnimator(const core::array& textures, + s32 timePerFrame, bool loop) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorTexture(textures, + timePerFrame, loop, os::Timer::getTime()); + + return anim; +} + + +//! Creates a scene node animator, which deletes the scene node after +//! some time automaticly. +ISceneNodeAnimator* CSceneManager::createDeleteAnimator(u32 when) +{ + return new CSceneNodeAnimatorDelete(this, os::Timer::getTime() + when); +} + + + + +//! Creates a special scene node animator for doing automatic collision detection +//! and response. +ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius, + const core::vector3df& gravityPerSecond, + const core::vector3df& ellipsoidTranslation, f32 slidingValue) +{ + ISceneNodeAnimatorCollisionResponse* anim = new + CSceneNodeAnimatorCollisionResponse(this, world, sceneNode, + ellipsoidRadius, gravityPerSecond, + ellipsoidTranslation, slidingValue); + + return anim; +} + + +//! Creates a follow spline animator. +ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed, f32 tightness) +{ + ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points, + speed, tightness); + return a; +} + + + +//! Adds an external mesh loader. +void CSceneManager::addExternalMeshLoader(IMeshLoader* externalLoader) +{ + if (!externalLoader) + return; + + externalLoader->grab(); + MeshLoaderList.push_back(externalLoader); +} + + + +//! Returns a pointer to the scene collision manager. +ISceneCollisionManager* CSceneManager::getSceneCollisionManager() +{ + return CollisionManager; +} + + +//! Returns a pointer to the mesh manipulator. +IMeshManipulator* CSceneManager::getMeshManipulator() +{ + return MeshManipulator; +} + + +//! Creates a simple ITriangleSelector, based on a mesh. +ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node) +{ + if (!mesh || !node) + return 0; + + return new CTriangleSelector(mesh, node); +} + + +//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. +ITriangleSelector* CSceneManager::createTriangleSelectorFromBoundingBox(ISceneNode* node) +{ + if (!node) + return 0; + + return new CTriangleBBSelector(node); +} + + +//! Creates a simple ITriangleSelector, based on a mesh. +ITriangleSelector* CSceneManager::createOctTreeTriangleSelector(IMesh* mesh, + ISceneNode* node, + s32 minimalPolysPerNode) +{ + if (!mesh || !node) + return 0; + + return new COctTreeTriangleSelector(mesh, node, minimalPolysPerNode); +} + + + +//! Creates a meta triangle selector. +IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector() +{ + return new CMetaTriangleSelector(); +} + + + +//! Creates a triangle selector which can select triangles from a terrain scene node +ITriangleSelector* CSceneManager::createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD) +{ + return new CTerrainTriangleSelector(node, LOD); +} + + + +//! Adds a scene node to the deletion queue. +void CSceneManager::addToDeletionQueue(ISceneNode* node) +{ + if (!node) + return; + + node->grab(); + DeletionList.push_back(node); +} + + +//! clears the deletion list +void CSceneManager::clearDeletionList() +{ + if (DeletionList.empty()) + return; + + for (s32 i=0; i<(s32)DeletionList.size(); ++i) + { + DeletionList[i]->remove(); + DeletionList[i]->drop(); + } + + DeletionList.clear(); +} + + +//! Returns the first scene node with the specified name. +ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (!strcmp(start->getName(),name)) + return start; + + ISceneNode* node = 0; + + const core::list& list = start->getChildren(); + core::list::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromName(name, *it); + if (node) + return node; + } + + return 0; +} + + +//! Returns the first scene node with the specified id. +ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getID() == id) + return start; + + ISceneNode* node = 0; + + const core::list& list = start->getChildren(); + core::list::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromId(id, *it); + if (node) + return node; + } + + return 0; +} + + +//! Returns the first scene node with the specified type. +ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getType() == type) + return start; + + ISceneNode* node = 0; + + const core::list& list = start->getChildren(); + core::list::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromType(type, *it); + if (node) + return node; + } + + return 0; +} + +//! returns scene nodes by type. +void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getType() == type) + outNodes.push_back(start); + + const core::list& list = start->getChildren(); + core::list::ConstIterator it = list.begin(); + + for (; it!=list.end(); ++it) + { + getSceneNodesFromType(type, outNodes, *it); + } +} + + +//! Posts an input event to the environment. Usually you do not have to +//! use this method, it is used by the internal engine. +bool CSceneManager::postEventFromUser(const SEvent& event) +{ + bool ret = false; + ICameraSceneNode* cam = getActiveCamera(); + if (cam) + ret = cam->OnEvent(event); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Removes all children of this scene node +void CSceneManager::removeAll() +{ + ISceneNode::removeAll(); + setActiveCamera(0); +} + + +//! Clears the whole scene. All scene nodes are removed. +void CSceneManager::clear() +{ + removeAll(); +} + + +//! Returns interface to the parameters set in this scene. +io::IAttributes* CSceneManager::getParameters() +{ + return &Parameters; +} + + +//! Returns current render pass. +E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const +{ + return CurrentRendertime; +} + + + +//! Returns an interface to the mesh cache which is shared beween all existing scene managers. +IMeshCache* CSceneManager::getMeshCache() +{ + return MeshCache; +} + + +//! Creates a new scene manager. +ISceneManager* CSceneManager::createNewSceneManager(bool cloneContent) +{ + CSceneManager* manager = new CSceneManager(Driver, FileSystem, CursorControl, MeshCache); + + if (cloneContent) + manager->cloneMembers(this, manager); + + return manager; +} + + +//! Returns the default scene node factory which can create all built in scene nodes +ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory() +{ + return getSceneNodeFactory(0); +} + + +//! Adds a scene node factory to the scene manager. +void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) +{ + if (factoryToAdd) + { + factoryToAdd->grab(); + SceneNodeFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node factories. +u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const +{ + return SceneNodeFactoryList.size(); +} + + +//! Returns a scene node factory by index +ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index) +{ + if (indexgrab(); + SceneNodeAnimatorFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node animator factories. +u32 CSceneManager::getRegisteredSceneNodeAnimatorFactoryCount() const +{ + return SceneNodeAnimatorFactoryList.size(); +} + + +//! Returns a scene node animator factory by index +ISceneNodeAnimatorFactory* CSceneManager::getSceneNodeAnimatorFactory(u32 index) +{ + if (indexcreateAndWriteFile(filename); + if (!file) + return false; + + bool ret = saveScene(file, userDataSerializer); + file->drop(); + return ret; +} + + +//! Saves the current scene into a file. +bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer) +{ + if (!file) + return false; + + io::IXMLWriter* writer = FileSystem->createXMLWriter(file); + if (!writer) + return false; + + writer->writeXMLHeader(); + writeSceneNode(writer, this, userDataSerializer); + writer->drop(); + + return true; +} + + +//! Loads a scene. Note that the current scene is not cleared before. +//! \param filename: Name of the file . +bool CSceneManager::loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer) +{ + io::IReadFile* read = FileSystem->createAndOpenFile(filename); + if (!read) + { + os::Printer::log("Unable to open scene file", filename, ELL_ERROR); + return false; + } + + bool ret = loadScene(read, userDataSerializer); + read->drop(); + + return ret; +} + + +//! Loads a scene. Note that the current scene is not cleared before. +bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer) +{ + if (!file) + { + os::Printer::log("Unable to open scene file", ELL_ERROR); + return false; + } + + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + { + os::Printer::log("Scene is not a valid XML file", file->getFileName(), ELL_ERROR); + return false; + } + + // for mesh loading, set collada loading attributes + + bool oldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES); + getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false); + + // read file + + while(reader->read()) + { + readSceneNode(reader, 0, userDataSerializer); + } + + // restore old collada parameters + + getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh); + + // finish up + + reader->drop(); + return true; + +} + + +//! reads a scene node +void CSceneManager::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, ISceneUserDataSerializer* userDataSerializer) +{ + if (!reader) + return; + + scene::ISceneNode* node = 0; + + if ((!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName()) || + ( parent && IRR_XML_FORMAT_NODE==reader->getNodeName())) + { + if (parent) + { + // find node type and create it + core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str()); + + for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i) + node = SceneNodeFactoryList[i]->addSceneNode(attrName.c_str(), parent); + + if (!node) + os::Printer::log("Could not create scene node of unknown type", attrName.c_str()); + } + else + node = this; // root + } + + // read attributes + while(reader->read()) + { + bool endreached = false; + + switch (reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) || + (IRR_XML_FORMAT_SCENE==reader->getNodeName())) + { + endreached = true; + } + break; + case io::EXN_ELEMENT: + if (core::stringw(L"attributes")==reader->getNodeName()) + { + // read attributes + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader, true); + + if (node) + node->deserializeAttributes(attr); + + attr->drop(); + } + else + if (core::stringw(L"materials")==reader->getNodeName()) + readMaterials(reader, node); + else + if (core::stringw(L"animators")==reader->getNodeName()) + readAnimators(reader, node); + else + if (core::stringw(L"userData")==reader->getNodeName()) + readUserData(reader, node, userDataSerializer); + else + if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) || + (IRR_XML_FORMAT_SCENE==reader->getNodeName())) + { + readSceneNode(reader, node, userDataSerializer); + } + else + { + os::Printer::log("Found unknown element in irrlicht scene file", + core::stringc(reader->getNodeName()).c_str()); + } + break; + default: + break; + } + + if (endreached) + break; + } +} + + +//! reads materials of a node +void CSceneManager::readMaterials(io::IXMLReader* reader, ISceneNode* node) +{ + u32 nr = 0; + + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (core::stringw(L"materials")==name) + return; + break; + case io::EXN_ELEMENT: + if (core::stringw(L"attributes")==name) + { + // read materials from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader); + + if (node && node->getMaterialCount() > nr) + { + getVideoDriver()->fillMaterialStructureFromAttributes( + node->getMaterial(nr), attr); + } + + attr->drop(); + ++nr; + } + break; + default: + break; + } + } +} + + +//! reads animators of a node +void CSceneManager::readAnimators(io::IXMLReader* reader, ISceneNode* node) +{ + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (core::stringw(L"animators")==name) + return; + break; + case io::EXN_ELEMENT: + if (core::stringw(L"attributes")==name) + { + // read animator data from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader); + + if (node) + { + core::stringc typeName = attr->getAttributeAsString("Type"); + ISceneNodeAnimator* anim = 0; + + for (int i=0; i<(int)SceneNodeAnimatorFactoryList.size() && !anim; ++i) + anim = SceneNodeAnimatorFactoryList[i]->createSceneNodeAnimator(typeName.c_str(), node); + + if (anim) + { + anim->deserializeAttributes(attr); + anim->drop(); + } + } + + attr->drop(); + } + break; + default: + break; + } + } +} + + +//! reads user data of a node +void CSceneManager::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer) +{ + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (core::stringw(L"userData")==name) + return; + break; + case io::EXN_ELEMENT: + if (core::stringw(L"attributes")==name) + { + // read user data from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader); + + if (node && userDataSerializer) + { + userDataSerializer->OnReadUserData(node, attr); + } + + attr->drop(); + } + break; + default: + break; + } + } +} + + +//! writes a scene node +void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer) +{ + if (!writer || !node || node->isDebugObject()) + return; + + const wchar_t* name; + + if (node == this) + { + name = IRR_XML_FORMAT_SCENE.c_str(); + writer->writeElement(name, false); + } + else + { + name = IRR_XML_FORMAT_NODE.c_str(); + writer->writeElement(name, false, IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str(), + core::stringw(getSceneNodeTypeName(node->getType())).c_str()); + } + + writer->writeLineBreak(); + writer->writeLineBreak(); + + // write properties + + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + node->serializeAttributes(attr); + + if (attr->getAttributeCount() != 0) + { + attr->write(writer); + writer->writeLineBreak(); + } + + // write materials + + if (node->getMaterialCount() && getVideoDriver()) + { + const wchar_t* materialElement = L"materials"; + + writer->writeElement(materialElement); + writer->writeLineBreak(); + + for (u32 i=0; i < node->getMaterialCount(); ++i) + { + io::IAttributes* tmp_attr = + getVideoDriver()->createAttributesFromMaterial(node->getMaterial(i)); + tmp_attr->write(writer); + tmp_attr->drop(); + } + + writer->writeClosingTag(materialElement); + writer->writeLineBreak(); + } + + // write animators + + if (!node->getAnimators().empty()) + { + const wchar_t* animatorElement = L"animators"; + writer->writeElement(animatorElement); + writer->writeLineBreak(); + + core::list::ConstIterator it = node->getAnimators().begin(); + for (; it != node->getAnimators().end(); ++it) + { + attr->clear(); + attr->addString("Type", getAnimatorTypeName((*it)->getType())); + + (*it)->serializeAttributes(attr); + + attr->write(writer); + } + + writer->writeClosingTag(animatorElement); + writer->writeLineBreak(); + } + + // write possible user data + + if ( userDataSerializer ) + { + io::IAttributes* userData = userDataSerializer->createUserData(node); + if (userData) + { + const wchar_t* userDataElement = L"userData"; + + writer->writeLineBreak(); + writer->writeElement(userDataElement); + writer->writeLineBreak(); + + userData->write(writer); + + writer->writeClosingTag(userDataElement); + writer->writeLineBreak(); + writer->writeLineBreak(); + + userData->drop(); + } + } + + // write children + + core::list::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); ++it) + writeSceneNode(writer, (*it), userDataSerializer); + + attr->drop(); + + writer->writeClosingTag(name); + writer->writeLineBreak(); + writer->writeLineBreak(); +} + + +//! Returns a typename from a scene node type or null if not found +const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type) +{ + const char* name = 0; + + for (int i=(int)SceneNodeFactoryList.size()-1; !name && i>=0; --i) + name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type); + + return name; +} + +//! Adds a scene node to the scene by name +ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent) +{ + ISceneNode* node = 0; + + for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i) + node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent); + + return node; +} + + +//! Returns a typename from a scene node animator type or null if not found +const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const +{ + const char* name = 0; + + for (u32 i=0; !name && igetCreateableSceneNodeAnimatorTypeName(type); + + return name; +} + + +//! Writes attributes of the scene node. +void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addString ("Name", Name.c_str()); + out->addInt ("Id", ID ); + out->addColorf ("AmbientLight", AmbientLight); +} + +//! Reads attributes of the scene node. +void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Name = in->getAttributeAsString("Name"); + ID = in->getAttributeAsInt("Id"); + AmbientLight = in->getAttributeAsColorf("AmbientLight"); + + RelativeTranslation.set(0,0,0); + RelativeRotation.set(0,0,0); + RelativeScale.set(1,1,1); + IsVisible = true; + AutomaticCullingState = scene::EAC_BOX; + DebugDataVisible = scene::EDS_OFF; + IsDebugObject = false; + + updateAbsolutePosition(); +} + + +//! Sets ambient color of the scene +void CSceneManager::setAmbientLight(const video::SColorf &ambientColor) +{ + AmbientLight = ambientColor; +} + + +//! Returns ambient color of the scene +const video::SColorf& CSceneManager::getAmbientLight() const +{ + return AmbientLight; +} + + +//! Returns a mesh writer implementation if available +IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type) +{ + switch(type) + { + case EMWT_IRR_MESH: +#ifdef _IRR_COMPILE_WITH_IRR_WRITER_ + return new CIrrMeshWriter(Driver, FileSystem); +#else + return 0; +#endif + case EMWT_COLLADA: +#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_ + return new CColladaMeshWriter(Driver, FileSystem); +#else + return 0; +#endif + case EMWT_STL: +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ + return new CSTLMeshWriter(this); +#else + return 0; +#endif + } + + return 0; +} + + +// creates a scenemanager +ISceneManager* createSceneManager(video::IVideoDriver* driver, + io::IFileSystem* fs, gui::ICursorControl* cursorcontrol, + gui::IGUIEnvironment *guiEnvironment) +{ + return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment ); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneManager.h b/src/dep/src/irrlicht/CSceneManager.h new file mode 100644 index 0000000..153282c --- /dev/null +++ b/src/dep/src/irrlicht/CSceneManager.h @@ -0,0 +1,615 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_MANAGER_H_INCLUDED__ +#define __C_SCENE_MANAGER_H_INCLUDED__ + +#include "ISceneManager.h" +#include "ISceneNode.h" +#include "ICursorControl.h" +#include "irrString.h" +#include "irrArray.h" +#include "IMeshLoader.h" +#include "CAttributes.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; + class IFileSystem; +} +namespace scene +{ + class IMeshCache; + + /*! + The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff. + */ + class CSceneManager : public ISceneManager, public ISceneNode + { + public: + + //! constructor + CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, + gui::ICursorControl* cursorControl, IMeshCache* cache = 0, + gui::IGUIEnvironment *guiEnvironment = 0); + + //! destructor + virtual ~CSceneManager(); + + //! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. + virtual IAnimatedMesh* getMesh(const c8* filename); + + //! Returns an interface to the mesh cache which is shared beween all existing scene managers. + virtual IMeshCache* getMeshCache(); + + //! returns the video driver + virtual video::IVideoDriver* getVideoDriver(); + + virtual gui::IGUIEnvironment* getGUIEnvironment(); + + //! adds a cube scene node to the scene. It is a simple cube of (1,1,1) size. + //! the returned pointer must not be dropped. + virtual ISceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), const core::vector3df& rotation = core::vector3df(0,0,0), const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! Adds a sphere scene node to the scene. + virtual ISceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! adds a scene node for rendering an animated mesh model + virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false); + + //! adds a scene node for rendering a static mesh + //! the returned pointer must not be dropped. + virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false); + + //! Adds a scene node for rendering a animated water surface mesh. + virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 wlenght, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! registers a node for rendering it at a specific time. + virtual u32 registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS = ESNRP_AUTOMATIC); + + //! draws all scene nodes + virtual void drawAll(); + + //! Adds a scene node for rendering using a octtree to the scene graph. This a good method for rendering + //! scenes with lots of geometry. The Octree is built on the fly from the mesh, much + //! faster then a bsp tree. + virtual ISceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=128, bool alsoAddIfMeshPointerZero=false); + + //! Adss a scene node for rendering using a octtree. This a good method for rendering + //! scenes with lots of geometry. The Octree is built on the fly from the mesh, much + //! faster then a bsp tree. + virtual ISceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=128, bool alsoAddIfMeshPointerZero=false); + + //! Adds a camera scene node to the tree and sets it as active camera. + //! \param position: Position of the space relative to its parent where the camera will be placed. + //! \param lookat: Position where the camera will look at. Also known as target. + //! \param parent: Parent scene node of the camera. Can be null. If the parent moves, + //! the camera will move too. + //! \return Returns pointer to interface to camera + virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,0), s32 id=-1); + + //! Adds a camera scene node which is able to be controlle with the mouse similar + //! like in the 3D Software Maya by Alias Wavefront. + //! The returned pointer must not be dropped. + virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent = 0, + f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f, f32 translationSpeed = 100.0f, s32 id=-1); + + //! Adds a camera scene node which is able to be controled with the mouse and keys + //! like in most first person shooters (FPS): + virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0, + f32 rotateSpeed = 1500.0f, f32 moveSpeed = 200.0f, s32 id=-1, + SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false, + f32 jumpSpeed = 0.f); + + //! Adds a dynamic light scene node. The light will cast dynamic light on all + //! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING + //! turned on. (This is the default setting in most scene nodes). + virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), f32 range=100.0f, s32 id=-1); + + //! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element, + //! which always looks to the camera. It is usually used for things like explosions, fire, + //! lensflares and things like that. + virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF); + + //! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and + //! is drawn around the camera position. + virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent = 0, s32 id=-1); + + //! Adds a skydome scene node. A skydome is a large (half-) sphere with a + //! panoramic texture on it and is drawn around the camera position. + virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes, u32 vertRes, f64 texturePercentage, + f64 spherePercentage, ISceneNode* parent=0, s32 id=-1); + + //! Adds a text scene node, which is able to display + //! 2d text at a position in three dimensional space + virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + video::SColor color=video::SColor(100,255,255,255), + ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0), + s32 id=-1); + + //! Adds a text scene node, which uses billboards + virtual ITextSceneNode* addBillboardTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF); + + //! Adds a scene node, which can render a quake3 shader + virtual ISceneNode* addQuake3SceneNode(IMeshBuffer* meshBuffer, const quake3::SShader * shader, + ISceneNode* parent=0, s32 id=-1 + ); + + + //! Adds a Hill Plane mesh to the mesh pool. The mesh is + //! generated on the fly and looks like a plane with some hills + //! on it. You can specify how many hills should be on the plane + //! and how high they should be. Also you must specify a name + //! for the mesh because the mesh is added to the mesh pool and + //! can be retrieved back using ISceneManager::getMesh with the + //! name as parameter. + virtual IAnimatedMesh* addHillPlaneMesh(const c8* name, + const core::dimension2d& tileSize, const core::dimension2d& tileCount, + video::SMaterial* material = 0, f32 hillHeight = 0.0f, + const core::dimension2d& countHills = core::dimension2d(1.0f, 1.0f), + const core::dimension2d& textureRepeatCount = core::dimension2d(1.0f, 1.0f)); + + //! Adds a terrain mesh to the mesh pool. + virtual IAnimatedMesh* addTerrainMesh(const c8* meshname, video::IImage* texture, video::IImage* heightmap, + const core::dimension2d& stretchSize, + f32 maxHeight, const core::dimension2d& defaultVertexBlockSize); + + //! Add a arrow mesh to the mesh pool + virtual IAnimatedMesh* addArrowMesh(const c8* name, + video::SColor vtxColor0, video::SColor vtxColor1, + u32 tesselationCylinder, u32 tesselationCone, + f32 height, f32 cylinderHeight, f32 width0, + f32 width1); + + //! Adds a static sphere mesh to the mesh pool. + IAnimatedMesh* addSphereMesh(const c8* name, + f32 radius, u32 polyCountX, u32 polyCountY); + + //! Adds a particle system scene node. + virtual IParticleSystemSceneNode* addParticleSystemSceneNode( + bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNode( + const c8* heightMapFileName, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=4, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false); + + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNode( + io::IReadFile* heightMap, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=4, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty=false); + + //! Adds a dummy transformation scene node to the scene graph. + virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode( + ISceneNode* parent=0, s32 id=-1); + + //! Adds an empty scene node. + virtual ISceneNode* addEmptySceneNode(ISceneNode* parent, s32 id=-1); + + //! Returns the root scene node. This is the scene node wich is parent + //! of all scene nodes. The root scene node is a special scene node which + //! only exists to manage all scene nodes. It is not rendered and cannot + //! be removed from the scene. + //! \return Returns a pointer to the root scene node. + virtual ISceneNode* getRootSceneNode(); + + //! Returns the current active camera. + //! \return The active camera is returned. Note that this can be NULL, if there + //! was no camera created yet. + virtual ICameraSceneNode* getActiveCamera(); + + //! Sets the active camera. The previous active camera will be deactivated. + //! \param camera: The new camera which should be active. + virtual void setActiveCamera(ICameraSceneNode* camera); + + //! creates a rotation animator, which rotates the attached scene node around itself. + //! \param rotationPerSecond: Specifies the speed of the animation + //! \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + //! and the animator will animate it. + virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationPerSecond); + + //! creates a fly circle animator, which lets the attached scene node fly + //! around a center. The center is the position of the scene node. + //! \param rotationSpeed: + //! \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator() + //! and the animator will animate it. + virtual ISceneNodeAnimator* createFlyCircleAnimator(const core::vector3df& normal, f32 radius, f32 speed, + const core::vector3df& direction); + + //! Creates a fly straight animator, which lets the attached scene node + //! fly or move along a line between two points. + virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop=false); + + //! Creates a texture animator, which switches the textures of the target scene + //! node based on a list of textures. + virtual ISceneNodeAnimator* createTextureAnimator(const core::array& textures, + s32 timePerFrame, bool loop); + + //! Creates a scene node animator, which deletes the scene node after + //! some time automaticly. + virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMS); + + + //! Creates a special scene node animator for doing automatic collision detection + //! and response. + virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-1.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingValue = 0.0005f); + + //! Creates a follow spline animator. + virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed = 1.0f, f32 tightness = 0.5f); + + + //! Creates a simple ITriangleSelector, based on a mesh. + virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node); + + //! Creates a simple ITriangleSelector, based on a mesh. + virtual ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode); + + //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. + virtual ITriangleSelector* createTriangleSelectorFromBoundingBox( + ISceneNode* node); + + //! Creates a meta triangle selector. + virtual IMetaTriangleSelector* createMetaTriangleSelector(); + + //! Creates a triangle selector which can select triangles from a terrain scene node + //! \param: Pointer to the created terrain scene node + //! \param: Level of detail, 0 for highest detail. + virtual ITriangleSelector* createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD=0); + + //! Adds an external mesh loader. + virtual void addExternalMeshLoader(IMeshLoader* externalLoader); + + //! Returns a pointer to the scene collision manager. + virtual ISceneCollisionManager* getSceneCollisionManager(); + + //! Returns a pointer to the mesh manipulator. + virtual IMeshManipulator* getMeshManipulator(); + + //! Sets the color of stencil buffers shadows drawn by the scene manager. + virtual void setShadowColor(video::SColor color); + + //! Returns the current color of shadows. + virtual video::SColor getShadowColor() const; + + //! Adds a scene node to the deletion queue. + virtual void addToDeletionQueue(ISceneNode* node); + + //! Returns the first scene node with the specified id. + virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0); + + //! Returns the first scene node with the specified name. + virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0); + + //! Returns the first scene node with the specified type. + virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0); + + //! returns scene nodes by type. + virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start=0); + + //! Posts an input event to the environment. Usually you do not have to + //! use this method, it is used by the internal engine. + virtual bool postEventFromUser(const SEvent& event); + + //! Clears the whole scene. All scene nodes are removed. + virtual void clear(); + + //! Removes all children of this scene node + virtual void removeAll(); + + //! Returns interface to the parameters set in this scene. + virtual io::IAttributes* getParameters(); + + //! Returns current render pass. + virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const; + + //! Creates a new scene manager. + virtual ISceneManager* createNewSceneManager(bool cloneContent); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_UNKNOWN; } + + //! Returns the default scene node factory which can create all built in scene nodes + virtual ISceneNodeFactory* getDefaultSceneNodeFactory(); + + //! Adds a scene node factory to the scene manager. + /** Use this to extend the scene manager with new scene node types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd); + + //! Returns amount of registered scene node factories. + virtual u32 getRegisteredSceneNodeFactoryCount() const; + + //! Returns a scene node factory by index + virtual ISceneNodeFactory* getSceneNodeFactory(u32 index); + + //! Returns a typename from a scene node type or null if not found + virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type); + + //! Adds a scene node to the scene by name + virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent); + + //! Returns the default scene node animator factory which can create all built-in scene node animators + virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory(); + + //! Adds a scene node animator factory to the scene manager. + virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd); + + //! Returns amount of registered scene node animator factories. + virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const; + + //! Returns a scene node animator factory by index + virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index); + + //! Saves the current scene into a file. + //! \param filename: Name of the file . + virtual bool saveScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0); + + //! Saves the current scene into a file. + virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0); + + //! Loads a scene. Note that the current scene is not cleared before. + //! \param filename: Name of the file . + virtual bool loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0); + + //! Loads a scene. Note that the current scene is not cleared before. + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns a mesh writer implementation if available + virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type); + + //! Sets ambient color of the scene + virtual void setAmbientLight(const video::SColorf &ambientColor); + + //! Returns ambient color of the scene + virtual const video::SColorf& getAmbientLight() const; + + private: + + //! Returns a typename from a scene node animator type or null if not found + virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const; + + //! returns if node is culled + bool isCulled(const ISceneNode* node); + + //! clears the deletion list + void clearDeletionList(); + + //! writes a scene node + void writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer); + + //! reads a scene node + void readSceneNode(io::IXMLReader* reader, ISceneNode* parent, ISceneUserDataSerializer* userDataSerializer); + + //! read materials + void readMaterials(io::IXMLReader* reader, ISceneNode* node); + + //! reads animators of a node + void readAnimators(io::IXMLReader* reader, ISceneNode* node); + + //! reads user data of a node + void readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer); + + struct DefaultNodeEntry + { + DefaultNodeEntry() {}; + + DefaultNodeEntry(ISceneNode* n) + { + textureValue = 0; + + if (n->getMaterialCount()) + textureValue = (n->getMaterial(0).getTexture(0)); + + node = n; + } + + ISceneNode* node; + void* textureValue; + + bool operator < (const DefaultNodeEntry& other) const + { + return (textureValue < other.textureValue); + } + }; + + struct ShaderNodeEntry + { + ShaderNodeEntry() {}; + + ShaderNodeEntry(ISceneNode* n, u32 sceneTime ) + { + textureValue = n->getMaterial( sceneTime ).getTexture(0); + + node = n; + } + + ISceneNode* node; + void* textureValue; + + bool operator < (const ShaderNodeEntry& other) const + { + return (textureValue < other.textureValue); + } + }; + + + struct TransparentNodeEntry + { + TransparentNodeEntry() {}; + + TransparentNodeEntry(ISceneNode* n, const core::vector3df &camera) + { + node = n; + + // TODO: this could be optimized, by not using sqrt + distance = (f32)(node->getAbsoluteTransformation().getTranslation().getDistanceFrom(camera)); + } + + ISceneNode* node; + f32 distance; + + bool operator < (const TransparentNodeEntry& other) const + { + return (distance > other.distance); + } + }; + + //! sort on distance (sphere) to camera + struct DistanceNodeEntry + { + DistanceNodeEntry() {}; + + DistanceNodeEntry(ISceneNode* n, f64 d) + { + node = n; + distance = d; + } + + DistanceNodeEntry(ISceneNode* n, const core::vector3df &cameraPos) + { + node = n; + + distance = (node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(cameraPos)); + distance -= node->getBoundingBox().getExtent().getLengthSQ() / 2.0; + } + + ISceneNode* node; + + f64 distance; + + bool operator < (const DistanceNodeEntry& other) const + { + return distance < other.distance; + } + }; + + //! video driver + video::IVideoDriver* Driver; + + //! file system + io::IFileSystem* FileSystem; + + //! GUI Enviroment ( Debug Purpose ) + gui::IGUIEnvironment* GUIEnvironment; + + //! cursor control + gui::ICursorControl* CursorControl; + + //! collision manager + ISceneCollisionManager* CollisionManager; + + //! mesh manipulator + IMeshManipulator* MeshManipulator; + + //! render pass lists + core::array CameraList; + core::array LightList; + core::array ShadowNodeList; + core::array SkyBoxList; + core::array SolidNodeList; + core::array TransparentNodeList; + core::array ShaderNodeList[ ESNRP_SHADER_10 - ESNRP_SHADER_0 + 1]; + + core::array MeshLoaderList; + core::array DeletionList; + core::array SceneNodeFactoryList; + core::array SceneNodeAnimatorFactoryList; + + //! current active camera + ICameraSceneNode* ActiveCamera; + core::vector3df camWorldPos; // Position of camera for transparent nodes. + + video::SColor ShadowColor; + video::SColorf AmbientLight; + + //! String parameters + io::CAttributes Parameters; + + //! Mesh cache + IMeshCache* MeshCache; + + E_SCENE_NODE_RENDER_PASS CurrentRendertime; + + //! constants for reading and writing XML. + //! Not made static due to portability problems. + const core::stringw IRR_XML_FORMAT_SCENE; + const core::stringw IRR_XML_FORMAT_NODE; + const core::stringw IRR_XML_FORMAT_NODE_ATTR_TYPE; + }; + +} // end namespace video +} // end namespace scene + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.cpp new file mode 100644 index 0000000..52a7a4f --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.cpp @@ -0,0 +1,211 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorCollisionResponse.h" +#include "ISceneCollisionManager.h" +#include "ISceneManager.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorCollisionResponse::CSceneNodeAnimatorCollisionResponse( + ISceneManager* scenemanager, + ITriangleSelector* world, ISceneNode* object, + const core::vector3df& ellipsoidRadius, + const core::vector3df& gravityPerSecond, + const core::vector3df& ellipsoidTranslation, + f32 slidingSpeed) +: Radius(ellipsoidRadius), Gravity(gravityPerSecond / 1000.0f), Translation(ellipsoidTranslation), + World(world), Object(object), SceneManager(scenemanager), + SlidingSpeed(slidingSpeed), Falling(false) +{ + if (World) + World->grab(); + + if (Object) + LastPosition = Object->getPosition(); + + LastTime = os::Timer::getTime(); + FallStartTime = LastTime; +} + + + +//! destructor +CSceneNodeAnimatorCollisionResponse::~CSceneNodeAnimatorCollisionResponse() +{ + if (World) + World->drop(); +} + + +//! Returns if the attached scene node is falling, which means that +//! there is no blocking wall from the scene node in the direction of +//! the gravity. +bool CSceneNodeAnimatorCollisionResponse::isFalling() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Falling; +} + + +//! Sets the radius of the ellipsoid with which collision detection and +//! response is done. +void CSceneNodeAnimatorCollisionResponse::setEllipsoidRadius( + const core::vector3df& radius) +{ + Radius = radius; +} + +//! Returns the radius of the ellipsoid with wich the collision detection and +//! response is done. +core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidRadius() const +{ + return Radius; +} + + +//! Sets the gravity of the environment. +void CSceneNodeAnimatorCollisionResponse::setGravity(const core::vector3df& gravity) +{ + Gravity = gravity; +} + + +//! Returns current vector of gravity. +core::vector3df CSceneNodeAnimatorCollisionResponse::getGravity() const +{ + return Gravity; +} + + +//! Sets the translation of the ellipsoid for collision detection. +void CSceneNodeAnimatorCollisionResponse::setEllipsoidTranslation(const core::vector3df &translation) +{ + Translation = translation; +} + + + +//! Returns the translation of the ellipsoid for collision detection. +core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidTranslation() const +{ + return Translation; +} + + +//! Sets a triangle selector holding all triangles of the world with which +//! the scene node may collide. +void CSceneNodeAnimatorCollisionResponse::setWorld(ITriangleSelector* newWorld) +{ + Falling = false; + + LastTime = os::Timer::getTime(); + FallStartTime = LastTime; + + + if (World) + World->drop(); + + World = newWorld; + if (World) + World->grab(); + +} + + + +//! Returns the current triangle selector containing all triangles for +//! collision detection. +ITriangleSelector* CSceneNodeAnimatorCollisionResponse::getWorld() const +{ + return World; +} + + + +void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 timeMs) +{ + if (node != Object) + { + os::Printer::log("CollisionResponseAnimator only works with same scene node as set as object during creation", ELL_ERROR); + return; + } + + if (!World) + return; + + u32 diff = timeMs - LastTime; + LastTime = timeMs; + + core::vector3df pos = Object->getPosition(); + core::vector3df vel = pos - LastPosition; + + //g = Gravity * (f32)((timeMs - FallStartTime) * diff); + + f32 dt = 1.f; + if (Falling) + { + dt = f32 ( ( timeMs - FallStartTime ) * diff ); + } + core::vector3df g = Gravity * dt; + + core::triangle3df triangle = RefTriangle; + + core::vector3df force = vel + g; + + const core::vector3df nullVector ( 0.f, 0.f, 0.f ); + + if ( force != nullVector ) + { + // TODO: divide SlidingSpeed by frame time + + bool f = false; + pos = SceneManager->getSceneCollisionManager()->getCollisionResultPosition( + World, LastPosition-Translation, + Radius, vel, triangle, f, SlidingSpeed, g); + + pos += Translation; + + if (f)//triangle == RefTriangle) + { + if (!Falling) + FallStartTime = timeMs; + + Falling = true; + } + else + Falling = false; + + Object->setPosition(pos); + } + + LastPosition = Object->getPosition(); +} + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorCollisionResponse::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Radius", Radius); + out->addVector3d("Gravity", Gravity); + out->addVector3d("Translation", Translation); +} + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorCollisionResponse::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Radius = in->getAttributeAsVector3d("Radius"); + Gravity = in->getAttributeAsVector3d("Gravity"); + Translation = in->getAttributeAsVector3d("Translation"); +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.h b/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.h new file mode 100644 index 0000000..09725de --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorCollisionResponse.h @@ -0,0 +1,104 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ + +#include "ISceneNodeAnimatorCollisionResponse.h" + +namespace irr +{ +namespace scene +{ + + //! Special scene node animator for doing automatic collision detection and response. + /** This scene node animator can be attached to any scene node modifying it in that + way, that it cannot move through walls of the world, is influenced by gravity and + acceleration. This animator is useful for example for first person shooter + games. Attach it for example to a first person shooter camera, and the camera will + behave as the player control in a first person shooter game: The camera stops and + slides at walls, walks up stairs, falls down if there is no floor under it, and so on. + */ + class CSceneNodeAnimatorCollisionResponse : public ISceneNodeAnimatorCollisionResponse + { + public: + + //! constructor + CSceneNodeAnimatorCollisionResponse(ISceneManager* scenemanager, + ITriangleSelector* world, ISceneNode* object, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingSpeed = 0.0005f); + + //! destructor + virtual ~CSceneNodeAnimatorCollisionResponse(); + + //! Returns if the attached scene node is falling, which means that + //! there is no blocking wall from the scene node in the direction of + //! the gravity. + virtual bool isFalling() const; + + //! Sets the radius of the ellipsoid with which collision detection and + //! response is done. + virtual void setEllipsoidRadius(const core::vector3df& radius); + + //! Returns the radius of the ellipsoid with which the collision detection and + //! response is done. + virtual core::vector3df getEllipsoidRadius() const; + + //! Sets the gravity of the environment. + virtual void setGravity(const core::vector3df& gravity); + + //! Returns current vector of gravity. + virtual core::vector3df getGravity() const; + + //! Sets the translation of the ellipsoid for collision detection. + virtual void setEllipsoidTranslation(const core::vector3df &translation); + + //! Returns the translation of the ellipsoid for collision detection. + virtual core::vector3df getEllipsoidTranslation() const; + + //! Sets a triangle selector holding all triangles of the world with which + //! the scene node may collide. + virtual void setWorld(ITriangleSelector* newWorld); + + //! Returns the current triangle selector containing all triangles for + //! collision detection. + virtual ITriangleSelector* getWorld() const; + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_COLLISION_RESPONSE; } + + private: + core::vector3df LastPosition; + core::vector3df Radius; + core::vector3df Gravity; + core::vector3df Translation; + + ITriangleSelector* World; + ISceneNode* Object; + ISceneManager* SceneManager; + u32 LastTime; + u32 FallStartTime; + f32 SlidingSpeed; + bool Falling; + + core::triangle3df RefTriangle; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.cpp new file mode 100644 index 0000000..cffbdf3 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorDelete.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorDelete::CSceneNodeAnimatorDelete(ISceneManager* manager, u32 time) +: DeleteTime(time), SceneManager(manager) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorDelete"); + #endif +} + + + +//! destructor +CSceneNodeAnimatorDelete::~CSceneNodeAnimatorDelete() +{ +} + + + +//! animates a scene node +void CSceneNodeAnimatorDelete::animateNode(ISceneNode* node, u32 timeMs) +{ + if (timeMs > DeleteTime && node && SceneManager) + { + // don't delete if scene manager is attached to an editor + if (!SceneManager->getParameters()->getAttributeAsBool(IRR_SCENE_MANAGER_IS_EDITOR)) + SceneManager->addToDeletionQueue(node); + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.h b/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.h new file mode 100644 index 0000000..2a3691e --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorDelete.h @@ -0,0 +1,44 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorDelete : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorDelete(ISceneManager* manager, u32 when); + + //! destructor + virtual ~CSceneNodeAnimatorDelete(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_DELETION; + } + + private: + + u32 DeleteTime; + ISceneManager* SceneManager; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.cpp new file mode 100644 index 0000000..c55a8ca --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFlyCircle.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorFlyCircle::CSceneNodeAnimatorFlyCircle(u32 time, const core::vector3df& center, f32 radius, f32 speed, const core::vector3df& direction) +: Center(center), Direction(direction), Radius(radius), Speed(speed), StartTime(time) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFlyCircle"); + #endif + Direction.normalize(); +} + + + +//! destructor +CSceneNodeAnimatorFlyCircle::~CSceneNodeAnimatorFlyCircle() +{ +} + + + +//! animates a scene node +void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs) +{ + if ( 0 == node ) + return; + + const f32 t = (timeMs-StartTime) * Speed; + + core::vector3df circle(Radius * sinf(t), 0, Radius * cosf(t)); + circle = circle.crossProduct ( Direction ); + + node->setPosition(Center + circle); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFlyCircle::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Center", Center); + out->addFloat("Radius", Radius); + out->addFloat("Speed", Speed); + out->addVector3d("Direction", Direction); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorFlyCircle::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Center = in->getAttributeAsVector3d("Center"); + Radius = in->getAttributeAsFloat("Radius"); + Speed = in->getAttributeAsFloat("Speed"); + Direction = in->getAttributeAsVector3d("Direction"); + + if (Direction.equals(core::vector3df(0,0,0))) + Direction.set(0,1,0); // irrlicht 1.1 backwards compatibility + else + Direction.normalize(); +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.h b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.h new file mode 100644 index 0000000..a9113eb --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyCircle.h @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FLY_CIRCLE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FLY_CIRCLE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorFlyCircle : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorFlyCircle(u32 time, const core::vector3df& center, f32 radius, f32 speed, + const core::vector3df& direction); + + //! destructor + virtual ~CSceneNodeAnimatorFlyCircle(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FLY_CIRCLE; } + + private: + + core::vector3df Center; + core::vector3df Direction; + f32 Radius; + f32 Speed; + u32 StartTime; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.cpp new file mode 100644 index 0000000..6a55391 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFlyStraight.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorFlyStraight::CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, + bool loop, u32 now) +: Start(startPoint), End(endPoint), WayLength(0.0f), TimeFactor(0.0f), StartTime(now), TimeForWay(timeForWay), Loop(loop) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFlyStraight"); + #endif + + recalculateImidiateValues(); +} + + +void CSceneNodeAnimatorFlyStraight::recalculateImidiateValues() +{ + Vector = End - Start; + WayLength = (f32)Vector.getLength(); + Vector.normalize(); + + TimeFactor = WayLength / TimeForWay; +} + + + +//! destructor +CSceneNodeAnimatorFlyStraight::~CSceneNodeAnimatorFlyStraight() +{ +} + + + +//! animates a scene node +void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs) +{ + if (!node) + return; + + u32 t = (timeMs-StartTime); + + core::vector3df pos = Start; + + if (!Loop && t >= TimeForWay) + pos = End; + else + pos += Vector * (f32)fmod((f32)t, (f32)TimeForWay) * TimeFactor; + node->setPosition(pos); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFlyStraight::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Start", Start); + out->addVector3d("End", End); + out->addInt("TimeForWay", TimeForWay); + out->addBool("Loop", Loop); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Start = in->getAttributeAsVector3d("Start"); + End = in->getAttributeAsVector3d("End"); + TimeForWay = in->getAttributeAsInt("TimeForWay"); + Loop = in->getAttributeAsBool("Loop"); + + recalculateImidiateValues(); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.h b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.h new file mode 100644 index 0000000..d9cb79a --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFlyStraight.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorFlyStraight : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, + const core::vector3df& endPoint, + u32 timeForWay, + bool loop, u32 now); + + //! destructor + virtual ~CSceneNodeAnimatorFlyStraight(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FLY_STRAIGHT; } + + private: + + void recalculateImidiateValues(); + + core::vector3df Start; + core::vector3df End; + core::vector3df Vector; + f32 WayLength; + f32 TimeFactor; + u32 StartTime; + u32 TimeForWay; + bool Loop; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.cpp new file mode 100644 index 0000000..ebd3f4f --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFollowSpline.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time, + const core::array& points, f32 speed, + f32 tightness) +: Points(points), Speed(speed), Tightness(tightness), StartTime(time) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFollowSpline"); + #endif +} + + + +inline s32 CSceneNodeAnimatorFollowSpline::clamp(s32 idx, s32 size) +{ + return ( idx<0 ? size+idx : ( idx>=size ? idx-size : idx ) ); +} + + +//! animates a scene node +void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs) +{ + const u32 pSize = Points.size(); + if (pSize==0) + return; + + const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f ); + const f32 u = core::fract ( dt ); + const s32 idx = core::floor32( dt ) % pSize; + //const f32 u = 0.001f * fmodf( dt, 1000.0f ); + + const core::vector3df& p0 = Points[ clamp( idx - 1, pSize ) ]; + const core::vector3df& p1 = Points[ clamp( idx + 0, pSize ) ]; + const core::vector3df& p2 = Points[ clamp( idx + 1, pSize ) ]; + const core::vector3df& p3 = Points[ clamp( idx + 2, pSize ) ]; + + // hermite polynomials + const f32 h1 = 2.0f * u * u * u - 3.0f * u * u + 1.0f; + const f32 h2 = -2.0f * u * u * u + 3.0f * u * u; + const f32 h3 = u * u * u - 2.0f * u * u + u; + const f32 h4 = u * u * u - u * u; + + // tangents + const core::vector3df t1 = ( p2 - p0 ) * Tightness; + const core::vector3df t2 = ( p3 - p1 ) * Tightness; + + // interpolated point + node->setPosition(p1 * h1 + p2 * h2 + t1 * h3 + t2 * h4); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addFloat("Speed", Speed); + out->addFloat("Tightness", Tightness); + + u32 count = Points.size(); + + if ( options && (options->Flags & io::EARWF_FOR_EDITOR)) + { + // add one point in addition when serializing for editors + // to make it easier to add points quickly + count += 1; + } + + for (u32 i=0; iaddVector3d(tname.c_str(), igetAttributeAsFloat("Speed"); + Tightness = in->getAttributeAsFloat("Tightness"); + Points.clear(); + + for(u32 i=1; true; ++i) + { + core::stringc pname = "Point"; + pname += i; + + if (in->existsAttribute(pname.c_str())) + Points.push_back(in->getAttributeAsVector3d(pname.c_str())); + else + break; + } + + // remove last point if double entry from editor + if ( options && (options->Flags & io::EARWF_FOR_EDITOR) && + Points.size() > 2 && Points.getLast() == core::vector3df(0,0,0)) + { + Points.erase(Points.size()-1); + + if (Points.size() > 2 && Points.getLast() == core::vector3df(0,0,0)) + Points.erase(Points.size()-1); + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.h b/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.h new file mode 100644 index 0000000..25eb90b --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorFollowSpline.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FOLLOW_SPLINE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FOLLOW_SPLINE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + //! Scene node animator based free code Matthias Gall wrote and sent in. (Most of + //! this code is written by him, I only modified bits.) + class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorFollowSpline(u32 startTime, + const core::array< core::vector3df >& points, + f32 speed = 1.0f, f32 tightness = 0.5f); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FOLLOW_SPLINE; } + + protected: + + //! clamps a the value idx to fit into range 0..size-1 + s32 clamp(s32 idx, s32 size); + + core::array< core::vector3df > Points; + f32 Speed; + f32 Tightness; + u32 StartTime; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.cpp new file mode 100644 index 0000000..751243c --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.cpp @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorRotation.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorRotation::CSceneNodeAnimatorRotation(u32 time, const core::vector3df& rotation) +: Rotation(rotation), StartTime(time) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorRotation"); + #endif +} + + +//! destructor +CSceneNodeAnimatorRotation::~CSceneNodeAnimatorRotation() +{ +} + + + +//! animates a scene node +void CSceneNodeAnimatorRotation::animateNode(ISceneNode* node, u32 timeMs) +{ + if (node) // thanks to warui for this fix + { + u32 diffTime = timeMs - StartTime; + + if (diffTime != 0) + { + core::vector3df NewRotation = node->getRotation(); + NewRotation += Rotation* ((diffTime)/10.0f); + node->setRotation(NewRotation); + StartTime=timeMs; + } + } +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorRotation::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Rotation", Rotation); +} + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorRotation::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Rotation = in->getAttributeAsVector3d("Rotation"); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.h b/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.h new file mode 100644 index 0000000..77caf87 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorRotation.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_ROTATION_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_ROTATION_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorRotation : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorRotation(u32 time, const core::vector3df& rotation); + + //! destructor + virtual ~CSceneNodeAnimatorRotation(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_ROTATION; } + + private: + + core::vector3df Rotation; + u32 StartTime; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.cpp b/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.cpp new file mode 100644 index 0000000..9122e60 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.cpp @@ -0,0 +1,125 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorTexture.h" +#include "ITexture.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array& textures, + s32 timePerFrame, bool loop, u32 now) +: TimePerFrame(timePerFrame), StartTime(now), Loop(loop) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorTexture"); + #endif + + for (u32 i=0; igrab(); + + Textures.push_back(textures[i]); + } + + EndTime = now + (timePerFrame * Textures.size()); +} + + + +//! destructor +CSceneNodeAnimatorTexture::~CSceneNodeAnimatorTexture() +{ + clearTextures(); +} + + + +void CSceneNodeAnimatorTexture::clearTextures() +{ + for (u32 i=0; idrop(); +} + + + +//! animates a scene node +void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs) +{ + if (Textures.size()) + { + u32 t = (timeMs-StartTime); + + s32 idx = 0; + + if (!Loop && timeMs >= EndTime) + idx = Textures.size() - 1; + else + idx = (t/TimePerFrame) % Textures.size(); + + if (idx < (s32)Textures.size()) + node->setMaterialTexture(0, Textures[idx]); + } +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorTexture::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addInt("TimePerFrame", TimePerFrame); + out->addBool("Loop", Loop); + + // add one texture in addition when serializing for editors + // to make it easier to add textures quickly + + u32 count = Textures.size(); + if ( options && (options->Flags & io::EARWF_FOR_EDITOR)) + count += 1; + + for (u32 i=0; iaddTexture(tname.c_str(), igetAttributeAsInt("TimePerFrame"); + Loop = in->getAttributeAsBool("Loop"); + + clearTextures(); + + for(u32 i=1; true; ++i) + { + core::stringc tname = "Texture"; + tname += (int)i; + + if (in->existsAttribute(tname.c_str())) + { + video::ITexture* tex = in->getAttributeAsTexture(tname.c_str()); + if (tex) + { + tex->grab(); + Textures.push_back(tex); + } + } + else + break; + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.h b/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.h new file mode 100644 index 0000000..fb4e0c8 --- /dev/null +++ b/src/dep/src/irrlicht/CSceneNodeAnimatorTexture.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_TEXTURE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_TEXTURE_H_INCLUDED__ + +#include "irrArray.h" +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorTexture : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorTexture(const core::array& textures, + s32 timePerFrame, bool loop, u32 now); + + //! destructor + virtual ~CSceneNodeAnimatorTexture(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_TEXTURE; } + + private: + + void clearTextures(); + + core::array Textures; + u32 TimePerFrame; + u32 StartTime; + u32 EndTime; + bool Loop; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CShadowVolumeSceneNode.cpp b/src/dep/src/irrlicht/CShadowVolumeSceneNode.cpp new file mode 100644 index 0000000..0403ab4 --- /dev/null +++ b/src/dep/src/irrlicht/CShadowVolumeSceneNode.cpp @@ -0,0 +1,473 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CShadowVolumeSceneNode.h" +#include "ISceneManager.h" +#include "IMesh.h" +#include "IVideoDriver.h" +#include "SLight.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CShadowVolumeSceneNode::CShadowVolumeSceneNode(ISceneNode* parent, + ISceneManager* mgr, s32 id, + bool zfailmethod, f32 infinity) +: IShadowVolumeSceneNode(parent, mgr, id), Indices(0), Vertices(0), + Adjacency(0), FaceData(0), UseZFailMethod(zfailmethod), + IndexCountAllocated(0), VertexCountAllocated(0), + IndexCount(0), VertexCount(0), ShadowVolumesUsed(0), + Edges(0), EdgeCount(0), Infinity(infinity) +{ + #ifdef _DEBUG + setDebugName("CShadowVolumeSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); +} + + + +//! destructor +CShadowVolumeSceneNode::~CShadowVolumeSceneNode() +{ + delete [] Edges; + + for (u32 i=0; i (u32)ShadowVolumesUsed) + { + // get the next unused buffer + svp = &ShadowVolumes[ShadowVolumesUsed]; + if (svp->size >= IndexCount*5) + svp->count = 0; + else + { + svp->size = IndexCount*5; + svp->count = 0; + delete [] svp->vertices; + svp->vertices = new core::vector3df[svp->size]; + } + + ++ShadowVolumesUsed; + } + else + { + // add a buffer + SShadowVolume tmp; + // lets make a rather large shadowbuffer + tmp.size = IndexCount*5; + tmp.count = 0; + tmp.vertices = new core::vector3df[tmp.size]; + ShadowVolumes.push_back(tmp); + svp = &ShadowVolumes[ShadowVolumes.size()-1]; + ++ShadowVolumesUsed; + } + + const s32 faceCount = (s32)(IndexCount / 3); + + if (!Edges || faceCount * 6 > EdgeCount) + { + delete [] Edges; + EdgeCount = faceCount * 6; + Edges = new u16[EdgeCount]; + } + + s32 numEdges = 0; + const core::vector3df ls = light * Infinity; // light scaled + + //if (UseZFailMethod) + // createZFailVolume(faceCount, numEdges, light, svp); + //else + // createZPassVolume(faceCount, numEdges, light, svp, false); + + // the createZFailVolume does currently not work 100% correctly, + // so we create createZPassVolume with caps if the zfail method + // is used + createZPassVolume(faceCount, numEdges, light, svp, UseZFailMethod); + + + for (s32 i=0; ivertices && svp->count < svp->size-5) + { + svp->vertices[svp->count++] = v1; + svp->vertices[svp->count++] = v2; + svp->vertices[svp->count++] = v3; + + svp->vertices[svp->count++] = v2; + svp->vertices[svp->count++] = v4; + svp->vertices[svp->count++] = v3; + } + } +} + +void CShadowVolumeSceneNode::createZFailVolume(s32 faceCount, s32& numEdges, + const core::vector3df& light, + SShadowVolume* svp) +{ + s32 i; + const core::vector3df ls = light * Infinity; + + // Check every face if it is front or back facing the light. + for (i=0; ivertices && svp->count < svp->size-5) + { + // add front cap + svp->vertices[svp->count++] = v0; + svp->vertices[svp->count++] = v2; + svp->vertices[svp->count++] = v1; + + // add back cap + svp->vertices[svp->count++] = v0 - ls; + svp->vertices[svp->count++] = v1 - ls; + svp->vertices[svp->count++] = v2 - ls; + } + } + else + FaceData[i] = true; // it's a front facing face + } + + for(i=0; ivertices && svp->count < svp->size-5) + { + svp->vertices[svp->count++] = Vertices[wFace0]; + svp->vertices[svp->count++] = Vertices[wFace2]; + svp->vertices[svp->count++] = Vertices[wFace1]; + + svp->vertices[svp->count++] = Vertices[wFace0] - light; + svp->vertices[svp->count++] = Vertices[wFace1] - light; + svp->vertices[svp->count++] = Vertices[wFace2] - light; + } + } + } +} + +//! sets the mesh from which the shadow volume should be generated. +void CShadowVolumeSceneNode::setMeshToRenderFrom(const IMesh* mesh) +{ + ShadowVolumesUsed = 0; + + s32 oldIndexCount = IndexCount; + s32 oldVertexCount = VertexCount; + + VertexCount = 0; + IndexCount = 0; + + if (!mesh) + return; + + // calculate total amount of vertices and indices + + u32 i; + s32 totalVertices = 0; + s32 totalIndices = 0; + u32 bufcnt = mesh->getMeshBufferCount(); + const IMeshBuffer* b; + + for (i=0; igetMeshBuffer(i); + totalIndices += b->getIndexCount(); + totalVertices += b->getVertexCount(); + } + + // allocate memory if necessary + + if (totalVertices > VertexCountAllocated) + { + delete [] Vertices; + Vertices = new core::vector3df[totalVertices]; + VertexCountAllocated = totalVertices; + } + + if (totalIndices > IndexCountAllocated) + { + delete [] Indices; + Indices = new u16[totalIndices]; + IndexCountAllocated = totalIndices; + + if (UseZFailMethod) + { + delete [] FaceData; + FaceData = new bool[totalIndices / 3]; + } + } + + // copy mesh + + for (i=0; igetMeshBuffer(i); + + s32 idxcnt = b->getIndexCount(); + s32 vtxnow = VertexCount; + + const u16* idxp = b->getIndices(); + const u16* idxpend = idxp + idxcnt; + + for (; idxp!=idxpend; ++idxp) + Indices[IndexCount++] = *idxp + vtxnow; + + s32 vtxcnt = b->getVertexCount(); + + switch(b->getVertexType()) + { + case video::EVT_STANDARD: + { + const video::S3DVertex* vp = (video::S3DVertex*)b->getVertices(); + const video::S3DVertex* const vpend = vp + vtxcnt; + + for (; vp!=vpend; ++vp) + Vertices[VertexCount++] = (*vp).Pos; + } + break; + case video::EVT_2TCOORDS: + { + const video::S3DVertex2TCoords* vp = (video::S3DVertex2TCoords*)b->getVertices(); + const video::S3DVertex2TCoords* const vpend = vp + vtxcnt; + + for (; vp!=vpend; ++vp) + Vertices[VertexCount++] = (*vp).Pos; + } + break; + case video::EVT_TANGENTS: + { + const video::S3DVertexTangents* vp = (video::S3DVertexTangents*)b->getVertices(); + const video::S3DVertexTangents* const vpend = vp + vtxcnt; + + for (; vp!=vpend; ++vp) + Vertices[VertexCount++] = (*vp).Pos; + } + break; + } + } + + // recalculate adjacency if necessary + if (oldVertexCount != VertexCount && + oldIndexCount != IndexCount && UseZFailMethod) + calculateAdjacency(); + + // create as much shadow volumes as there are lights but + // do not ignore the max light settings. + + const u32 lights = SceneManager->getVideoDriver()->getDynamicLightCount(); + core::matrix4 mat = Parent->getAbsoluteTransformation(); + const core::vector3df parentpos = Parent->getAbsolutePosition(); + core::vector3df lpos; + mat.makeInverse(); + + // TODO: Only correct for point lights. + for (i=0; igetVideoDriver()->getDynamicLight(i); + lpos = dl.Position; + if (dl.CastShadows && + fabs((lpos - parentpos).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f)) + { + mat.transformVect(lpos); + createShadowVolume(lpos); + } + } +} + + + +//! pre render method +void CShadowVolumeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, scene::ESNRP_SHADOW); + ISceneNode::OnRegisterSceneNode(); + } +} + + + +//! renders the node. +void CShadowVolumeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!ShadowVolumesUsed || !driver) + return; + + driver->setTransform(video::ETS_WORLD, Parent->getAbsoluteTransformation()); + + for (s32 i=0; idrawStencilShadowVolume(ShadowVolumes[i].vertices, + ShadowVolumes[i].count, UseZFailMethod); +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CShadowVolumeSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! Generates adjacency information based on mesh indices. +void CShadowVolumeSceneNode::calculateAdjacency(f32 epsilon) +{ + delete [] Adjacency; + Adjacency = new u16[IndexCount]; + + epsilon *= epsilon; + + f32 t = 0; + + // go through all faces and fetch their three neighbours + for (s32 f=0; f& getBoundingBox() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SHADOW_VOLUME; } + + private: + + struct SShadowVolume + { + core::vector3df* vertices; + s32 count; + s32 size; + }; + + void createShadowVolume(const core::vector3df& pos); + void createZPassVolume(s32 faceCount, s32& numEdges, core::vector3df light, SShadowVolume* svp, bool caps); + void createZFailVolume(s32 faceCount, s32& numEdges, const core::vector3df& light, SShadowVolume* svp); + void addEdge(s32& numEdges, u16 v0, u16 v1); + + //! Generates adjacency information based on mesh indices. + void calculateAdjacency(f32 epsilon=0.0001f); + + core::aabbox3d Box; + + u16* Indices; + core::vector3df* Vertices; + u16* Adjacency; + bool* FaceData; // used for zfail method, if face is front facing + bool UseZFailMethod; + + s32 IndexCountAllocated; + s32 VertexCountAllocated; + s32 IndexCount; + s32 VertexCount; + + core::array ShadowVolumes; // a shadow volume for every light + s32 ShadowVolumesUsed; + + u16* Edges; + s32 EdgeCount; + + f32 Infinity; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSkinnedMesh.cpp b/src/dep/src/irrlicht/CSkinnedMesh.cpp new file mode 100644 index 0000000..2759fc5 --- /dev/null +++ b/src/dep/src/irrlicht/CSkinnedMesh.cpp @@ -0,0 +1,1372 @@ +// Copyright (C) 2002-2006 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + +#include "CSkinnedMesh.h" +#include "CBoneSceneNode.h" +#include "IAnimatedMeshSceneNode.h" +#include "os.h" + + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSkinnedMesh::CSkinnedMesh() +: SkinningBuffers(0), HasAnimation(0), PreparedForSkinning(0), + AnimationFrames(0.f), lastAnimatedFrame(0.f), lastSkinnedFrame(0.f), + BoneControlUsed(false), AnimateNormals(true), InterpolationMode(EIM_LINEAR) +{ + #ifdef _DEBUG + setDebugName("CSkinnedMesh"); + #endif + + SkinningBuffers=&LocalBuffers; +} + + +//! destructor +CSkinnedMesh::~CSkinnedMesh() +{ + for (u32 i=0; idrop(); + } +} + + +//! returns the amount of frames in milliseconds. +//! If the amount is 1, it is a static (=non animated) mesh. +u32 CSkinnedMesh::getFrameCount() const +{ + return core::floor32(AnimationFrames); +} + + +//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. +IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + //animate(frame,startFrameLoop, endFrameLoop); + if (frame==-1) + return this; + + animateMesh((f32)frame, 1.0f); + buildAll_LocalAnimatedMatrices(); + buildAll_GlobalAnimatedMatrices(); + skinMesh(); + return this; +} + + +//-------------------------------------------------------------------------- +// Keyframe Animation +//-------------------------------------------------------------------------- + + +//! Animates this mesh's joints based on frame input +//! blend: {0-old position, 1-New position} +void CSkinnedMesh::animateMesh(f32 frame, f32 blend) +{ + + if ( !HasAnimation || lastAnimatedFrame==frame) + return; + + lastAnimatedFrame=frame; + + if (blend<=0.f) + return; //No need to animate + + for (u32 i=0; iAnimatedposition; + const core::vector3df oldScale = Joint->Animatedscale; + const core::quaternion oldRotation = Joint->Animatedrotation; + + core::vector3df position = oldPosition; + core::vector3df scale = oldScale; + core::quaternion rotation = oldRotation; + + if (!BoneControlUsed) + { + Joint->positionHint=-1; + Joint->scaleHint=-1; + Joint->rotationHint=-1; + } + + getFrameData(frame, Joint, + position, Joint->positionHint, + scale, Joint->scaleHint, + rotation, Joint->rotationHint); + + if (blend==1.0f) + { + //No blending needed + Joint->Animatedposition = position; + Joint->Animatedscale = scale; + Joint->Animatedrotation = rotation; + } + else + { + //Blend animation + Joint->Animatedposition = core::lerp(oldPosition, position, blend); + Joint->Animatedscale = core::lerp(oldScale, scale, blend); + Joint->Animatedrotation.slerp(oldRotation, rotation, blend); + } + + //Note: + //_LocalAnimatedMatrix needs to be built at some point, but this function may be called lots of times for + //one render (to play two animations at the same time) _LocalAnimatedMatrix only needs to be built once. + //a call to buildAllLocalAnimatedMatrices is needed before skinning the mesh, and before the user gets the joints to move + + //---------------- + // Temp! + buildAll_LocalAnimatedMatrices(); + //----------------- + } + + BoneControlUsed=false; +} + + +void CSkinnedMesh::buildAll_LocalAnimatedMatrices() +{ + for (u32 i=0; iUseAnimationFrom && + (Joint->UseAnimationFrom->PositionKeys.size() || + Joint->UseAnimationFrom->ScaleKeys.size() || + Joint->UseAnimationFrom->RotationKeys.size() )) + { + Joint->LocalAnimatedMatrix.makeIdentity(); + Joint->LocalAnimatedMatrix.setTranslation(Joint->Animatedposition); + Joint->LocalAnimatedMatrix*=Joint->Animatedrotation.getMatrix(); + + Joint->GlobalSkinningSpace=false; + + if (Joint->ScaleKeys.size()) + { + //Joint->_LocalAnimatedMatrix.setScale(Joint->_Animatedscale); + core::matrix4 scaleMatrix; + scaleMatrix.setScale(Joint->Animatedscale); + Joint->LocalAnimatedMatrix *= scaleMatrix; + } + } + else + { + Joint->LocalAnimatedMatrix=Joint->LocalMatrix; + } + } +} + + +void CSkinnedMesh::buildAll_GlobalAnimatedMatrices(SJoint *Joint, SJoint *ParentJoint) +{ + if (!Joint) + { + for (u32 i=0; iGlobalSkinningSpace) + Joint->GlobalAnimatedMatrix = Joint->LocalAnimatedMatrix; + else + Joint->GlobalAnimatedMatrix = ParentJoint->GlobalAnimatedMatrix * Joint->LocalAnimatedMatrix; + + } + + for (u32 j=0; jChildren.size(); ++j) + buildAll_GlobalAnimatedMatrices(Joint->Children[j], Joint); +} + + +void CSkinnedMesh::getFrameData(f32 frame, SJoint *Joint, + core::vector3df &position, s32 &positionHint, + core::vector3df &scale, s32 &scaleHint, + core::quaternion &rotation, s32 &rotationHint) +{ + s32 foundPositionIndex = -1; + s32 foundScaleIndex = -1; + s32 foundRotationIndex = -1; + + if (Joint->UseAnimationFrom) + { + const core::array &PositionKeys=Joint->UseAnimationFrom->PositionKeys; + const core::array &ScaleKeys=Joint->UseAnimationFrom->ScaleKeys; + const core::array &RotationKeys=Joint->UseAnimationFrom->RotationKeys; + + if (PositionKeys.size()) + { + foundPositionIndex = -1; + + //Test the Hints... + if ((u32)positionHint < PositionKeys.size()) + { + //check this hint + if (PositionKeys[positionHint].frame>=frame && PositionKeys[positionHint-1].frame=frame && + PositionKeys[positionHint+0].frame= frame) //Keys should to be sorted by frame + { + foundPositionIndex=i; + positionHint=i; + break; + } + } + } + + //Do interpolation... + if (foundPositionIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundPositionIndex==0) + { + position = PositionKeys[foundPositionIndex].position; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SPositionKey& KeyA = PositionKeys[foundPositionIndex]; + const SPositionKey& KeyB = PositionKeys[foundPositionIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + position = ((KeyB.position-KeyA.position)/(fd1+fd2))*fd1 + KeyA.position; + } + } + } + + //------------------------------------------------------------ + + if (ScaleKeys.size()) + { + foundScaleIndex = -1; + + //Test the Hints... + if ((u32)scaleHint < ScaleKeys.size()) + { + //check this hint + if (ScaleKeys[scaleHint].frame>=frame && ScaleKeys[scaleHint-1].frame=frame && + ScaleKeys[scaleHint+0].frame= frame) //Keys should to be sorted by frame + { + foundScaleIndex=i; + scaleHint=i; + break; + } + } + } + + //Do interpolation... + if (foundScaleIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundScaleIndex==0) + { + scale = ScaleKeys[foundScaleIndex].scale; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SScaleKey& KeyA = ScaleKeys[foundScaleIndex]; + const SScaleKey& KeyB = ScaleKeys[foundScaleIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + scale = ((KeyB.scale-KeyA.scale)/(fd1+fd2))*fd1 + KeyA.scale; + } + } + } + + //------------------------------------------------------------- + + if (RotationKeys.size()) + { + foundRotationIndex = -1; + + //Test the Hints... + if ((u32)rotationHint < RotationKeys.size()) + { + //check this hint + if (RotationKeys[rotationHint].frame>=frame && RotationKeys[rotationHint-1].frame=frame && + RotationKeys[rotationHint+0].frame= frame) //Keys should be sorted by frame + { + foundRotationIndex=i; + rotationHint=i; + break; + } + } + } + + //Do interpolation... + if (foundRotationIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundRotationIndex==0) + { + rotation = RotationKeys[foundRotationIndex].rotation; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SRotationKey& KeyA = RotationKeys[foundRotationIndex]; + const SRotationKey& KeyB = RotationKeys[foundRotationIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + const f32 t = fd1/(fd1+fd2); + + /* + f32 t = 0; + if (KeyA.frame!=KeyB.frame) + t = (frame-KeyA.frame) / (KeyB.frame - KeyA.frame); + */ + + rotation.slerp(KeyA.rotation, KeyB.rotation, t); + } + } + } + } +} + +//-------------------------------------------------------------------------- +// Software Skinning +//-------------------------------------------------------------------------- + +//! Preforms a software skin on this mesh based of joint positions +void CSkinnedMesh::skinMesh() +{ + + if ( !HasAnimation) + return; + + + //---------------- + // Temp! + buildAll_GlobalAnimatedMatrices(); + //----------------- + + + //Software skin.... + + u32 i; + + + + + //rigid animation + for (i=0; iAttachedMeshes.size(); ++j) + { + SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ]; + Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix; + } + } + + //clear skinning helper array + + for (i=0; iWeights.size()) + { + //Find this joints pull on vertices... + core::matrix4 JointVertexPull(core::matrix4::EM4CONST_NOTHING); + JointVertexPull.setbyproduct(Joint->GlobalAnimatedMatrix, Joint->GlobalInversedMatrix); + + core::vector3df ThisVertexMove, ThisNormalMove; + + core::array &BuffersUsed=*SkinningBuffers; + + //Skin Vertices Positions and Normals... + for (u32 i=0; iWeights.size(); ++i) + { + SWeight& weight = Joint->Weights[i]; + + // Pull this vertex... + JointVertexPull.transformVect(ThisVertexMove, weight.StaticPos); + + if (AnimateNormals) + JointVertexPull.rotateVect(ThisNormalMove, weight.StaticNormal); + + if (! (*(weight.Moved)) ) + { + *(weight.Moved) = true; + + BuffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = ThisVertexMove * weight.strength; + + if (AnimateNormals) + BuffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = ThisNormalMove * weight.strength; + + //*(weight._Pos) = ThisVertexMove * weight.strength; + } + else + { + BuffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += ThisVertexMove * weight.strength; + + if (AnimateNormals) + BuffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += ThisNormalMove * weight.strength; + + //*(weight._Pos) += ThisVertexMove * weight.strength; + } + } + } + + //Skin all children + for (u32 j=0; jChildren.size(); ++j) + SkinJoint(Joint->Children[j], Joint); +} + + +E_ANIMATED_MESH_TYPE CSkinnedMesh::getMeshType() const +{ + return EAMT_SKINNED; +} + + +//! Gets joint count. +u32 CSkinnedMesh::getJointCount() const +{ + return AllJoints.size(); +} + + +//! Gets the name of a joint. +const c8* CSkinnedMesh::getJointName(u32 number) const +{ + if (number >= AllJoints.size()) + return 0; + return AllJoints[number]->Name.c_str(); +} + + +//! Gets a joint number from its name +s32 CSkinnedMesh::getJointNumber(const c8* name) const +{ + for (u32 i=0; iName == name) + return i; + } + + return -1; +} + + +//! returns amount of mesh buffers. +u32 CSkinnedMesh::getMeshBufferCount() const +{ + return LocalBuffers.size(); +} + + +//! returns pointer to a mesh buffer +IMeshBuffer* CSkinnedMesh::getMeshBuffer(u32 nr) const +{ + if (nr < LocalBuffers.size()) + return LocalBuffers[nr]; + else + return 0; +} + + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CSkinnedMesh::getMeshBuffer(const video::SMaterial &material) const +{ + for (u32 i=0; igetMaterial() == material) + return LocalBuffers[i]; + } + return 0; +} + + +//! returns an axis aligned bounding box +const core::aabbox3d& CSkinnedMesh::getBoundingBox() const +{ + return BoundingBox; +} + + +//! set user axis aligned bounding box +void CSkinnedMesh::setBoundingBox( const core::aabbox3df& box) +{ + BoundingBox = box; +} + + +//! sets a flag of all contained materials to a new value +void CSkinnedMesh::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + for (u32 i=0; iMaterial.setFlag(flag,newvalue); +} + + +//! uses animation from another mesh +bool CSkinnedMesh::useAnimationFrom(const ISkinnedMesh *mesh) +{ + bool unmatched=false; + + for(u32 i=0;iUseAnimationFrom=0; + + if (joint->Name=="") + unmatched=true; + else + { + for(u32 j=0;jgetAllJoints().size();++j) + { + SJoint *otherJoint=mesh->getAllJoints()[j]; + if (joint->Name==otherJoint->Name) + { + joint->UseAnimationFrom=otherJoint; + } + } + if (!joint->UseAnimationFrom) unmatched=true; + } + } + + checkForAnimation(); + + return !unmatched; +} + + +//!Update Normals when Animating +//!False= Don't animate them, faster +//!True= Update normals (default) +void CSkinnedMesh::updateNormalsWhenAnimating(bool on) +{ + AnimateNormals = on; +} + + +//!Sets Interpolation Mode +void CSkinnedMesh::setInterpolationMode(E_INTERPOLATION_MODE mode) +{ + InterpolationMode = mode; +} + + +core::array &CSkinnedMesh::getMeshBuffers() +{ + return LocalBuffers; +} + + +core::array &CSkinnedMesh::getAllJoints() +{ + return AllJoints; +} + + +const core::array &CSkinnedMesh::getAllJoints() const +{ + return AllJoints; +} + + +void CSkinnedMesh::CalculateGlobalMatrixes(SJoint *Joint,SJoint *ParentJoint) +{ + if (!Joint && ParentJoint) // bit of protection from endless loops + return; + + //Go through the root bones + if (!Joint) + { + for (u32 i=0; iGlobalMatrix = Joint->LocalMatrix; + else + Joint->GlobalMatrix = ParentJoint->GlobalMatrix * Joint->LocalMatrix; + + Joint->LocalAnimatedMatrix=Joint->LocalMatrix; + Joint->GlobalAnimatedMatrix=Joint->GlobalMatrix; + + if (Joint->GlobalInversedMatrix.isIdentity())//might be pre calculated + { + Joint->GlobalInversedMatrix = Joint->GlobalMatrix; + Joint->GlobalInversedMatrix.makeInverse(); // slow + } + + for (u32 j=0; jChildren.size(); ++j) + CalculateGlobalMatrixes(Joint->Children[j],Joint); +} + + +void CSkinnedMesh::checkForAnimation() +{ + u32 i,j; + //Check for animation... + HasAnimation = false; + for(i=0;iUseAnimationFrom) + { + if (AllJoints[i]->UseAnimationFrom->PositionKeys.size() || + AllJoints[i]->UseAnimationFrom->ScaleKeys.size() || + AllJoints[i]->UseAnimationFrom->RotationKeys.size() ) + { + HasAnimation = true; + } + } + } + + //meshes with weights, are still counted as animated for ragdolls, etc + if (!HasAnimation) + { + for(i=0;iWeights.size()) + HasAnimation = true; + } + } + + if (HasAnimation) + { + //--- Find the length of the animation --- + AnimationFrames=0; + for(i=0;iUseAnimationFrom) + { + if (AllJoints[i]->UseAnimationFrom->PositionKeys.size()) + if (AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame; + + if (AllJoints[i]->UseAnimationFrom->ScaleKeys.size()) + if (AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame; + + if (AllJoints[i]->UseAnimationFrom->RotationKeys.size()) + if (AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame; + } + } + } + + if (HasAnimation && !PreparedForSkinning) + { + PreparedForSkinning=true; + + //check for bugs: + for(i=0; i < AllJoints.size(); ++i) + { + SJoint *Joint = AllJoints[i]; + for (j=0; jWeights.size(); ++j) + { + const u16 buffer_id=Joint->Weights[j].buffer_id; + const u32 vertex_id=Joint->Weights[j].vertex_id; + + //check for invalid ids + if (buffer_id>=LocalBuffers.size()) + { + os::Printer::log("Skinned Mesh: Weight buffer id too large", ELL_WARNING); + Joint->Weights[j].buffer_id = Joint->Weights[j].vertex_id =0; + } + else if (vertex_id>=LocalBuffers[buffer_id]->getVertexCount()) + { + os::Printer::log("Skinned Mesh: Weight vertex id too large", ELL_WARNING); + Joint->Weights[j].buffer_id = Joint->Weights[j].vertex_id =0; + } + } + } + + //An array used in skinning + + for (i=0; iWeights.size(); ++j) + { + const u16 buffer_id=Joint->Weights[j].buffer_id; + const u32 vertex_id=Joint->Weights[j].vertex_id; + + Joint->Weights[j].Moved = &Vertices_Moved[buffer_id] [vertex_id]; + Joint->Weights[j].StaticPos = LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos; + Joint->Weights[j].StaticNormal = LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal; + + //Joint->Weights[j]._Pos=&Buffers[buffer_id]->getVertex(vertex_id)->Pos; + } + } + + // normalize weights + normalizeWeights(); + } +} + + +//! called by loader after populating with mesh and bone data +void CSkinnedMesh::finalize() +{ + u32 i; + + lastAnimatedFrame=-1; + lastSkinnedFrame=-1; + + //calculate bounding box + + for (i=0; irecalculateBoundingBox(); + } + + // Get BoundingBox... + if (LocalBuffers.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(LocalBuffers[0]->BoundingBox.MaxEdge); + for (u32 j=0; jBoundingBox); + } + } + + //add 5% padding to bounding box + core::vector3df Padding=BoundingBox.getExtent()*0.05f; + BoundingBox.MinEdge-=Padding; + BoundingBox.MaxEdge+=Padding; + + + if (AllJoints.size() || RootJoints.size()) + { + // populate AllJoints or RootJoints, depending on which is empty + if (!RootJoints.size()) + { + + for(u32 CheckingIdx=0; CheckingIdx < AllJoints.size(); ++CheckingIdx) + { + + bool foundParent=false; + for(i=0; i < AllJoints.size(); ++i) + { + for(u32 n=0; n < AllJoints[i]->Children.size(); ++n) + { + if (AllJoints[i]->Children[n] == AllJoints[CheckingIdx]) + foundParent=true; + } + } + + if (!foundParent) + RootJoints.push_back(AllJoints[CheckingIdx]); + } + } + else + { + AllJoints=RootJoints; + } + } + + for(i=0; i < AllJoints.size(); ++i) + { + AllJoints[i]->UseAnimationFrom=AllJoints[i]; + } + + //Set array sizes... + + for (i=0; i() ); + Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount()); + } + + + //Todo: optimise keys here... + + + checkForAnimation(); + + + if (HasAnimation) + { + + //--- optimize and check keyframes --- + for(i=0;i &PositionKeys =AllJoints[i]->PositionKeys; + core::array &ScaleKeys = AllJoints[i]->ScaleKeys; + core::array &RotationKeys = AllJoints[i]->RotationKeys; + + if (PositionKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= PositionKeys[j+1].frame) //bad frame, unneed and may cause problems + { + PositionKeys.erase(j+1); + --j; + } + } + } + + if (ScaleKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= ScaleKeys[j+1].frame) //bad frame, unneed and may cause problems + { + ScaleKeys.erase(j+1); + --j; + } + } + } + + if (RotationKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= RotationKeys[j+1].frame) //bad frame, unneed and may cause problems + { + RotationKeys.erase(j+1); + --j; + } + } + } + + + //Fill empty keyframe areas + if (PositionKeys.size()) + { + SPositionKey *Key; + Key=&PositionKeys[0];//getFirst + if (Key->frame!=0) + { + PositionKeys.push_front(*Key); + Key=&PositionKeys[0];//getFirst + Key->frame=0; + } + + Key=&PositionKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + PositionKeys.push_back(*Key); + Key=&PositionKeys.getLast(); + Key->frame=AnimationFrames; + } + } + + if (ScaleKeys.size()) + { + SScaleKey *Key; + Key=&ScaleKeys[0];//getFirst + if (Key->frame!=0) + { + ScaleKeys.push_front(*Key); + Key=&ScaleKeys[0];//getFirst + Key->frame=0; + } + + Key=&ScaleKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + ScaleKeys.push_back(*Key); + Key=&ScaleKeys.getLast(); + Key->frame=AnimationFrames; + } + } + + if (RotationKeys.size()) + { + SRotationKey *Key; + Key=&RotationKeys[0];//getFirst + if (Key->frame!=0) + { + RotationKeys.push_front(*Key); + Key=&RotationKeys[0];//getFirst + Key->frame=0; + } + + Key=&RotationKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + RotationKeys.push_back(*Key); + Key=&RotationKeys.getLast(); + Key->frame=AnimationFrames; + } + } + } + } + + //Needed for animation and skinning... + + CalculateGlobalMatrixes(0,0); + + //animateMesh(0, 1); + //buildAll_LocalAnimatedMatrices(); + //buildAll_GlobalAnimatedMatrices(); + + + + //rigid animation for non animated meshes + for (i=0; iAttachedMeshes.size(); ++j) + { + SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ]; + Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix; + } + } + + + +} + + +scene::SSkinMeshBuffer *CSkinnedMesh::createBuffer() +{ + scene::SSkinMeshBuffer *buffer=new scene::SSkinMeshBuffer(); + LocalBuffers.push_back(buffer); + return buffer; +} + + +CSkinnedMesh::SJoint *CSkinnedMesh::createJoint(SJoint *parent) +{ + SJoint *joint=new SJoint; + + AllJoints.push_back(joint); + if (!parent) + { + //Add root joints to array in finalize() + } + else + { + //Set parent (Be careful of the mesh loader also setting the parent) + parent->Children.push_back(joint); + } + + return joint; +} + + +CSkinnedMesh::SPositionKey *CSkinnedMesh::createPositionKey(SJoint *joint) +{ + if (!joint) + return 0; + SPositionKey *key; + + joint->PositionKeys.push_back(SPositionKey()); + key=&joint->PositionKeys.getLast(); + + key->frame=0; + return key; +} + + +CSkinnedMesh::SScaleKey *CSkinnedMesh::createScaleKey(SJoint *joint) +{ + if (!joint) + return 0; + SScaleKey *key; + + joint->ScaleKeys.push_back(SScaleKey()); + key=&joint->ScaleKeys.getLast(); + + return key; +} + + +CSkinnedMesh::SRotationKey *CSkinnedMesh::createRotationKey(SJoint *joint) +{ + if (!joint) + return 0; + SRotationKey *key; + + joint->RotationKeys.push_back(SRotationKey()); + key=&joint->RotationKeys.getLast(); + + return key; +} + + +CSkinnedMesh::SWeight *CSkinnedMesh::createWeight(SJoint *joint) +{ + if (!joint) + return 0; + + joint->Weights.push_back(SWeight()); + + SWeight *weight=&joint->Weights.getLast(); + + //Could do stuff here... + + return weight; +} + + +void CSkinnedMesh::normalizeWeights() +{ + // note: unsure if weights ids are going to be used. + + // Normalise the weights on bones.... + + u32 i,j; + core::array< core::array > Vertices_TotalWeight; + + for (i=0; i()); + Vertices_TotalWeight[i].set_used(LocalBuffers[i]->getVertexCount()); + } + + + for (i=0; iWeights.size(); ++j) + { + if (Joint->Weights[j].strength<=0)//Check for invalid weights + { + Joint->Weights.erase(j); + j--; + } + else + { + Vertices_TotalWeight[ Joint->Weights[j].buffer_id ] [ Joint->Weights[j].vertex_id ] += Joint->Weights[j].strength; + } + } + } + + for (i=0; iWeights.size(); ++j) + { + f32 total = Vertices_TotalWeight[ Joint->Weights[j].buffer_id ] [ Joint->Weights[j].vertex_id ]; + if (total != 0 && total != 1) + Joint->Weights[j].strength /= total; + } + } +} + + +void CSkinnedMesh::recoverJointsFromMesh(core::array &JointChildSceneNodes) +{ + for (u32 i=0;isetPosition( joint->LocalAnimatedMatrix.getTranslation() ); + node->setRotation( joint->LocalAnimatedMatrix.getRotationDegrees() ); + + //node->setScale( joint->LocalAnimatedMatrix.getScale() ); + + node->positionHint=joint->positionHint; + node->scaleHint=joint->scaleHint; + node->rotationHint=joint->rotationHint; + + //node->setAbsoluteTransformation(joint->GlobalMatrix); //not going to work + + //Note: This updateAbsolutePosition will not work well if joints are not nested like b3d + //node->updateAbsolutePosition(); + } +} + +void CSkinnedMesh::transferJointsToMesh(const core::array &JointChildSceneNodes) +{ + for (u32 i=0;iLocalAnimatedMatrix.setTranslation( node->getPosition() ); + joint->LocalAnimatedMatrix.setRotationDegrees( node->getRotation() ); + + + //joint->LocalAnimatedMatrix.setScale( node->getScale() ); + + joint->positionHint=node->positionHint; + joint->scaleHint=node->scaleHint; + joint->rotationHint=node->rotationHint; + + if (node->getSkinningSpace()==EBSS_GLOBAL) + joint->GlobalSkinningSpace=true; + else + joint->GlobalSkinningSpace=false; + } + //Remove cache, temp... + lastAnimatedFrame=-1; + lastSkinnedFrame=-1; + + BoneControlUsed=true; +} + + +void CSkinnedMesh::createJoints(core::array &JointChildSceneNodes, + IAnimatedMeshSceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager) +{ + u32 i; + + //Create new joints + for (i=0;iName.c_str()); + + JointChildSceneNodes.push_back(node); + } + + //Match up parents + for (i=0;iChildren.size();++n) + { + if (parentTest->Children[n]==joint) + { + parentID=j; + break; + } + } + } + } + + if (parentID!=-1) + node->setParent( JointChildSceneNodes[parentID] ); + else + node->setParent( AnimatedMeshSceneNode ); + + node->drop(); + } +} + + +void CSkinnedMesh::convertMeshToTangents() +{ + // now calculate tangents + for (u32 b=0; b < LocalBuffers.size(); ++b) + { + if (LocalBuffers[b]) + { + LocalBuffers[b]->MoveTo_Tangents(); + + s32 idxCnt = LocalBuffers[b]->getIndexCount(); + + u16* idx = LocalBuffers[b]->getIndices(); + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)LocalBuffers[b]->getVertices(); + + for (s32 i=0; i + +#include "ISkinnedMesh.h" + +namespace irr +{ +namespace scene +{ + + class IAnimatedMeshSceneNode; + class IBoneSceneNode; + + class CSkinnedMesh: public ISkinnedMesh + { + public: + + //! constructor + CSkinnedMesh(); + + //! destructor + virtual ~CSkinnedMesh(); + + //! returns the amount of frames. If the amount is 1, it is a static (=non animated) mesh. + virtual u32 getFrameCount() const; + + //! returns the animated mesh based on a detail level (which is ignored) + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1); + + //! Animates this mesh's joints based on frame input + //! blend: {0-old position, 1-New position} + virtual void animateMesh(f32 frame, f32 blend); + + //! Preforms a software skin on this mesh based of joint positions + virtual void skinMesh(); + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const; + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box); + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! Gets joint count. + virtual u32 getJointCount() const; + + //! Gets the name of a joint. + virtual const c8* getJointName(u32 number) const; + + //! Gets a joint number from its name + virtual s32 getJointNumber(const c8* name) const; + + //! uses animation from another mesh + virtual bool useAnimationFrom(const ISkinnedMesh *mesh); + + //! Update Normals when Animating + //! False= Don't (default) + //! True = Update normals, slower + virtual void updateNormalsWhenAnimating(bool on); + + //! Sets Interpolation Mode + virtual void setInterpolationMode(E_INTERPOLATION_MODE mode); + + //! Recovers the joints from the mesh + virtual void recoverJointsFromMesh(core::array &JointChildSceneNodes); + + //! Tranfers the joint data to the mesh + virtual void transferJointsToMesh(const core::array &JointChildSceneNodes); + + //! Creates an array of joints from this mesh + virtual void createJoints(core::array &JointChildSceneNodes, IAnimatedMeshSceneNode* AnimatedMeshSceneNode, ISceneManager* SceneManager); + + + virtual void convertMeshToTangents(); + + + + + + //Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_ + + //these functions will use the needed arrays, set vaules, etc to help the loaders + + //! exposed for loaders to add mesh buffers + virtual core::array &getMeshBuffers(); + + //! alternative method for adding joints + virtual core::array &getAllJoints(); + + //! alternative method for adding joints + virtual const core::array &getAllJoints() const; + + //! loaders should call this after populating the mesh + virtual void finalize(); + + + + + virtual SSkinMeshBuffer *createBuffer(); + + virtual SJoint *createJoint(SJoint *parent=0); + + virtual SPositionKey *createPositionKey(SJoint *joint); + virtual SScaleKey *createScaleKey(SJoint *joint); + virtual SRotationKey *createRotationKey(SJoint *joint); + + virtual SWeight *createWeight(SJoint *joint); + + + + + +private: + + void checkForAnimation(); + + void normalizeWeights(); + + void buildAll_LocalAnimatedMatrices(); //public? + + void buildAll_GlobalAnimatedMatrices(SJoint *Joint=0, SJoint *ParentJoint=0); + + void getFrameData(f32 frame,SJoint *Node,core::vector3df &position, s32 &positionHint, core::vector3df &scale, s32 &scaleHint, core::quaternion &rotation, s32 &rotationHint); + + void CalculateGlobalMatrixes(SJoint *Joint,SJoint *ParentJoint); + + void SkinJoint(SJoint *Joint, SJoint *ParentJoint); + + void calculateTangents(core::vector3df& normal, + core::vector3df& tangent, core::vector3df& binormal, + core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3, + core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3); + + //void createSkelton_Helper(ISceneManager* SceneManager, core::array &JointChildSceneNodes, IAnimatedMeshSceneNode *AnimatedMeshSceneNode, ISceneNode* ParentNode, SJoint *ParentNode, SJoint *Node); + + + core::array *SkinningBuffers; //Meshbuffer to skin, default is to skin localBuffers + + core::array LocalBuffers; + + core::array AllJoints; + core::array RootJoints; + + bool HasAnimation; + + bool PreparedForSkinning; + + f32 AnimationFrames; + + f32 lastAnimatedFrame; + f32 lastSkinnedFrame; + bool BoneControlUsed; + + bool AnimateNormals; + + E_INTERPOLATION_MODE InterpolationMode; + + core::aabbox3d BoundingBox; + + core::array< core::array > Vertices_Moved; + }; + +} // end namespace scene +} // end namespace irr + +#endif + + + diff --git a/src/dep/src/irrlicht/CSkyBoxSceneNode.cpp b/src/dep/src/irrlicht/CSkyBoxSceneNode.cpp new file mode 100644 index 0000000..a636ab3 --- /dev/null +++ b/src/dep/src/irrlicht/CSkyBoxSceneNode.cpp @@ -0,0 +1,255 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSkyBoxSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, video::ITexture* left, + video::ITexture* right, video::ITexture* front, video::ITexture* back, ISceneNode* parent, ISceneManager* mgr, s32 id) +: ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CSkyBoxSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); + Box.MaxEdge.set(0,0,0); + Box.MinEdge.set(0,0,0); + + // create indices + + Indices[0] = 0; + Indices[1] = 1; + Indices[2] = 2; + Indices[3] = 3; + + // create material + + video::SMaterial mat; + mat.Lighting = false; + mat.ZBuffer = false; + mat.ZWriteEnable = false; + mat.TextureLayer[0].TextureWrap = video::ETC_CLAMP; + + /* Hey, I am no artist, but look at that + cool ASCII art I made! ;) + + -111 111 + /6--------/5 y + / | / | ^ z + / | 11-1 | | / + -11-1 3---------2 | |/ + | 7- - -| -4 1-11 *---->x + | -1-11 | / 3-------|2 + |/ | / | //| + 0---------1/ | // | + -1-1-1 1-1-1 |// | + 0--------1 + */ + + video::ITexture* tex = front; + if (!tex) tex = left; + if (!tex) tex = back; + if (!tex) tex = right; + if (!tex) tex = top; + if (!tex) tex = bottom; + + const f32 onepixel = tex?(1.0f / (tex->getSize().Width * 1.5f)) : 0.0f; + const f32 l = 10.0f; + const f32 t = 1.0f - onepixel; + const f32 o = 0.0f + onepixel; + + // create front side + + Material[0] = mat; + Material[0].setTexture(0, front); + Vertices[0] = video::S3DVertex(-l,-l,-l, 0,0,1, video::SColor(255,255,255,255), t, t); + Vertices[1] = video::S3DVertex( l,-l,-l, 0,0,1, video::SColor(255,255,255,255), o, t); + Vertices[2] = video::S3DVertex( l, l,-l, 0,0,1, video::SColor(255,255,255,255), o, o); + Vertices[3] = video::S3DVertex(-l, l,-l, 0,0,1, video::SColor(255,255,255,255), t, o); + + // create left side + + Material[1] = mat; + Material[1].setTexture(0, left); + Vertices[4] = video::S3DVertex( l,-l,-l, -1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[5] = video::S3DVertex( l,-l, l, -1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[6] = video::S3DVertex( l, l, l, -1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[7] = video::S3DVertex( l, l,-l, -1,0,0, video::SColor(255,255,255,255), t, o); + + // create back side + + Material[2] = mat; + Material[2].setTexture(0, back); + Vertices[8] = video::S3DVertex( l,-l, l, 0,0,-1, video::SColor(255,255,255,255), t, t); + Vertices[9] = video::S3DVertex(-l,-l, l, 0,0,-1, video::SColor(255,255,255,255), o, t); + Vertices[10] = video::S3DVertex(-l, l, l, 0,0,-1, video::SColor(255,255,255,255), o, o); + Vertices[11] = video::S3DVertex( l, l, l, 0,0,-1, video::SColor(255,255,255,255), t, o); + + // create right side + + Material[3] = mat; + Material[3].setTexture(0, right); + Vertices[12] = video::S3DVertex(-l,-l, l, 1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[13] = video::S3DVertex(-l,-l,-l, 1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[14] = video::S3DVertex(-l, l,-l, 1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[15] = video::S3DVertex(-l, l, l, 1,0,0, video::SColor(255,255,255,255), t, o); + + // create top side + + Material[4] = mat; + Material[4].setTexture(0, top); + Vertices[16] = video::S3DVertex( l, l,-l, 0,-1,0, video::SColor(255,255,255,255), t, t); + Vertices[17] = video::S3DVertex( l, l, l, 0,-1,0, video::SColor(255,255,255,255), o, t); + Vertices[18] = video::S3DVertex(-l, l, l, 0,-1,0, video::SColor(255,255,255,255), o, o); + Vertices[19] = video::S3DVertex(-l, l,-l, 0,-1,0, video::SColor(255,255,255,255), t, o); + + // create bottom side + + Material[5] = mat; + Material[5].setTexture(0, bottom); + Vertices[20] = video::S3DVertex( l,-l, l, 0,1,0, video::SColor(255,255,255,255), o, o); + Vertices[21] = video::S3DVertex( l,-l,-l, 0,1,0, video::SColor(255,255,255,255), t, o); + Vertices[22] = video::S3DVertex(-l,-l,-l, 0,1,0, video::SColor(255,255,255,255), t, t); + Vertices[23] = video::S3DVertex(-l,-l, l, 0,1,0, video::SColor(255,255,255,255), o, t); +} + + +//! renders the node. +void CSkyBoxSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + if ( !camera->isOrthogonal() ) + { + // draw perspective skybox + + core::matrix4 mat(AbsoluteTransformation); + mat.setTranslation(camera->getAbsolutePosition()); + + driver->setTransform(video::ETS_WORLD, mat); + + for (s32 i=0; i<6; ++i) + { + driver->setMaterial(Material[i]); + driver->drawIndexedTriangleFan(&Vertices[i*4], 4, Indices, 2); + } + } + else + { + // draw orthogonal skybox, + // simply choose one texture and draw it as 2d picture. + // there could be better ways to do this, but currently I think this is ok. + + core::vector3df lookVect = camera->getTarget() - camera->getAbsolutePosition(); + lookVect.normalize(); + core::vector3df absVect( core::abs_(lookVect.X), + core::abs_(lookVect.Y), + core::abs_(lookVect.Z)); + + int idx = 0; + + if ( absVect.X >= absVect.Y && absVect.X >= absVect.Z ) + { + // x direction + idx = lookVect.X > 0 ? 0 : 2; + } + else + if ( absVect.Y >= absVect.X && absVect.Y >= absVect.Z ) + { + // y direction + idx = lookVect.Y > 0 ? 4 : 5; + } + else + if ( absVect.Z >= absVect.X && absVect.Z >= absVect.Y ) + { + // z direction + idx = lookVect.Z > 0 ? 1 : 3; + } + + video::ITexture* tex = Material[idx].getTexture(0); + + if ( tex ) + { + core::rect rctDest(core::position2d(-1,0), driver->getCurrentRenderTargetSize()); + core::rect rctSrc(core::position2d(0,0), tex->getSize()); + + driver->draw2DImage(tex, rctDest, rctSrc); + } + } +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSkyBoxSceneNode::getBoundingBox() const +{ + return Box; +} + + +void CSkyBoxSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSkyBoxSceneNode::getMaterial(u32 i) +{ + return Material[i]; +} + + +//! returns amount of materials used by this scene node. +u32 CSkyBoxSceneNode::getMaterialCount() const +{ + return 6; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CSkyBoxSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CSkyBoxSceneNode* nb = new CSkyBoxSceneNode(0,0,0,0,0,0, newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + + for (u32 i=0; i<6; ++i) + nb->Material[i] = Material[i]; + + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSkyBoxSceneNode.h b/src/dep/src/irrlicht/CSkyBoxSceneNode.h new file mode 100644 index 0000000..9beb59a --- /dev/null +++ b/src/dep/src/irrlicht/CSkyBoxSceneNode.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SKY_BOX_SCENE_NODE_H_INCLUDED__ +#define __C_SKY_BOX_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + + // Skybox, rendered with zbuffer turned off, before all other nodes. + class CSkyBoxSceneNode : public ISceneNode + { + public: + + //! constructor + CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, video::ITexture* left, + video::ITexture* right, video::ITexture* front, video::ITexture* back, + ISceneNode* parent, ISceneManager* mgr, s32 id); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + core::aabbox3d Box; + u16 Indices[4]; + video::S3DVertex Vertices[4*6]; + video::SMaterial Material[6]; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSkyDomeSceneNode.cpp b/src/dep/src/irrlicht/CSkyDomeSceneNode.cpp new file mode 100644 index 0000000..9e3e1b4 --- /dev/null +++ b/src/dep/src/irrlicht/CSkyDomeSceneNode.cpp @@ -0,0 +1,172 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code for this scene node has been contributed by Anders la Cour-Harbo (alc) + +#include "CSkyDomeSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +/* horiRes and vertRes: + Controls the number of faces along the horizontal axis (30 is a good value) + and the number of faces along the vertical axis (8 is a good value). + + texturePercentage: + Only the top texturePercentage of the image is used, e.g. 0.8 uses the top 80% of the image, + 1.0 uses the entire image. This is useful as some landscape images have a small banner + at the bottom that you don't want. + + spherePercentage: + This controls how far around the sphere the sky dome goes. For value 1.0 you get exactly the upper + hemisphere, for 1.1 you get slightly more, and for 2.0 you get a full sphere. It is sometimes useful + to use a value slightly bigger than 1 to avoid a gap between some ground place and the sky. This + parameters stretches the image to fit the chosen "sphere-size". */ + +CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes, + f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CSkyDomeSceneNode"); + #endif + + f64 radius = 1000.0; /* Adjust this to get more or less perspective distorsion. */ + f64 azimuth, azimuth_step; + f64 elevation, elevation_step; + u32 k, c; + + video::S3DVertex vtx; + + AutomaticCullingState = scene::EAC_OFF; + + Buffer.Material.Lighting = false; + Buffer.Material.ZBuffer = false; + Buffer.Material.ZWriteEnable = false; + Buffer.Material.setTexture(0, sky); + Buffer.BoundingBox.MaxEdge.set(0,0,0); + Buffer.BoundingBox.MinEdge.set(0,0,0); + + azimuth_step = 2.*core::PI64/(f64)horiRes; + if (spherePercentage<0.) + spherePercentage=-spherePercentage; + if (spherePercentage>2.) + spherePercentage=2.; + elevation_step = spherePercentage*core::PI64/2./(f64)vertRes; + + Buffer.Vertices.set_used((horiRes+1)*(vertRes+1)); + Buffer.Indices.set_used(3*(2*vertRes-1)*horiRes); + + vtx.Color.set(255,255,255,255); + vtx.Normal.set(0.0f,0.0f,0.0f); + + c = 0; + for (k = 0, azimuth = 0; k <= horiRes; ++k) + { + elevation = core::PI64/2.; + for (u32 j = 0; j <= vertRes; ++j) + { + vtx.Pos.set((f32) (radius*cos(elevation)*sin(azimuth)), + (f32) (radius*sin(elevation)+50.0f), + (f32) (radius*cos(elevation)*cos(azimuth))); + + vtx.TCoords.set((f32)k/(f32)horiRes, (f32)j/(f32)vertRes*(f32)texturePercentage); + + Buffer.Vertices[c++] = vtx; + elevation -= elevation_step; + } + azimuth += azimuth_step; + } + + c = 0; + for (k = 0; k < horiRes; ++k) + { + Buffer.Indices[c++] = vertRes+2+(vertRes+1)*k; + Buffer.Indices[c++] = 1+(vertRes+1)*k; + Buffer.Indices[c++] = 0+(vertRes+1)*k; + + for (u32 j = 1; j < vertRes; ++j) + { + Buffer.Indices[c++] = vertRes+2+(vertRes+1)*k+j; + Buffer.Indices[c++] = 1+(vertRes+1)*k+j; + Buffer.Indices[c++] = 0+(vertRes+1)*k+j; + + Buffer.Indices[c++] = vertRes+1+(vertRes+1)*k+j; + Buffer.Indices[c++] = vertRes+2+(vertRes+1)*k+j; + Buffer.Indices[c++] = 0+(vertRes+1)*k+j; + } + } +} + + +//! destructor +CSkyDomeSceneNode::~CSkyDomeSceneNode() +{ +} + + +//! renders the node. +void CSkyDomeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + if ( !camera->isOrthogonal() ) + { + core::matrix4 mat(AbsoluteTransformation); + mat.setTranslation(camera->getAbsolutePosition()); + + driver->setTransform(video::ETS_WORLD, mat); + + driver->setMaterial(Buffer.Material); + driver->drawMeshBuffer(&Buffer); + } +} + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSkyDomeSceneNode::getBoundingBox() const +{ + return Buffer.BoundingBox; +} + + +void CSkyDomeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i) +{ + return Buffer.Material; +} + + +//! returns amount of materials used by this scene node. +u32 CSkyDomeSceneNode::getMaterialCount() const +{ + return 1; +} + + +} +} + diff --git a/src/dep/src/irrlicht/CSkyDomeSceneNode.h b/src/dep/src/irrlicht/CSkyDomeSceneNode.h new file mode 100644 index 0000000..8422c98 --- /dev/null +++ b/src/dep/src/irrlicht/CSkyDomeSceneNode.h @@ -0,0 +1,40 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code for this scene node has been contributed by Anders la Cour-Harbo (alc) + +#ifndef __C_SKY_DOME_SCENE_NODE_H_INCLUDED__ +#define __C_SKY_DOME_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +class CSkyDomeSceneNode : public ISceneNode +{ + public: + CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes, + f64 texturePercentage, f64 spherePercentage, ISceneNode* root, + ISceneManager* smgr, s32 id); + virtual ~CSkyDomeSceneNode(); + virtual void OnRegisterSceneNode(); + virtual void render(); + virtual const core::aabbox3d& getBoundingBox() const; + virtual video::SMaterial& getMaterial(u32 i); + virtual u32 getMaterialCount() const; + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; } + + private: + SMeshBuffer Buffer; +}; + + +} +} + +#endif + diff --git a/src/dep/src/irrlicht/CSoftware2MaterialRenderer.h b/src/dep/src/irrlicht/CSoftware2MaterialRenderer.h new file mode 100644 index 0000000..0ba49e0 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftware2MaterialRenderer.h @@ -0,0 +1,83 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" + +#include "IMaterialRenderer.h" +#include "CSoftwareDriver2.h" + +namespace irr +{ +namespace video +{ + +//! Base class for all internal Software2 material renderers +class CSoftware2MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CSoftware2MaterialRenderer(video::CSoftwareDriver2* driver) + : Driver(driver) + { + } + +protected: + + video::CSoftwareDriver2* Driver; +}; + +//! solid material renderer +class CSoftware2MaterialRenderer_SOLID : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_SOLID ( video::CSoftwareDriver2* driver ) + :CSoftware2MaterialRenderer ( driver ) {} + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return false; + } + +}; + + + +//! Transparent material renderer +class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR ( video::CSoftwareDriver2* driver ) + : CSoftware2MaterialRenderer ( driver ) {} + + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } + +}; + +//! unsupported material renderer +class CSoftware2MaterialRenderer_UNSUPPORTED : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_UNSUPPORTED ( video::CSoftwareDriver2* driver ) + : CSoftware2MaterialRenderer ( driver ) {} + + virtual s32 getRenderCapability() const { return 1; } + +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSoftwareDriver.cpp b/src/dep/src/irrlicht/CSoftwareDriver.cpp new file mode 100644 index 0000000..3409e49 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareDriver.cpp @@ -0,0 +1,918 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSoftwareDriver.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +#include "CSoftwareTexture.h" +#include "os.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CSoftwareDriver::CSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +: CNullDriver(io, windowSize), RenderTargetTexture(0), RenderTargetSurface(0), + CurrentTriangleRenderer(0), ZBuffer(0), Texture(0) +{ + #ifdef _DEBUG + setDebugName("CSoftwareDriver"); + #endif + + // create backbuffer + + BackBuffer = new CImage(ECF_A1R5G5B5, windowSize); + BackBuffer->fill(SColor(0)); + + // get presenter + + Presenter = presenter; + + // create z buffer + + ZBuffer = video::createZBuffer(BackBuffer->getDimension()); + + // create triangle renderers + + TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer); + TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer); + TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer); + TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer); + TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ(); + TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer); + + // select render target + + setRenderTarget(BackBuffer); + + // select the right renderer + + selectRightTriangleRenderer(); +} + + + +//! destructor +CSoftwareDriver::~CSoftwareDriver() +{ + // delete Backbuffer + BackBuffer->drop(); + + // delete triangle renderers + + for (s32 i=0; idrop(); + + // delete zbuffer + + if (ZBuffer) + ZBuffer->drop(); + + // delete current texture + + if (Texture) + Texture->drop(); + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + if (RenderTargetSurface) + RenderTargetSurface->drop(); +} + + + +//! switches to a triangle renderer +void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer) +{ + video::IImage* s = 0; + if (Texture) + s = ((CSoftwareTexture*)Texture)->getTexture(); + + CurrentTriangleRenderer = TriangleRenderers[renderer]; + CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true); + CurrentTriangleRenderer->setTexture(s); + CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); +} + + +//! void selects the right triangle renderer based on the render states. +void CSoftwareDriver::selectRightTriangleRenderer() +{ + + ETriangleRenderer renderer = ETR_FLAT; + + if (Texture) + { + if (!Material.GouraudShading) + renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE; + else + { + if (Material.Wireframe) + renderer = ETR_TEXTURE_GOURAUD_WIRE; + else + { + if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR || + Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL || + Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA) + { + // simply draw all transparent stuff with the same renderer. at + // least it is transparent then. + renderer = ETR_TEXTURE_GOURAUD_ADD; + } + else + if (!Material.ZBuffer && !Material.ZWriteEnable) + renderer = ETR_TEXTURE_GOURAUD_NOZ; + else + { + renderer = ETR_TEXTURE_GOURAUD; + } + } + } + } + else + { + if (!Material.GouraudShading) + renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE; + else + renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE; + } + + switchToTriangleRenderer(renderer); +} + + + + +//! presents the rendered scene on the screen, returns false if failed +bool CSoftwareDriver::endScene( s32 windowId, core::rect* sourceRect ) +{ + CNullDriver::endScene(); + + Presenter->present(BackBuffer, windowId, sourceRect ); + return true; +} + + + +//! queries the features of the driver, returns true if feature is available +bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_RENDER_TO_TARGET: + return true; + default: + return false; + }; +} + + + +//! sets transformation +void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + TransformationMatrix[state] = mat; +} + + + + +//! sets the current Texture +bool CSoftwareDriver::setTexture(video::ITexture* texture) +{ + if (texture && texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (Texture) + Texture->drop(); + + Texture = texture; + + if (Texture) + Texture->grab(); + + selectRightTriangleRenderer(); + return true; +} + + + +//! sets a material +void CSoftwareDriver::setMaterial(const SMaterial& material) +{ + Material = material; + + for (u32 i = 0; i < 1; ++i) + { + setTexture(Material.getTexture(i)); + setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), + material.getTextureMatrix(i)); + } +} + + +//! clears the zbuffer +bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color); + + if (backBuffer) + BackBuffer->fill( color ); + + if (ZBuffer && zBuffer) + ZBuffer->clear(); + + return true; +} + + +//! sets a render target +bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + if (texture && texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + RenderTargetTexture = texture; + + if (RenderTargetTexture) + { + RenderTargetTexture->grab(); + setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture()); + } + else + { + setRenderTarget(BackBuffer); + } + + if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) + { + if (clearZBuffer) + ZBuffer->clear(); + + if (clearBackBuffer) + ((video::CImage*)RenderTargetSurface)->fill( color ); + } + + return true; +} + + +//! sets a render target +void CSoftwareDriver::setRenderTarget(video::CImage* image) +{ + if (RenderTargetSurface) + RenderTargetSurface->drop(); + + RenderTargetSurface = image; + RenderTargetSize.Width = 0; + RenderTargetSize.Height = 0; + Render2DTranslation.X = 0; + Render2DTranslation.Y = 0; + + if (RenderTargetSurface) + { + RenderTargetSurface->grab(); + RenderTargetSize = RenderTargetSurface->getDimension(); + } + + setViewPort(core::rect(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); + + if (ZBuffer) + ZBuffer->setSize(RenderTargetSize); +} + + + +//! sets a viewport +void CSoftwareDriver::setViewPort(const core::rect& area) +{ + ViewPort = area; + + //TODO: the clipping is not correct, because the projection is affected. + // to correct this, ViewPortSize and Render2DTranslation will have to be corrected. + core::rect rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); + ViewPort.clipAgainst(rendert); + + ViewPortSize = ViewPort.getSize(); + Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X; + Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y; + + if (CurrentTriangleRenderer) + CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); +} + + +//! draws a vertex primitive list +void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + const u16* indexPointer=0; + core::array newBuffer; + switch (pType) + { + case scene::EPT_LINE_STRIP: + { + switch (vType) + { + case EVT_STANDARD: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, + ((S3DVertex*)vertices)[indexList[i+1]].Pos, + ((S3DVertex*)vertices)[indexList[i]].Color); + } + break; + case EVT_2TCOORDS: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); + } + break; + case EVT_TANGENTS: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i]].Color); + } + break; + } + } + return; + case scene::EPT_LINE_LOOP: + drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP); + switch (vType) + { + case EVT_STANDARD: + draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertex*)vertices)[indexList[0]].Pos, + ((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color); + break; + case EVT_2TCOORDS: + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[0]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color); + break; + case EVT_TANGENTS: + draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[0]].Pos, + ((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color); + break; + } + return; + case scene::EPT_LINES: + { + switch (vType) + { + case EVT_STANDARD: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, + ((S3DVertex*)vertices)[indexList[i+1]].Pos, + ((S3DVertex*)vertices)[indexList[i]].Color); + } + break; + case EVT_2TCOORDS: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); + } + break; + case EVT_TANGENTS: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i]].Color); + } + break; + } + } + return; + case scene::EPT_TRIANGLE_FAN: + { + // TODO: don't convert fan to list + newBuffer.reallocate(primitiveCount*3); + for( u32 t=0; t +void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices, + s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + if (!RenderTargetSurface || !ZBuffer || !triangleCount) + return; + + if (!checkPrimitiveCount(triangleCount)) + return; + + // arrays for storing clipped vertices + core::array clippedVertices; + core::array clippedIndices; + + // calculate inverse world transformation + core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]); + worldinv.makeInverse(); + + // calculate view frustum planes + scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]); + + // copy and transform clipping planes ignoring far plane + core::plane3df planes[5]; // ordered by near, left, right, bottom, top + for (int p=0; p<5; ++p) + worldinv.transformPlane(frustum.planes[p+1], planes[p]); + + core::EIntersectionRelation3D inout[3]; // is point in front or back of plane? + + // temporary buffer for vertices to be clipped by all planes + core::array tClpBuf; + int t; + + int i; + for (i=0; i textureSize(0,0); + f32 zDiv; + + if (Texture) + textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension(); + + f32 transformedPos[4]; // transform all points in the list + + core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]); + matrix *= TransformationMatrix[ETS_VIEW]; + matrix *= TransformationMatrix[ETS_WORLD]; + + s32 ViewTransformWidth = (ViewPortSize.Width>>1); + s32 ViewTransformHeight = (ViewPortSize.Height>>1); + + for (i=0; i<(int)clippedVertices.size(); ++i) + { + transformedPos[0] = currentVertex->Pos.X; + transformedPos[1] = currentVertex->Pos.Y; + transformedPos[2] = currentVertex->Pos.Z; + transformedPos[3] = 1.0f; + + matrix.multiplyWith1x4Matrix(transformedPos); + zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]); + + tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X)); + tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv))); + tp->Color = currentVertex->Color.toA1R5G5B5(); + tp->ZValue = (TZBufferType)(32767.0f * zDiv); + + tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width); + tp->TCoords.X <<= 8; + tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height); + tp->TCoords.Y <<= 8; + + ++currentVertex; + ++tp; + } + + // draw all transformed points from the index list + CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0], + clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3); +} + + + +//! Draws a 3d line. +void CSoftwareDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + core::vector3df vect = start.crossProduct(end); + vect.normalize(); + vect *= Material.Thickness*0.3f; + + S3DVertex vtx[4]; + + vtx[0].Color = color; + vtx[1].Color = color; + vtx[2].Color = color; + vtx[3].Color = color; + + vtx[0].Pos = start; + vtx[1].Pos = end; + + vtx[2].Pos = start + vect; + vtx[3].Pos = end + vect; + + u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1}; + + drawIndexedTriangleList(vtx, 4, idx, 4); +} + + + +//! clips a triangle against the viewing frustum +void CSoftwareDriver::clipTriangle(f32* transformedPos) +{ +} + + + +//! creates the clipping planes from the matrix +void CSoftwareDriver::createPlanes(const core::matrix4& mat) +{ + Frustum = scene::SViewFrustum(mat); +} + + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CSoftwareDriver::OnResize(const core::dimension2d& size) +{ + // make sure width and height are multiples of 2 + core::dimension2d realSize(size); + + if (realSize.Width % 2) + realSize.Width += 1; + + if (realSize.Height % 2) + realSize.Height += 1; + + if (ScreenSize != realSize) + { + if (ViewPort.getWidth() == ScreenSize.Width && + ViewPort.getHeight() == ScreenSize.Height) + { + ViewPort = core::rect(core::position2d(0,0), realSize); + } + + ScreenSize = realSize; + + bool resetRT = (RenderTargetSurface == BackBuffer); + + BackBuffer->drop(); + BackBuffer = new CImage(ECF_A1R5G5B5, realSize); + + if (resetRT) + setRenderTarget(BackBuffer); + } +} + +//! returns the current render target size +const core::dimension2d& CSoftwareDriver::getCurrentRenderTargetSize() const +{ + return RenderTargetSize; +} + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (texture) + { + if (texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); + return; + } + + if (useAlphaChannelOfTexture) + ((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha( + ((CImage*)RenderTargetSurface), destPos, sourceRect, color, clipRect); + else + ((CSoftwareTexture*)texture)->getImage()->copyTo( + ((CImage*)RenderTargetSurface), destPos, sourceRect, clipRect); + } +} + + + +//! Draws a 2d line. +void CSoftwareDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + ((CImage*)RenderTargetSurface)->drawLine(start, end, color ); +} + + + +//! draw a 2d rectangle +void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip) +{ + if (clip) + { + core::rect p(pos); + + p.clipAgainst(*clip); + + if(!p.isValid()) + return; + + ((CImage*)RenderTargetSurface)->drawRectangle(p, color); + } + else + { + if(!pos.isValid()) + return; + + ((CImage*)RenderTargetSurface)->drawRectangle(pos, color); + } +} + + +//!Draws an 2d rectangle with a gradient. +void CSoftwareDriver::draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + // TODO: implement + draw2DRectangle(colorLeftUp, pos, clip); +} + + +//! \return Returns the name of the video driver. Example: In case of the Direct3D8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CSoftwareDriver::getName() const +{ + return L"Irrlicht Software Device 1.0"; +} + + +//! Returns type of video driver +E_DRIVER_TYPE CSoftwareDriver::getDriverType() const +{ + return EDT_SOFTWARE; +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return TransformationMatrix[state]; +} + +//! Creates a render target texture. +ITexture* CSoftwareDriver::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + CImage* img = new CImage(video::ECF_A1R5G5B5, size); + ITexture* tex = new CSoftwareTexture(img, name, true); + img->drop(); + return tex; +} + + +//! Clears the ZBuffer. +void CSoftwareDriver::clearZBuffer() +{ + if (ZBuffer) + ZBuffer->clear(); +} + + +//! Returns an image created from the last rendered frame. +IImage* CSoftwareDriver::createScreenShot() +{ + return new CImage(BackBuffer->getColorFormat(), BackBuffer); +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CSoftwareDriver::getMaximalPrimitiveCount() const +{ + return 0x00800000; +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! creates a video driver +IVideoDriver* createSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CSoftwareDriver(windowSize, fullscreen, io, presenter); + #else + return 0; + #endif +} + + +} // end namespace video +} // end namespace irr diff --git a/src/dep/src/irrlicht/CSoftwareDriver.h b/src/dep/src/irrlicht/CSoftwareDriver.h new file mode 100644 index 0000000..f925ce8 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareDriver.h @@ -0,0 +1,167 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_SOFTWARE_H_INCLUDED__ +#define __C_VIDEO_SOFTWARE_H_INCLUDED__ + +#include "ITriangleRenderer.h" +#include "CNullDriver.h" +#include "SViewFrustum.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + class CSoftwareDriver : public CNullDriver + { + public: + + //! constructor + CSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter); + + //! destructor + virtual ~CSoftwareDriver(); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene( s32 windowId = 0, core::rect* sourceRect=0 ); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! returns size of the current render target + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! draws a vertex primitive list + void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! \return Returns the name of the video driver. Example: In case of the Direct3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Creates a render target texture. + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + protected: + + struct splane + { + core::vector3df Normal; + f32 Dist; + }; + + //! sets a render target + void setRenderTarget(video::CImage* image); + + //! sets the current Texture + bool setTexture(video::ITexture* texture); + + video::CImage* BackBuffer; + video::IImagePresenter* Presenter; + + //! switches to a triangle renderer + void switchToTriangleRenderer(ETriangleRenderer renderer); + + //! void selects the right triangle renderer based on the render states. + void selectRightTriangleRenderer(); + + //! clips a triangle agains the viewing frustum + void clipTriangle(f32* transformedPos); + + //! creates the clipping planes from the view matrix + void createPlanes(const core::matrix4& mat); + + template + void drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices, + s32 vertexCount, const u16* indexList, s32 triangleCount); + + core::array TransformedPoints; + + video::ITexture* RenderTargetTexture; + video::IImage* RenderTargetSurface; + core::position2d Render2DTranslation; + core::dimension2d RenderTargetSize; + core::dimension2d ViewPortSize; + + core::matrix4 TransformationMatrix[ETS_COUNT]; + + ITriangleRenderer* CurrentTriangleRenderer; + ITriangleRenderer* TriangleRenderers[ETR_COUNT]; + ETriangleRenderer CurrentRenderer; + + IZBuffer* ZBuffer; + + video::ITexture* Texture; + scene::SViewFrustum Frustum; + + SMaterial Material; + + splane planes[6]; // current planes of the view frustum + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CSoftwareDriver2.cpp b/src/dep/src/irrlicht/CSoftwareDriver2.cpp new file mode 100644 index 0000000..d8c759c --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareDriver2.cpp @@ -0,0 +1,1919 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSoftwareDriver2.h" + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_helper.h" +#include "CSoftwareTexture2.h" +#include "CSoftware2MaterialRenderer.h" +#include "S3DVertex.h" +#include "S4DVertex.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CSoftwareDriver2::CSoftwareDriver2(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), + RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0), + DepthBuffer(0), CurrentOut ( 12 * 2, 128 ), Temp ( 12 * 2, 128 ) +{ + #ifdef _DEBUG + setDebugName("CSoftwareDriver2"); + #endif + + Texture[0] = 0; + Texture[1] = 0; + Texmap[0].Texture = 0; + Texmap[1].Texture = 0; + + // create backbuffer + BackBuffer = new CImage(ECF_SOFTWARE2, windowSize); + BackBuffer->fill(SColor(0)); + + // create z buffer + + DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension()); + + // create triangle renderers + + irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) ); + //BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer); + //BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer); + BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(DepthBuffer); + BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(DepthBuffer ); + BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(DepthBuffer ); + //BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer); + //BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer); + //BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP] = createTriangleRendererTextureLightMap2_M1(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M2] = createTriangleRendererTextureLightMap2_M2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M4] = createTriangleRendererGTextureLightMap2_M4(DepthBuffer); + BurningShader[ETR_TEXTURE_LIGHTMAP_M4] = createTriangleRendererTextureLightMap2_M4(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD] = createTriangleRendererTextureLightMap2_Add(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_DETAIL_MAP] = createTriangleRendererTextureDetailMap2(DepthBuffer); + + BurningShader[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_NOZ] = createTRTextureGouraudNoZ2(); + BurningShader[ETR_TEXTURE_GOURAUD_ADD] = createTRTextureGouraudAdd2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_ADD_NO_Z] = createTRTextureGouraudAddNoZ2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD_VERTEX_ALPHA] = createTriangleRendererTextureVertexAlpha2 ( DepthBuffer ); + + BurningShader[ETR_TEXTURE_GOURAUD_ALPHA] = createTRTextureGouraudAlpha(DepthBuffer ); + BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ( DepthBuffer ); + + BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( DepthBuffer ); + + + // add the same renderer for all solid types + CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this); + CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this); + CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this ); + + //!TODO: addMaterialRenderer depends on pushing order.... + addMaterialRenderer ( smr ); // EMT_SOLID + addMaterialRenderer ( smr ); // EMT_SOLID_2_LAYER, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP, + addMaterialRenderer ( tmr ); // EMT_LIGHTMAP_ADD, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M2, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M4, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4, + addMaterialRenderer ( smr ); // EMT_DETAIL_MAP, + addMaterialRenderer ( umr ); // EMT_SPHERE_MAP, + addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL_REF, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER, + addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_SOLID, + addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( umr ); // EMT_PARALLAX_MAP_SOLID, + addMaterialRenderer ( umr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( umr ); // EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( tmr ); // EMT_ONETEXTURE_BLEND + + smr->drop (); + tmr->drop (); + umr->drop (); + + + // select render target + + setRenderTarget(BackBuffer); + + + Global_AmbientLight.set ( 0.f, 0.f, 0.f, 0.f ); + + // select the right renderer + setCurrentShader(); + +} + + + +//! destructor +CSoftwareDriver2::~CSoftwareDriver2() +{ + // delete Backbuffer + BackBuffer->drop(); + + // delete triangle renderers + + for (s32 i=0; idrop(); + + // delete zbuffer + + if (DepthBuffer) + DepthBuffer->drop(); + + // delete current texture + + if ( Texture[0] ) + Texture[0]->drop(); + + if ( Texture[1] ) + Texture[1]->drop(); + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + if (RenderTargetSurface) + RenderTargetSurface->drop(); +} + + + +//! void selects the right triangle renderer based on the render states. +void CSoftwareDriver2::setCurrentShader() +{ + EBurningFFShader shader = ETR_TEXTURE_GOURAUD; + + bool zMaterialTest = true; + switch ( Material.org.MaterialType ) + { + case EMT_ONETEXTURE_BLEND: + shader = ETR_TEXTURE_BLEND; + zMaterialTest = false; + break; + + case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: + case EMT_TRANSPARENT_ALPHA_CHANNEL: + if ( Material.org.ZBuffer ) + { + shader = ETR_TEXTURE_GOURAUD_ALPHA; + } + else + { + shader = ETR_TEXTURE_GOURAUD_ALPHA_NOZ; + } + zMaterialTest = false; + break; + + case EMT_TRANSPARENT_ADD_COLOR: + if ( Material.org.ZBuffer ) + { + shader = ETR_TEXTURE_GOURAUD_ADD; + } + else + { + shader = ETR_TEXTURE_GOURAUD_ADD_NO_Z; + } + zMaterialTest = false; + break; + + case EMT_TRANSPARENT_VERTEX_ALPHA: + shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA; + break; + + case EMT_LIGHTMAP: + case EMT_LIGHTMAP_LIGHTING: + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP; + break; + + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_LIGHTING_M2: + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2; + break; + + case EMT_LIGHTMAP_LIGHTING_M4: + if ( Material.org.getTexture(1) ) + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4; + break; + case EMT_LIGHTMAP_M4: + if ( Material.org.getTexture(1) ) + shader = ETR_TEXTURE_LIGHTMAP_M4; + break; + + case EMT_LIGHTMAP_ADD: + if ( Material.org.getTexture(1) ) + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD; + break; + + case EMT_DETAIL_MAP: + shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP; + break; + + default: + break; + + } + + if ( zMaterialTest && !Material.org.ZBuffer && !Material.org.ZWriteEnable) + { + shader = ETR_TEXTURE_GOURAUD_NOZ; + } + + if ( 0 == Material.org.getTexture(0) ) + { + shader = ETR_GOURAUD; + } + + if ( Material.org.Wireframe ) + { + shader = ETR_TEXTURE_GOURAUD_WIRE; + } + + // switchToTriangleRenderer + CurrentShader = BurningShader[shader]; + if ( CurrentShader ) + { + CurrentShader->setZCompareFunc ( Material.org.ZBuffer ); + switch ( shader ) + { + case ETR_TEXTURE_GOURAUD_ALPHA: + case ETR_TEXTURE_GOURAUD_ALPHA_NOZ: + CurrentShader->setParam ( 0, Material.org.MaterialTypeParam ); + break; + + case EMT_ONETEXTURE_BLEND: + { + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + unpack_texureBlendFunc ( srcFact, dstFact, modulate, Material.org.MaterialTypeParam ); + CurrentShader->setParam ( 0, Material.org.MaterialTypeParam ); + } + break; + default: + break; + } + + CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); + } +} + + + +//! queries the features of the driver, returns true if feature is available +bool CSoftwareDriver2::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { +#ifdef SOFTWARE_DRIVER_2_BILINEAR + case EVDF_BILINEAR_FILTER: + return true; +#endif +#ifdef SOFTWARE_DRIVER_2_MIPMAPPING + case EVDF_MIP_MAP: + return true; +#endif + case EVDF_RENDER_TO_TARGET: + case EVDF_MULTITEXTURE: + case EVDF_HARDWARE_TL: + return true; + + default: + return false; + } +} + + + +//! sets transformation +void CSoftwareDriver2::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + Transformation[state].m = mat; + Transformation[state].isIdentity = mat.isIdentity(); + + switch ( state ) + { + case ETS_VIEW: + Transformation[ETS_VIEW_PROJECTION].m.setbyproduct_nocheck ( + Transformation[ETS_PROJECTION].m, + Transformation[ETS_VIEW].m + ); + break; + + case ETS_WORLD: + if ( Transformation[state].isIdentity ) + { + Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION]; + } + else + { + Transformation[ETS_CURRENT].m.setbyproduct_nocheck ( + Transformation[ETS_VIEW_PROJECTION].m, + Transformation[ETS_WORLD].m + ); + } + Transformation[ETS_CURRENT].isIdentity = 0; + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + if ( Material.org.Lighting ) + { + if ( Transformation[state].isIdentity ) + { + Transformation[ETS_WORLD_VIEW] = Transformation[ETS_VIEW]; + } + else + { + Transformation[ETS_WORLD_VIEW].m.setbyproduct_nocheck ( + Transformation[ETS_VIEW].m, + Transformation[ETS_WORLD].m + ); + } + + core::matrix4 m2 ( Transformation[ETS_WORLD_VIEW].m ); + m2.makeInverse (); + m2.getTransposed ( Transformation[ETS_WORLD_VIEW_INVERSE_TRANSPOSED].m ); + } +#endif + break; + default: + break; + } +} + + + +//! sets the current Texture +bool CSoftwareDriver2::setTexture(u32 stage, video::ITexture* texture) +{ + if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (Texture[stage]) + Texture[stage]->drop(); + + Texture[stage] = texture; + + if (Texture[stage]) + Texture[stage]->grab(); + + if (Texture[stage]) + Texmap[stage].Texture = (video::CSoftwareTexture2*) Texture[stage]; + + setCurrentShader(); + return true; +} + + + +//! sets a material +void CSoftwareDriver2::setMaterial(const SMaterial& material) +{ + Material.org = material; + + Material.AmbientColor.setA8R8G8B8 ( Material.org.AmbientColor.color ); + Material.DiffuseColor.setA8R8G8B8 ( Material.org.DiffuseColor.color ); + Material.EmissiveColor.setA8R8G8B8 ( Material.org.EmissiveColor.color ); + Material.SpecularColor.setA8R8G8B8 ( Material.org.SpecularColor.color ); + + Material.SpecularEnabled = Material.org.Shininess != 0.f; + if (Material.SpecularEnabled) + Material.org.NormalizeNormals = true; + + for (u32 i = 0; i < 2; ++i) + { + setTexture( i, Material.org.getTexture(i) ); + setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), + material.getTextureMatrix(i)); + } +} + + + +//! clears the zbuffer +bool CSoftwareDriver2::beginScene(bool backBuffer, bool zBuffer, SColor color) +{ + + CNullDriver::beginScene(backBuffer, zBuffer, color); + + if (backBuffer) + BackBuffer->fill( color ); + + if (DepthBuffer && zBuffer) + DepthBuffer->clear(); + + return true; +} + +//! presents the rendered scene on the screen, returns false if failed +bool CSoftwareDriver2::endScene( s32 windowId, core::rect* sourceRect ) +{ + CNullDriver::endScene(); + + Presenter->present(BackBuffer, windowId, sourceRect ); + + return true; +} + + + + +//! sets a render target +bool CSoftwareDriver2::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + RenderTargetTexture = texture; + + if (RenderTargetTexture) + { + RenderTargetTexture->grab(); + setRenderTarget(((CSoftwareTexture2*)RenderTargetTexture)->getTexture()); + } + else + { + setRenderTarget(BackBuffer); + } + + if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) + { + if (clearZBuffer) + DepthBuffer->clear(); + + if (clearBackBuffer) + ((video::CImage*)RenderTargetSurface)->fill( color ); + } + + return true; +} + + +//! sets a render target +void CSoftwareDriver2::setRenderTarget(video::CImage* image) +{ + if (RenderTargetSurface) + RenderTargetSurface->drop(); + + RenderTargetSurface = image; + RenderTargetSize.Width = 0; + RenderTargetSize.Height = 0; + + if (RenderTargetSurface) + { + RenderTargetSurface->grab(); + RenderTargetSize = RenderTargetSurface->getDimension(); + } + + setViewPort(core::rect(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); + + if (DepthBuffer) + DepthBuffer->setSize(RenderTargetSize); +} + + + +//! sets a viewport +void CSoftwareDriver2::setViewPort(const core::rect& area) +{ + ViewPort = area; + + core::rect rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); + ViewPort.clipAgainst(rendert); + + Transformation [ ETS_CLIPSCALE ].m.buildNDCToDCMatrix ( ViewPort, 1 ); + + + if (CurrentShader) + CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); +} + +/* + generic plane clipping in homogenous coordinates + special case ndc frustum <-w,w>,<-w,w>,<-w,w> + can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w +*/ + +const sVec4 CSoftwareDriver2::NDCPlane[6] = +{ + sVec4( 0.f, 0.f, -1.f, -1.f ), // near + sVec4( 0.f, 0.f, 1.f, -1.f ), // far + sVec4( 1.f, 0.f, 0.f, -1.f ), // left + sVec4( -1.f, 0.f, 0.f, -1.f ), // right + sVec4( 0.f, 1.f, 0.f, -1.f ), // bottom + sVec4( 0.f, -1.f, 0.f, -1.f ) // top +}; + + + +/* + test a vertex if it's inside the standard frustum + + this is the generic one.. + + f32 dotPlane; + for ( u32 i = 0; i!= 6; ++i ) + { + dotPlane = v->Pos.dotProduct ( NDCPlane[i] ); + setbit ( flag, dotPlane <= 0.f, 1 << i ); + } + + // this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w> + setbits ( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 ); + setbits ( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 ); + setbits ( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 ); + setbits ( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 ); + setbits ( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 ); + setbits ( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 ); + +*/ +#ifdef _MSC_VER + +REALINLINE u32 CSoftwareDriver2::clipToFrustumTest ( const s4DVertex * v ) const +{ + f32 test[6]; + u32 flag; + const f32 w = - v->Pos.w; + + // a conditional move is needed....FCOMI ( but we don't have it ) + // so let the fpu calculate and write it back. + // cpu makes the compare, interleaving + + test[0] = v->Pos.z + w; + test[1] = -v->Pos.z + w; + test[2] = v->Pos.x + w; + test[3] = -v->Pos.x + w; + test[4] = v->Pos.y + w; + test[5] = -v->Pos.y + w; + + flag = (IR ( test[0] ) ) >> 31; + flag |= (IR ( test[1] ) & 0x80000000 ) >> 30; + flag |= (IR ( test[2] ) & 0x80000000 ) >> 29; + flag |= (IR ( test[3] ) & 0x80000000 ) >> 28; + flag |= (IR ( test[4] ) & 0x80000000 ) >> 27; + flag |= (IR ( test[5] ) & 0x80000000 ) >> 26; + +/* + flag = F32_LOWER_EQUAL_0 ( test[0] ); + flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1; + flag |= F32_LOWER_EQUAL_0 ( test[2] ) << 2; + flag |= F32_LOWER_EQUAL_0 ( test[3] ) << 3; + flag |= F32_LOWER_EQUAL_0 ( test[4] ) << 4; + flag |= F32_LOWER_EQUAL_0 ( test[5] ) << 5; +*/ + return flag; +} + +#else + + +REALINLINE u32 CSoftwareDriver2::clipToFrustumTest ( const s4DVertex * v ) const +{ + u32 flag = 0; + for ( u32 i = 0; i!= 6; ++i ) + { + core::setbit ( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i ); + } + return flag; +} + +#endif // _MSC_VER + +u32 CSoftwareDriver2::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ) +{ + u32 outCount = 0; + s4DVertex * out = dest; + + const s4DVertex * a; + const s4DVertex * b = source; + + f32 bDotPlane; + + bDotPlane = b->Pos.dotProduct ( plane ); + + for( u32 i = 1; i < inCount + 1; ++i) + { + const s32 condition = i - inCount; + const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1; + + a = &source[ index ]; + + // current point inside + if ( a->Pos.dotProduct ( plane ) <= 0.f ) + { + // last point outside + if ( F32_GREATER_0 ( bDotPlane ) ) + { + // intersect line segment with plane + out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); + out += 2; + outCount += 1; + } + + // copy current to out + //*out = *a; + irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 ); + b = out; + + out += 2; + outCount += 1; + } + else + { + // current point outside + + if ( F32_LOWER_EQUAL_0 ( bDotPlane ) ) + { + // previous was inside + // intersect line segment with plane + out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); + out += 2; + outCount += 1; + } + // pointer + b = a; + } + + bDotPlane = b->Pos.dotProduct ( plane ); + + } + + return outCount; +} + + +u32 CSoftwareDriver2::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn ) +{ + u32 vOut = vIn; + + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] ); + return vOut; +} + +/*! + Part I: + apply Clip Scale matrix + From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC ) + + Part II: + Project homogeneous vector + homogeneous to non-homogenous coordinates ( dividebyW ) + + Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A ) + Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w ) + + + replace w/w by 1/w +*/ +inline void CSoftwareDriver2::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const +{ + u32 g; + + for ( g = 0; g != vIn; g += 2 ) + { + if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) + continue; + + dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; + + const f32 w = source[g].Pos.w; + const f32 iw = core::reciprocal ( w ); + + // to device coordinates + dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ].m[ 0] + w * Transformation [ ETS_CLIPSCALE ].m[12] ); + dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ].m[ 5] + w * Transformation [ ETS_CLIPSCALE ].m[13] ); + +#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER + dest[g].Pos.z = iw * source[g].Pos.z; +#endif + + #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dest[g].Color[0] = source[g].Color[0] * iw; + #else + dest[g].Color[0] = source[g].Color[0]; + #endif + + #endif + + dest[g].Pos.w = iw; + + } + +} + + +inline void CSoftwareDriver2::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const +{ + u32 g; + + for ( g = 0; g != size; g += 1 ) + { + s4DVertex * a = (s4DVertex*) v[g]; + + if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) + continue; + + a[1].flag = a->flag | VERTEX4D_PROJECTED; + + // project homogenous vertex, store 1/w + const f32 w = a->Pos.w; + const f32 iw = core::reciprocal ( w ); + + // to device coordinates + a[1].Pos.x = iw * ( a->Pos.x * Transformation [ ETS_CLIPSCALE ].m[ 0] + w * Transformation [ ETS_CLIPSCALE ].m[12] ); + a[1].Pos.y = iw * ( a->Pos.y * Transformation [ ETS_CLIPSCALE ].m[ 5] + w * Transformation [ ETS_CLIPSCALE ].m[13] ); + +#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER + a[1].Pos.z = a->Pos.z * iw; +#endif + + #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + a[1].Color[0] = a->Color[0] * iw; + #else + a[1].Color[0] = a->Color[0]; + #endif + #endif + + a[1].Pos.w = iw; + + } + +} + + +/*! + crossproduct in projected 2D -> screen area triangle +*/ +inline f32 CSoftwareDriver2::screenarea ( const s4DVertex *v ) const +{ + return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) - + ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) ); +} + + +/*! +*/ +inline f32 CSoftwareDriver2::texelarea ( const s4DVertex *v, int tex ) const +{ + f32 x0,y0, x1,y1, z; + + x0 = v[2].Tex[tex].x - v[0].Tex[tex].x; + y0 = v[2].Tex[tex].y - v[0].Tex[tex].y; + x1 = v[4].Tex[tex].x - v[0].Tex[tex].x; + y1 = v[4].Tex[tex].y - v[0].Tex[tex].y; + + z = x0*y1 - x1*y0; + + const core::dimension2d &d = Texmap[tex].Texture->getMaxSize(); + z *= d.Height; + z *= d.Width; + return z; +} + +/*! + crossproduct in projected 2D +*/ +inline f32 CSoftwareDriver2::screenarea2 ( const s4DVertex **v ) const +{ + return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) - + ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) ); +} + +/*! +*/ +inline f32 CSoftwareDriver2::texelarea2 ( const s4DVertex **v, s32 tex ) const +{ + f32 z; + + z = (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * + (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) + - (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * + (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) + ; + + const core::dimension2d &d = Texmap[tex].Texture->getMaxSize(); + z *= d.Height; + z *= d.Width; + return z; +} + + + + +/*! +*/ +inline void CSoftwareDriver2::select_polygon_mipmap ( s4DVertex *v, u32 vIn, s32 tex ) +{ + f32 f[2]; + const core::dimension2d& dim = Texmap[tex].Texture->getSize(); + + f[0] = (f32) dim.Width; + f[1] = (f32) dim.Height; + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + for ( u32 g = 0; g != vIn; g += 2 ) + { + (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0]; + (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1]; + } +#else + for ( u32 g = 0; g != vIn; g += 2 ) + { + (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0]; + (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1]; + } +#endif +} + +inline void CSoftwareDriver2::select_polygon_mipmap2 ( s4DVertex **v, s32 tex ) const +{ + f32 f[2]; + const core::dimension2d& dim = Texmap[tex].Texture->getSize(); + + f[0] = (f32) dim.Width; + f[1] = (f32) dim.Height; + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0]; + (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1]; + + (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0]; + (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1]; + + (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0]; + (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1]; + +#else + (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0]; + (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1]; + + (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0]; + (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1]; + + (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0]; + (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1]; +#endif +} + +// Vertex Cache +const SVSize CSoftwareDriver2::vSize[] = +{ + { VERTEX4D_FORMAT_0, sizeof(S3DVertex),1 }, + { VERTEX4D_FORMAT_1, sizeof(S3DVertex2TCoords),2 }, + { VERTEX4D_FORMAT_2, sizeof(S3DVertexTangents),2 } +}; + + + +/*! + fill a cache line with transformed, light and clipp test triangles +*/ +void CSoftwareDriver2::VertexCache_fill(const u32 sourceIndex, + const u32 destIndex) +{ + u8 * source; + s4DVertex *dest; + + source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch ); + + // it's a look ahead so we never hit it.. + // but give priority... + //VertexCache.info[ destIndex ].hit = hitCount; + + // store info + VertexCache.info[ destIndex ].index = sourceIndex; + VertexCache.info[ destIndex ].hit = 0; + + // destination Vertex + dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + + // transform Model * World * Camera * Projection * NDCSpace matrix + Transformation [ ETS_CURRENT].m.transformVect ( &dest->Pos.x, ((S3DVertex*) source )->Pos ); + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + + // light Vertex + #ifdef SOFTWARE_DRIVER_2_LIGHTING + lightVertex ( dest, ((S3DVertex*) source ) ); + #else + dest->Color[0].setA8R8G8B8 ( ((S3DVertex*) source )->Color.color ); + #endif +#endif + + // transfer texture coordinates + if ( Transformation [ ETS_TEXTURE_0 ].isIdentity ) + { + // only look on first transform + irr::memcpy32_small ( &dest->Tex[0], + &((S3DVertex*) source )->TCoords, + vSize[VertexCache.vType].TexSize * ( sizeof ( f32 ) * 2 ) + ); + } + else + { + /* + Generate texture coordinates as linear functions so that: + u = Ux*x + Uy*y + Uz*z + Uw + v = Vx*x + Vy*y + Vz*z + Vw + The matrix M for this case is: + Ux Vx 0 0 + Uy Vy 0 0 + Uz Vz 0 0 + Uw Vw 0 0 + */ + + const core::vector2d *src = &((S3DVertex*) source )->TCoords; + u32 t; + + for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t ) + { + const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ].m; + if ( Material.org.TextureLayer[0].TextureWrap==ETC_REPEAT ) + { + dest->Tex[t].x = M[0] * src[t].X + M[4] * src[t].Y + M[8]; + dest->Tex[t].y = M[1] * src[t].X + M[5] * src[t].Y + M[9]; + } + else + { + f32 tx1, ty1; + + tx1 = M[0] * src[t].X + M[4] * src[t].Y + M[8]; + ty1 = M[1] * src[t].X + M[5] * src[t].Y + M[9]; + + dest->Tex[t].x = tx1 <= 0.f ? 0.f : tx1 >= 1.f ? 1.f : tx1; + dest->Tex[t].y = ty1 <= 0.f ? 0.f : ty1 >= 1.f ? 1.f : ty1; + + //dest->Tex[t].x = core::clamp ( M[0] * src[t].X + M[4] * src[t].Y + M[8], 0.f, 1.f ); + //dest->Tex[t].y = core::clamp ( M[1] * src[t].X + M[5] * src[t].Y + M[9], 0.f, 1.f ); + } + } + + } + + dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format; + + // test vertex + dest[0].flag |= clipToFrustumTest ( dest); + + // to DC Space, project homogenous vertex + if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) + { + ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 ); + } + + //return dest; +} + +// + +REALINLINE s4DVertex * CSoftwareDriver2::VertexCache_getVertex ( const u32 sourceIndex ) +{ + for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i ) + { + if ( VertexCache.info[ i ].index == sourceIndex ) + { + return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + } + } + return 0; +} + + +/* + Cache based on linear walk indices + fill blockwise on the next 16(Cache_Size) unique vertices in indexlist + merge the next 16 vertices with the current +*/ +REALINLINE void CSoftwareDriver2::VertexCache_get ( s4DVertex ** face ) +{ + SCacheInfo info[VERTEXCACHE_ELEMENT]; + + // next primitive must be complete in cache + if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 && + VertexCache.indicesIndex < VertexCache.indexCount + ) + { + // rewind to start of primitive + VertexCache.indicesIndex = VertexCache.indicesRun; + + irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) ); + + // get the next unique vertices cache line + u32 fillIndex = 0; + u32 dIndex; + u32 i; + + while ( VertexCache.indicesIndex < VertexCache.indexCount && + fillIndex < VERTEXCACHE_ELEMENT + ) + { + u32 sourceIndex = VertexCache.indices [ VertexCache.indicesIndex++ ]; + + // if not exist, push back + s32 exist = 0; + for ( dIndex = 0; dIndex < fillIndex; ++dIndex ) + { + if ( info[ dIndex ].index == sourceIndex ) + { + exist = 1; + break; + } + } + + if ( 0 == exist ) + { + info[fillIndex++].index = sourceIndex; + } + } + + // clear marks + for ( i = 0; i!= VERTEXCACHE_ELEMENT; ++i ) + { + VertexCache.info[i].hit = 0; + } + + // mark all exisiting + for ( i = 0; i!= fillIndex; ++i ) + { + for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) + { + if ( VertexCache.info[ dIndex ].index == info[i].index ) + { + info[i].hit = dIndex; + VertexCache.info[ dIndex ].hit = 1; + break; + } + } + } + + // fill new + for ( i = 0; i!= fillIndex; ++i ) + { + if ( info[i].hit != VERTEXCACHE_MISS ) + continue; + + for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) + { + if ( 0 == VertexCache.info[dIndex].hit ) + { + VertexCache_fill ( info[i].index, dIndex ); + VertexCache.info[dIndex].hit += 1; + info[i].hit = dIndex; + break; + } + } + } + } + + const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); + + face[0] = VertexCache_getVertex ( VertexCache.indices[ i0 ] ); + face[1] = VertexCache_getVertex ( VertexCache.indices[ VertexCache.indicesRun + 1] ); + face[2] = VertexCache_getVertex ( VertexCache.indices[ VertexCache.indicesRun + 2] ); + + VertexCache.indicesRun += VertexCache.primitivePitch; +} + +REALINLINE void CSoftwareDriver2::VertexCache_get2 ( s4DVertex ** face ) +{ + const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); + + VertexCache_fill ( VertexCache.indices[ i0 ], 0 ); + VertexCache_fill ( VertexCache.indices[ VertexCache.indicesRun + 1], 1 ); + VertexCache_fill ( VertexCache.indices[ VertexCache.indicesRun + 2], 2 ); + + VertexCache.indicesRun += VertexCache.primitivePitch; + + face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + +} + +void CSoftwareDriver2::VertexCache_reset ( const void* vertices, u32 vertexCount, + const u16* indices, u32 primitiveCount, + E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType ) +{ + VertexCache.vertices = vertices; + VertexCache.vertexCount = vertexCount; + + VertexCache.indices = indices; + VertexCache.indicesIndex = 0; + VertexCache.indicesRun = 0; + + VertexCache.vType = vType; + VertexCache.pType = pType; + + switch ( VertexCache.pType ) + { + case scene::EPT_TRIANGLES: + VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount; + VertexCache.primitivePitch = 3; + break; + case scene::EPT_TRIANGLE_FAN: + VertexCache.indexCount = primitiveCount + 2; + VertexCache.primitivePitch = 1; + break; + } + + irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) ); + +} + + +//! draws a vertex primitive list +void CSoftwareDriver2::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType); + + if ( 0 == CurrentShader ) + return; + + + VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType ); + + const s4DVertex * face[3]; + + f32 dc_area; + s32 lodLevel; + u32 i; + u32 g; + + for ( i = 0; i < (u32) primitiveCount; ++i ) + { + VertexCache_get ( (s4DVertex**) face ); + + // if fully outside or outside on same side + if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK ) + != VERTEX4D_INSIDE + ) + continue; + + // if fully inside + if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) + { + dc_area = screenarea2 ( face ); + if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) ) + { + continue; + } + + dc_area = core::reciprocal ( dc_area ); + // select mipmap + for ( g = 0; g != 2; ++g ) + { + if ( 0 == Texmap[g].Texture ) + { + CurrentShader->setTexture(g, 0, 0); + continue; + } + + lodLevel = s32_log2_f32 ( texelarea2 ( face, g ) * dc_area ); + + CurrentShader->setTexture(g, Texmap[g].Texture, lodLevel); + select_polygon_mipmap2 ( (s4DVertex**) face, g ); + + } + + // rasterize + CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); + continue; + } + + // else if not complete inside clipping necessary + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 ); + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 ); + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 ); + + u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK; + + for ( g = 0; g != CurrentOut.ElementSize; ++g ) + { + CurrentOut.data[g].flag = flag; + Temp.data[g].flag = flag; + } + + u32 vOut; + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); +/* + if ( vOut < 3 ) + { + char buf[256]; + struct SCheck + { + u32 flag; + const char * name; + }; + + SCheck check[5]; + check[0].flag = face[0]->flag; + check[0].name = "face0"; + check[1].flag = face[1]->flag; + check[1].name = "face1"; + check[2].flag = face[2]->flag; + check[2].name = "face2"; + check[3].flag = (face[0]->flag & face[1]->flag & face[2]->flag); + check[3].name = "AND "; + check[4].flag = (face[0]->flag | face[1]->flag | face[2]->flag); + check[4].name = "OR "; + + for ( s32 h = 0; h!= 5; ++h ) + { + sprintf ( buf, "%s: %d %d %d %d %d %d", + check[h].name, + ( check[h].flag & 1 ), + ( check[h].flag & 2 ) >> 1, + ( check[h].flag & 4 ) >> 2, + ( check[h].flag & 8 ) >> 3, + ( check[h].flag & 16 ) >> 4, + ( check[h].flag & 32 ) >> 5 + ); + os::Printer::print ( buf ); + } + + sprintf ( buf, "Vout: %d\n", vOut ); + os::Printer::print ( buf ); + + int hold = 1; + } +*/ + if ( vOut < 3 ) + continue; + + vOut <<= 1; + + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + +/* + // if not complete inside clipping necessary + if ( ( test & VERTEX4D_INSIDE ) != VERTEX4D_INSIDE ) + { + u32 v[2] = { PointerAsValue ( Temp ) , PointerAsValue ( CurrentOut ) }; + for ( g = 0; g != 6; ++g ) + { + vOut = clipToHyperPlane ( (s4DVertex*) v[0], (s4DVertex*) v[1], vOut, NDCPlane[g] ); + if ( vOut < 3 ) + break; + + v[0] ^= v[1]; + v[1] ^= v[0]; + v[0] ^= v[1]; + + } + + if ( vOut < 3 ) + continue; + + } +*/ + + // check 2d backface culling on first + dc_area = screenarea ( CurrentOut.data ); + if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) ) + continue; + + // select mipmap + for ( g = 0; g != 2; ++g ) + { + if ( 0 == Texmap[g].Texture ) + { + CurrentShader->setTexture(g, 0, 0); + continue; + } + + lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, g ) / dc_area ); + + CurrentShader->setTexture(g, Texmap[g].Texture, lodLevel); + select_polygon_mipmap ( CurrentOut.data, vOut, g ); + } + + // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) + for ( g = 0; g <= vOut - 6; g += 2 ) + { + // rasterize + CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1, + CurrentOut.data + g + 3, + CurrentOut.data + g + 5 + ); + } + + } + + // dump statistics +/* + char buf [64]; + sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d", + vertexCount, primitiveCount, + VertexCache.CacheMiss + ); + os::Printer::print ( buf ); +*/ +} + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CSoftwareDriver2::setAmbientLight(const SColorf& color) +{ + Global_AmbientLight.setColorf ( color ); +} + + +//! adds a dynamic light +void CSoftwareDriver2::addDynamicLight(const SLight& dl) +{ + if ( Light.size () >= getMaximalDynamicLightAmount () ) + return; + + SInternalLight l; + l.org = dl; + + // light in eye space + Transformation[ETS_VIEW].m.transformVect ( &l.posEyeSpace.x, l.org.Position ); + + l.constantAttenuation = l.org.Attenuation.X; + l.linearAttenuation = l.org.Attenuation.Y; + l.quadraticAttenuation = l.org.Attenuation.Z; + + l.AmbientColor.setColorf ( l.org.AmbientColor ); + l.DiffuseColor.setColorf ( l.org.DiffuseColor ); + l.SpecularColor.setColorf ( l.org.SpecularColor ); + + switch ( dl.Type ) + { + case video::ELT_DIRECTIONAL: + { + l.posEyeSpace.normalize_xyz (); + } break; + } + + Light.push_back ( l ); + CNullDriver::addDynamicLight( l.org ); +} + +//! deletes all dynamic lights there are +void CSoftwareDriver2::deleteAllDynamicLights() +{ + Light.set_used ( 0 ); + CNullDriver::deleteAllDynamicLights(); + +} + +//! returns the maximal amount of dynamic lights the device can handle +u32 CSoftwareDriver2::getMaximalDynamicLightAmount() const +{ + return 8; +} + + + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + +/*! +*/ +void CSoftwareDriver2::lightVertex ( s4DVertex *dest, const S3DVertex *source ) +{ + // apply lighting model + if ( false == Material.org.Lighting ) + { + // should use the DiffuseColor but using pre-lit vertex color + dest->Color[0].setA8R8G8B8 ( source->Color.color ); + return; + } + + if ( Lights.size () == 0 ) + { + dest->Color[0] = Material.EmissiveColor; + return; + } + + // eyespace +/* + core::matrix4 modelview = Transformation[ETS_WORLD].m * Transformation[ETS_VIEW].m; + + core::matrix4 m2 ( modelview ); + m2.makeInverse (); + core::matrix4 modelviewinversetransposed ( m2.getTransposed() ); +*/ + + sVec4 vertexEyeSpace; + sVec4 normalEyeSpace; + sVec4 vertexEyeSpaceUnit; + + // vertex in eye space + Transformation[ETS_WORLD_VIEW].m.transformVect ( &vertexEyeSpace.x, source->Pos ); + vertexEyeSpace.project_xyz (); + + vertexEyeSpaceUnit = vertexEyeSpace; + vertexEyeSpaceUnit.normalize_xyz(); + + // vertex normal in eye-space + //modelviewinversetransposed.transformVect ( &normalEyeSpace.x, source->Normal ); + Transformation[ETS_WORLD_VIEW_INVERSE_TRANSPOSED].m.rotateVect ( &normalEyeSpace.x, source->Normal ); + if ( Material.org.NormalizeNormals ) + { + normalEyeSpace.normalize_xyz(); + } + + + sVec4 ambient; + sVec4 diffuse; + sVec4 specular; + + + // the universe started in darkness.. + ambient.set ( 0.f, 0.f, 0.f, 0.f ); + diffuse.set ( 0.f, 0.f, 0.f, 0.f ); + specular.set ( 0.f, 0.f, 0.f, 0.f ); + + f32 attenuation = 1.f; + + u32 i; + for ( i = 0; i!= Light.size (); ++i ) + { + const SInternalLight &light = Light[i]; + + sVec4 vp; // unit vector vertex to light + sVec4 lightHalf; // blinn-phong reflection + + + switch ( light.org.Type ) + { + case video::ELT_POINT: + { + // surface to light + vp.x = light.posEyeSpace.x - vertexEyeSpace.x; + vp.y = light.posEyeSpace.y - vertexEyeSpace.y; + vp.z = light.posEyeSpace.z - vertexEyeSpace.z; + + // irrlicht attenuation model +#if 0 + const f32 d = vp.get_inverse_length_xyz(); + + vp.x *= d; + vp.y *= d; + vp.z *= d; + attenuation = light.org.Radius * d; + +#else + const f32 d = vp.get_length_xyz(); + attenuation = core::reciprocal (light.constantAttenuation + + light.linearAttenuation * d + + light.quadraticAttenuation * d * d + ); + + // normalize surface to light + vp.normalize_xyz(); +#endif + + lightHalf.x = vp.x - vertexEyeSpaceUnit.x; + lightHalf.y = vp.y - vertexEyeSpaceUnit.y; + lightHalf.z = vp.z - vertexEyeSpaceUnit.z; + lightHalf.normalize_xyz(); + + } break; + + case video::ELT_DIRECTIONAL: + { + attenuation = 1.f; + vp = light.posEyeSpace; + + // half angle = lightvector + eye vector ( 0, 0, 1 ) + lightHalf.x = vp.x; + lightHalf.y = vp.y; + lightHalf.z = vp.z - 1.f; + lightHalf.normalize_xyz(); + } break; + } + + // build diffuse reflection + + //angle between normal and light vector + f32 dotVP = core::max_ ( 0.f, normalEyeSpace.dot_xyz ( vp ) ); + f32 dotHV = core::max_ ( 0.f, normalEyeSpace.dot_xyz ( lightHalf ) ); + + f32 pf; + if ( dotVP == 0.0 ) + { + pf = 0.f; + } + else + { + pf = (f32)pow(dotHV, Material.org.Shininess ); + } + + // accumulate ambient + ambient += light.AmbientColor * attenuation; + diffuse += light.DiffuseColor * ( dotVP * attenuation ); + specular += light.SpecularColor * ( pf * attenuation ); + + } + + sVec4 dColor; + + dColor = Global_AmbientLight; + dColor += Material.EmissiveColor; + dColor += ambient * Material.AmbientColor; + dColor += diffuse * Material.DiffuseColor; + dColor += specular * Material.SpecularColor; + dColor.saturate(); + + dest->Color[0] = dColor; +} + +#endif + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CSoftwareDriver2::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (texture) + { + if (texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); + return; + } + + if (useAlphaChannelOfTexture) + ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha( + BackBuffer, destPos, sourceRect, color, clipRect); + else + ((CSoftwareTexture2*)texture)->getImage()->copyTo( + BackBuffer, destPos, sourceRect, clipRect); + } +} + + + +//! Draws a 2d line. +void CSoftwareDriver2::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + ((CImage*)BackBuffer)->drawLine(start, end, color ); +} + + + +//! draw an 2d rectangle +void CSoftwareDriver2::draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip) +{ + if (clip) + { + core::rect p(pos); + + p.clipAgainst(*clip); + + if(!p.isValid()) + return; + + BackBuffer->drawRectangle(p, color); + } + else + { + if(!pos.isValid()) + return; + + BackBuffer->drawRectangle(pos, color); + } +} + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CSoftwareDriver2::OnResize(const core::dimension2d& size) +{ + // make sure width and height are multiples of 2 + core::dimension2d realSize(size); + + if (realSize.Width % 2) + realSize.Width += 1; + + if (realSize.Height % 2) + realSize.Height += 1; + + if (ScreenSize != realSize) + { + if (ViewPort.getWidth() == ScreenSize.Width && + ViewPort.getHeight() == ScreenSize.Height) + { + ViewPort = core::rect(core::position2d(0,0), realSize); + } + + ScreenSize = realSize; + + bool resetRT = (RenderTargetSurface == BackBuffer); + + BackBuffer->drop(); + BackBuffer = new CImage(ECF_SOFTWARE2, realSize); + + if (resetRT) + setRenderTarget(BackBuffer); + } +} + +//! returns the current render target size +const core::dimension2d& CSoftwareDriver2::getCurrentRenderTargetSize() const +{ + return RenderTargetSize; +} + +//!Draws an 2d rectangle with a gradient. +void CSoftwareDriver2::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + const core::dimension2d renderTargetSize ( ViewPort.getSize() ); + + const s32 xPlus = -(renderTargetSize.Width>>1); + const f32 xFact = 1.0f / (renderTargetSize.Width>>1); + + const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); + const f32 yFact = 1.0f / (renderTargetSize.Height>>1); + + // fill VertexCache direct + s4DVertex *v; + + VertexCache.vertexCount = 4; + + VertexCache.info[0].index = 0; + VertexCache.info[1].index = 1; + VertexCache.info[2].index = 2; + VertexCache.info[3].index = 3; + + v = &VertexCache.mem.data [ 0 ]; + + v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); + v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color ); + + v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); + v[2].Color[0].setA8R8G8B8 ( colorRightUp.color ); + + v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f ); + v[4].Color[0].setA8R8G8B8 ( colorRightDown.color ); + + v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f ); + v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color ); + + s32 i; + u32 g; + + for ( i = 0; i!= 8; i += 2 ) + { + v[i + 0].flag = clipToFrustumTest ( v + i ); + v[i + 1].flag = 0; + if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE ) + { + ndc_2_dc_and_project ( v + i + 1, v + i, 2 ); + } + } + + + IBurningShader * render; + + render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ]; + render->setRenderTarget(RenderTargetSurface, ViewPort); + + static const s16 indexList[6] = {0,1,2,0,2,3}; + + s4DVertex * face[3]; + + for ( i = 0; i!= 6; i += 3 ) + { + face[0] = VertexCache_getVertex ( indexList [ i + 0 ] ); + face[1] = VertexCache_getVertex ( indexList [ i + 1 ] ); + face[2] = VertexCache_getVertex ( indexList [ i + 2 ] ); + + // test clipping + u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE; + + if ( test == VERTEX4D_INSIDE ) + { + render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); + continue; + } + // Todo: all vertices are clipped in 2d.. + // is this true ? + u32 vOut = 6; + memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 ); + memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 ); + memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 ); + + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); + if ( vOut < 3 ) + continue; + + vOut <<= 1; + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + + // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) + for ( g = 0; g <= vOut - 6; g += 2 ) + { + // rasterize + render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] ); + } + + } +#else + draw2DRectangle ( colorLeftUp, position, clip ); +#endif +} + + + +//! Draws a 3d line. +void CSoftwareDriver2::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + Transformation [ ETS_CURRENT].m.transformVect ( &CurrentOut.data[0].Pos.x, start ); + Transformation [ ETS_CURRENT].m.transformVect ( &CurrentOut.data[2].Pos.x, end ); + + u32 g; + u32 vOut; + + // no clipping flags + for ( g = 0; g != CurrentOut.ElementSize; ++g ) + { + CurrentOut.data[g].flag = 0; + Temp.data[g].flag = 0; + } + + // vertices count per line + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 ); + if ( vOut < 2 ) + return; + + vOut <<= 1; + + IBurningShader * line; + line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ]; + line->setRenderTarget(RenderTargetSurface, ViewPort); + + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + + // unproject vertex color +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( g = 0; g != vOut; g+= 2 ) + { + CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color ); + } +#endif + + + for ( g = 0; g <= vOut - 4; g += 2 ) + { + // rasterize + line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 ); + } +} + + + +//! \return Returns the name of the video driver. Example: In case of the DirectX8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CSoftwareDriver2::getName() const +{ +#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL + return L"burnings video 0.38b"; +#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) + return L"burnings video 0.38uf"; +#elif defined ( BURNINGVIDEO_RENDERER_FAST ) + return L"burnings video 0.38f"; +#else + return L"burnings video 0.38"; +#endif +} + +//! Returns type of video driver +E_DRIVER_TYPE CSoftwareDriver2::getDriverType() const +{ + return EDT_BURNINGSVIDEO; +} + +//! Returns the transformation set by setTransform +const core::matrix4& CSoftwareDriver2::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Transformation[state].m; +} + +//! Creates a render target texture. +ITexture* CSoftwareDriver2::createRenderTargetTexture(const core::dimension2d& size, const c8* name) +{ + CImage* img = new CImage(ECF_SOFTWARE2, size); + + ITexture* tex = new CSoftwareTexture2(img, name, false, true); + img->drop(); + return tex; +} + + +//! Clears the DepthBuffer. +void CSoftwareDriver2::clearZBuffer() +{ + if (DepthBuffer) + DepthBuffer->clear(); +} + + +//! Returns an image created from the last rendered frame. +IImage* CSoftwareDriver2::createScreenShot() +{ + return new CImage(BackBuffer->getColorFormat(), BackBuffer); +} + + +//! returns a device dependent texture from a software surface (IImage) +//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES +ITexture* CSoftwareDriver2::createDeviceDependentTexture(IImage* surface, const char* name) +{ + return new CSoftwareTexture2(surface, name, getTextureCreationFlag(ETCF_CREATE_MIP_MAPS)); + +} + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CSoftwareDriver2::getMaximalPrimitiveCount() const +{ + return 0x00800000; +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a video driver +IVideoDriver* createSoftwareDriver2(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CSoftwareDriver2(windowSize, fullscreen, io, presenter); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + + +} // end namespace video +} // end namespace irr diff --git a/src/dep/src/irrlicht/CSoftwareDriver2.h b/src/dep/src/irrlicht/CSoftwareDriver2.h new file mode 100644 index 0000000..14eef09 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareDriver2.h @@ -0,0 +1,259 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_2_SOFTWARE_H_INCLUDED__ +#define __C_VIDEO_2_SOFTWARE_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "IBurningShader.h" +#include "CNullDriver.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + class CSoftwareDriver2 : public CNullDriver + { + public: + + //! constructor + CSoftwareDriver2(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter); + + //! destructor + virtual ~CSoftwareDriver2(); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene( s32 windowId = 0, core::rect* sourceRect=0 ); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! returns size of the current render target + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light + virtual void addDynamicLight(const SLight& light); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! draws a vertex primitive list + void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! \return Returns the name of the video driver. Example: In case of the DirectX8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Creates a render target texture. + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, const c8* name); + + //! Clears the DepthBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + protected: + + //! sets a render target + void setRenderTarget(video::CImage* image); + + //! sets the current Texture + bool setTexture(u32 stage, video::ITexture* texture); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name); + + video::CImage* BackBuffer; + video::IImagePresenter* Presenter; + + video::ITexture* RenderTargetTexture; + video::IImage* RenderTargetSurface; + core::dimension2d RenderTargetSize; + + //! selects the right triangle renderer based on the render states. + void setCurrentShader(); + + IBurningShader* CurrentShader; + IBurningShader* BurningShader[ETR2_COUNT]; + + IDepthBuffer* DepthBuffer; + + video::ITexture* Texture[2]; + sInternalTexture Texmap[2]; + + /* + extend Matrix Stack + -> combined CameraProjection + -> combined CameraProjectionWorld + -> ClipScale from NDC to DC Space + */ + enum E_TRANSFORMATION_STATE_2 + { + ETS_VIEW_PROJECTION = ETS_COUNT, + ETS_WORLD_VIEW, + ETS_WORLD_VIEW_INVERSE_TRANSPOSED, + ETS_CURRENT, + ETS_CLIPSCALE, + + ETS2_COUNT + }; + + struct SMatrixStack + { + s32 isIdentity; + core::matrix4 m; + }; + + SMatrixStack Transformation[ETS2_COUNT]; + + // Vertex Cache + static const SVSize vSize[]; + + SVertexCache VertexCache; + + void VertexCache_reset (const void* vertices, u32 vertexCount, + const u16* indices, u32 indexCount, + E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType); + void VertexCache_get ( s4DVertex ** face ); + void VertexCache_get2 ( s4DVertex ** face ); + + void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex ); + s4DVertex * VertexCache_getVertex ( const u32 sourceIndex ); + + + // culling & clipping + u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ); + u32 clipToFrustumTest ( const s4DVertex * v ) const; + u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn ); + + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + void lightVertex ( s4DVertex *dest, const S3DVertex *source ); +#endif + + + // holds transformed, clipped vertices + SAlignedVertex CurrentOut; + SAlignedVertex Temp; + + void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const; + f32 screenarea ( const s4DVertex *v0 ) const; + void select_polygon_mipmap ( s4DVertex *source, u32 vIn, s32 tex ); + f32 texelarea ( const s4DVertex *v0, int tex ) const; + + + void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const; + f32 screenarea2 ( const s4DVertex **v ) const; + f32 texelarea2 ( const s4DVertex **v, int tex ) const; + void select_polygon_mipmap2 ( s4DVertex **source, s32 tex ) const; + + + sVec4 Global_AmbientLight; + + struct SInternalLight + { + SLight org; + + sVec4 posEyeSpace; + + f32 constantAttenuation; + f32 linearAttenuation; + f32 quadraticAttenuation; + + sVec4 AmbientColor; + sVec4 DiffuseColor; + sVec4 SpecularColor; + }; + core::array Light; + + struct SInternalMaterial + { + SMaterial org; + + sVec4 AmbientColor; + sVec4 DiffuseColor; + sVec4 SpecularColor; + sVec4 EmissiveColor; + + u32 SpecularEnabled; // == Power2 + }; + + SInternalMaterial Material; + + static const sVec4 NDCPlane[6]; + + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CSoftwareTexture.cpp b/src/dep/src/irrlicht/CSoftwareTexture.cpp new file mode 100644 index 0000000..572376e --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareTexture.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +#include "CSoftwareTexture.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CSoftwareTexture::CSoftwareTexture(IImage* image, const char* name, bool renderTarget) +: ITexture(name), Texture(0), IsRenderTarget(renderTarget) +{ + #ifdef _DEBUG + setDebugName("CSoftwareTexture"); + #endif + + if (image) + { + core::dimension2d optSize; + OrigSize = image->getDimension(); + + optSize.Width = getTextureSizeFromSurfaceSize(OrigSize.Width); + optSize.Height = getTextureSizeFromSurfaceSize(OrigSize.Height); + + Image = new CImage(ECF_A1R5G5B5, image); + + if (optSize == OrigSize) + { + Texture = Image; + Texture->grab(); + } + else + { + Texture = new CImage(ECF_A1R5G5B5, optSize); + Image->copyToScaling(Texture); + } + } +} + + + +//! destructor +CSoftwareTexture::~CSoftwareTexture() +{ + if (Image) + Image->drop(); + + if (Texture) + Texture->drop(); +} + + + +//! lock function +void* CSoftwareTexture::lock() +{ + return Image->lock(); +} + + + +//! unlock function +void CSoftwareTexture::unlock() +{ + if (Image != Texture) + { + os::Printer::log("Performance warning, slow unlock of non power of 2 texture.", ELL_WARNING); + Image->copyToScaling(Texture); + } + + Image->unlock(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CSoftwareTexture::getOriginalSize() const +{ + return OrigSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CSoftwareTexture::getSize() const +{ + return Image->getDimension(); +} + + +//! returns unoptimized surface +CImage* CSoftwareTexture::getImage() +{ + return Image; +} + + + +//! returns texture surface +CImage* CSoftwareTexture::getTexture() +{ + return Texture; +} + + + +//! returns the size of a texture which would be the optimize size for rendering it +inline s32 CSoftwareTexture::getTextureSizeFromSurfaceSize(s32 size) const +{ + s32 ts = 0x01; + while(ts < size) + ts <<= 1; + + return ts; +} + + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CSoftwareTexture::getDriverType() const +{ + return EDT_SOFTWARE; +} + + + +//! returns color format of texture +ECOLOR_FORMAT CSoftwareTexture::getColorFormat() const +{ + return ECF_A1R5G5B5; +} + + + +//! returns pitch of texture (in bytes) +u32 CSoftwareTexture::getPitch() const +{ + return Image->getDimension().Width * 2; +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CSoftwareTexture::regenerateMipMapLevels() +{ + // our software textures don't have mip maps +} + +bool CSoftwareTexture::isRenderTarget() const +{ + return IsRenderTarget; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + diff --git a/src/dep/src/irrlicht/CSoftwareTexture.h b/src/dep/src/irrlicht/CSoftwareTexture.h new file mode 100644 index 0000000..26f250a --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareTexture.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE_TEXTURE_H_INCLUDED__ +#define __C_SOFTWARE_TEXTURE_H_INCLUDED__ + +#include "ITexture.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + +/*! + interface for a Video Driver dependent Texture. +*/ +class CSoftwareTexture : public ITexture +{ +public: + + //! constructor + CSoftwareTexture(IImage* surface, const char* name, bool renderTarget=false); + + //! destructor + virtual ~CSoftwareTexture(); + + //! lock function + virtual void* lock(); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns unoptimized surface + virtual CImage* getImage(); + + //! returns texture surface + virtual CImage* getTexture(); + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(); + + //! is it a render target? + virtual bool isRenderTarget() const; + +private: + + //! returns the size of a texture which would be the optimize size for rendering it + inline s32 getTextureSizeFromSurfaceSize(s32 size) const; + + CImage* Image; + CImage* Texture; + core::dimension2d OrigSize; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSoftwareTexture2.cpp b/src/dep/src/irrlicht/CSoftwareTexture2.cpp new file mode 100644 index 0000000..5031c33 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareTexture2.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_compile_config.h" +#include "SoftwareDriver2_helper.h" +#include "CSoftwareTexture2.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CSoftwareTexture2::CSoftwareTexture2(IImage* image, const char* name, bool generateMipLevels, bool isRenderTarget) +: ITexture(name), MipMapLOD(0), HasMipMaps(generateMipLevels), IsRenderTarget(isRenderTarget) +{ + #ifndef SOFTWARE_DRIVER_2_MIPMAPPING + HasMipMaps = false; + #endif + + memset32 ( MipMap, 0, sizeof ( MipMap ) ); + + if (image) + { + + core::dimension2d optSize; + core::dimension2d origSize = image->getDimension(); + OrigSize = origSize; + + optSize.Width = getTextureSizeFromSurfaceSize(origSize.Width); + optSize.Height = getTextureSizeFromSurfaceSize(origSize.Height); + + if ( origSize == optSize ) + { + MipMap[0] = new CImage(ECF_SOFTWARE2, image); + } + else + { + MipMap[0] = new CImage(ECF_SOFTWARE2, optSize); + + // temporary CImage needed + CImage * temp = new CImage ( ECF_SOFTWARE2, image ); + temp->copyToScaling(MipMap[0]); + temp->drop (); + } + } + + regenerateMipMapLevels (); + setCurrentMipMapLOD ( 0 ); +} + + +//! destructor +CSoftwareTexture2::~CSoftwareTexture2() +{ + for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) + { + if ( MipMap[i] ) + MipMap[i]->drop (); + } +} + + +//! returns the size of a texture which would be the optimize size for rendering it +inline s32 CSoftwareTexture2::getTextureSizeFromSurfaceSize(s32 size) const +{ + s32 ts = 0x01; + while(ts < size) + ts <<= 1; + +/* + if (ts > size && ts > 256 ) + ts >>= 1; +*/ + return ts; +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CSoftwareTexture2::regenerateMipMapLevels() +{ + if ( !HasMipMaps ) + return; + + s32 i; + + // release + for ( i = 1; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) + { + if ( MipMap[i] ) + MipMap[i]->drop (); + } + + core::dimension2d newSize; + core::dimension2d currentSize; + + i = 1; + CImage * c = MipMap[0]; + while ( i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) + { + currentSize = c->getDimension(); + newSize.Width = core::s32_max ( 1, currentSize.Width >> 1 ); + newSize.Height = core::s32_max ( 1, currentSize.Height >> 1 ); + + MipMap[i] = new CImage(ECF_SOFTWARE2, newSize); + MipMap[0]->copyToScalingBoxFilter ( MipMap[i], 0 ); + c = MipMap[i]; + i += 1; + } +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + diff --git a/src/dep/src/irrlicht/CSoftwareTexture2.h b/src/dep/src/irrlicht/CSoftwareTexture2.h new file mode 100644 index 0000000..3637398 --- /dev/null +++ b/src/dep/src/irrlicht/CSoftwareTexture2.h @@ -0,0 +1,134 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE_2_TEXTURE_H_INCLUDED__ +#define __C_SOFTWARE_2_TEXTURE_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" + +#include "ITexture.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + +/*! + interface for a Video Driver dependent Texture. +*/ +class CSoftwareTexture2 : public ITexture +{ +public: + + //! constructor + CSoftwareTexture2(IImage* surface, const char* name, bool generateMipLevels, bool isRenderTarget=false); + + //! destructor + virtual ~CSoftwareTexture2(); + + //! lock function + virtual void* lock() + { + return MipMap[MipMapLOD]->lock(); + } + + //! unlock function + virtual void unlock() + { + MipMap[MipMapLOD]->unlock(); + } + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const + { + //return MipMap[0]->getDimension(); + return OrigSize; + } + + //! Returns the size of the largest mipmap. + const core::dimension2d& getMaxSize() const + { + return MipMap[0]->getDimension(); + } + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const + { + return MipMap[MipMapLOD]->getDimension(); + } + + //! returns unoptimized surface + virtual CImage* getImage() const + { + return MipMap[0]; + } + + //! returns texture surface + virtual CImage* getTexture() const + { + return MipMap[MipMapLOD]; + } + + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const + { + return EDT_BURNINGSVIDEO; + } + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const + { + return ECF_SOFTWARE2; + } + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const + { + return MipMap[MipMapLOD]->getPitch(); + } + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(); + + //! Select a Mipmap Level + virtual void setCurrentMipMapLOD ( s32 lod ) + { + if ( HasMipMaps ) + MipMapLOD = lod; + } + + //! support mipmaps + virtual bool hasMipMaps() const + { + return HasMipMaps; + } + + //! is a render target + virtual bool isRenderTarget() const + { + return IsRenderTarget; + } + +private: + + //! returns the size of a texture which would be the optimize size for rendering it + inline s32 getTextureSizeFromSurfaceSize(s32 size) const; + + core::dimension2d OrigSize; + + CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; + + s32 MipMapLOD; + bool HasMipMaps, IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CSphereSceneNode.cpp b/src/dep/src/irrlicht/CSphereSceneNode.cpp new file mode 100644 index 0000000..7d22ecd --- /dev/null +++ b/src/dep/src/irrlicht/CSphereSceneNode.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSphereSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "CGeometryCreator.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) +: ISceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), + Radius(radius), PolyCountX(polyCountX), PolyCountY(polyCountY) +{ + #ifdef _DEBUG + setDebugName("CSphereSceneNode"); + #endif + + Mesh = CGeometryCreator::createSphereMesh(radius, polyCountX, polyCountY); +} + + + +//! destructor +CSphereSceneNode::~CSphereSceneNode() +{ + if (Mesh) + Mesh->drop(); +} + + +//! renders the node. +void CSphereSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (Mesh && driver) + { + driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial()); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + driver->drawMeshBuffer(Mesh->getMeshBuffer(0)); + if ( DebugDataVisible & scene::EDS_BBOX ) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(Mesh->getMeshBuffer(0)->getBoundingBox(), video::SColor(255,255,255,255)); + } + } +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSphereSceneNode::getBoundingBox() const +{ + return Mesh ? Mesh->getBoundingBox() : Box; +} + + +void CSphereSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSphereSceneNode::getMaterial(u32 i) +{ + if (i>0 || !Mesh) + return ISceneNode::getMaterial(i); + else + return Mesh->getMeshBuffer(i)->getMaterial(); +} + + +//! returns amount of materials used by this scene node. +u32 CSphereSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Writes attributes of the scene node. +void CSphereSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addFloat("Radius", Radius); + out->addInt("PolyCountX", PolyCountX); + out->addInt("PolyCountY", PolyCountY); +} + + +//! Reads attributes of the scene node. +void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + f32 oldRadius = Radius; + u32 oldPolyCountX = PolyCountX; + u32 oldPolyCountY = PolyCountY; + + Radius = in->getAttributeAsFloat("Radius"); + PolyCountX = in->getAttributeAsInt("PolyCountX"); + PolyCountY = in->getAttributeAsInt("PolyCountY"); + // legacy values read for compatibility with older versions + u32 polyCount = in->getAttributeAsInt("PolyCount"); + if (PolyCountX ==0 && PolyCountY == 0) + PolyCountX = PolyCountY = polyCount; + + Radius = core::max_(Radius, 0.0001f); + + if ( !core::equals(Radius, oldRadius) || PolyCountX != oldPolyCountX || PolyCountY != oldPolyCountY) + { + if (Mesh) + Mesh->drop(); + Mesh = CGeometryCreator::createSphereMesh(Radius, PolyCountX, PolyCountY); + } + + ISceneNode::deserializeAttributes(in, options); +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CSphereSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CSphereSceneNode* nb = new CSphereSceneNode(Radius, PolyCountX, PolyCountY, newParent, + newManager, ID, RelativeTranslation); + + nb->cloneMembers(this, newManager); + nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial(); + + nb->drop(); + return nb; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CSphereSceneNode.h b/src/dep/src/irrlicht/CSphereSceneNode.h new file mode 100644 index 0000000..24b0ed6 --- /dev/null +++ b/src/dep/src/irrlicht/CSphereSceneNode.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SHPERE_SCENE_NODE_H_INCLUDED__ +#define __C_SHPERE_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + class CSphereSceneNode : public ISceneNode + { + public: + + //! constructor + CSphereSceneNode(f32 size, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CSphereSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SPHERE; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + IMesh* Mesh; + core::aabbox3d Box; + f32 Radius; + u32 PolyCountX; + u32 PolyCountY; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CTRFlat.cpp b/src/dep/src/irrlicht/CTRFlat.cpp new file mode 100644 index 0000000..c1113f7 --- /dev/null +++ b/src/dep/src/irrlicht/CTRFlat.cpp @@ -0,0 +1,301 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRFlat : public CTRTextureGouraud +{ +public: + + CTRFlat(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRFlat"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + color = v1->Color; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = color; + } + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRFlat(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRFlatWire.cpp b/src/dep/src/irrlicht/CTRFlatWire.cpp new file mode 100644 index 0000000..9cf2cb1 --- /dev/null +++ b/src/dep/src/irrlicht/CTRFlatWire.cpp @@ -0,0 +1,282 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRFlatWire : public CTRTextureGouraud +{ +public: + + CTRFlatWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + color = v1->Color; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = color; + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = color; + } + + } + + // draw the span + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererFlatWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRFlatWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRGouraud.cpp b/src/dep/src/irrlicht/CTRGouraud.cpp new file mode 100644 index 0000000..90514aa --- /dev/null +++ b/src/dep/src/irrlicht/CTRGouraud.cpp @@ -0,0 +1,359 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +class CTRGouraud : public CTRTextureGouraud +{ +public: + + CTRGouraud(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraud"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRedSigned(v1->Color)<<3; + leftG = rightG = video::getGreenSigned(v1->Color)<<3; + leftB = rightB = video::getBlueSigned(v1->Color)<<3; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRedSigned(v2->Color)<<3) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v2->Color)<<3) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v2->Color)<<3) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRedSigned(v3->Color)<<3) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v3->Color)<<3) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v3->Color)<<3) - leftB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRedSigned(v3->Color)<<3) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v3->Color)<<3) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v3->Color)<<3) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRedSigned(v2->Color)<<3) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v2->Color)<<3) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v2->Color)<<3) - leftB) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + spanR = leftR; + spanG = leftG; + spanB = leftB; + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanStepB = (s32)((rightB - leftB) * tmpDiv); + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = video::RGB16(spanR, spanG, spanB); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRedSigned(v2->Color)<<3; + rightG = video::getGreenSigned(v2->Color)<<3; + rightB = video::getBlueSigned(v2->Color)<<3; + rightStepR = (s32)(((video::getRedSigned(v3->Color)<<3) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v3->Color)<<3) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v3->Color)<<3) - rightB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRedSigned(v2->Color)<<3; + leftG = video::getGreenSigned(v2->Color)<<3; + leftB = video::getBlueSigned(v2->Color)<<3; + leftStepR = (s32)(((video::getRedSigned(v3->Color)<<3) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v3->Color)<<3) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v3->Color)<<3) - leftB) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererGouraud(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRGouraud(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRGouraud2.cpp b/src/dep/src/irrlicht/CTRGouraud2.cpp new file mode 100644 index 0000000..986a3bd --- /dev/null +++ b/src/dep/src/irrlicht/CTRGouraud2.cpp @@ -0,0 +1,672 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRGouraud2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraud2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraud2::CTRGouraud2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRGouraud2"); + #endif +} + + + +/*! +*/ +void CTRGouraud2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + + +#ifdef IPOL_C0 + tFixPoint r0, g0, b0; + +#ifdef INVERSE_W + f32 inversew; +#endif + +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef IPOL_C0 +#ifdef INVERSE_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( r0, g0, b0, line.c[0] * inversew ); +#else + getSample_color ( r0, g0, b0, line.c[0] ); +#endif + + dst[i] = fix_to_color ( r0, g0, b0 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#endif + +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b); + if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c); + if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGouraud2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraud2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRGouraudAlpha2.cpp b/src/dep/src/irrlicht/CTRGouraudAlpha2.cpp new file mode 100644 index 0000000..f785805 --- /dev/null +++ b/src/dep/src/irrlicht/CTRGouraudAlpha2.cpp @@ -0,0 +1,683 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRGouraudAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraudAlpha2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraudAlpha2::CTRGouraudAlpha2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRGouraudAlpha2"); + #endif +} + + + +/*! +*/ +void CTRGouraudAlpha2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + + +#ifdef IPOL_C0 + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint a0; + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef IPOL_C0 +#ifdef INVERSE_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( a0, r0, g0, b0, line.c[0] * inversew ); +#else + getSample_color ( a0, r0, g0, b0, line.c[0] ); +#endif + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + + dst[i] = fix_to_color ( r2, g2, b2 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#endif +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGouraudAlpha2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraudAlpha2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRGouraudAlphaNoZ2.cpp b/src/dep/src/irrlicht/CTRGouraudAlphaNoZ2.cpp new file mode 100644 index 0000000..d2fc258 --- /dev/null +++ b/src/dep/src/irrlicht/CTRGouraudAlphaNoZ2.cpp @@ -0,0 +1,684 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +//#define INVERSE_W + +//#define USE_ZBUFFER +//#define IPOL_W +//#define CMP_W +//#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + //#define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRGouraudAlphaNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraudAlphaNoZ2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraudAlphaNoZ2::CTRGouraudAlphaNoZ2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRGouraudAlphaNoZ2"); + #endif +} + + + +/*! +*/ +void CTRGouraudAlphaNoZ2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + + +#ifdef IPOL_C0 + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint a0; + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef IPOL_C0 +#ifdef IPOL_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( a0, r0, g0, b0, line.c[0] * inversew ); +#else + getSample_color ( a0, r0, g0, b0, line.c[0] ); +#endif + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + + dst[i] = fix_to_color ( r2, g2, b2 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRGouraudAlphaNoZ2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraudAlphaNoZ2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRGouraudWire.cpp b/src/dep/src/irrlicht/CTRGouraudWire.cpp new file mode 100644 index 0000000..fd0f1e4 --- /dev/null +++ b/src/dep/src/irrlicht/CTRGouraudWire.cpp @@ -0,0 +1,327 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRGouraudWire : public CTRTextureGouraud +{ +public: + + CTRGouraudWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = (((leftR>>8) & 0x1F)<<10) | (((leftG>>8) & 0x1F)<<5) | ((leftB>>8) & 0x1F); + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = (((rightR>>8) & 0x1F)<<10) | (((rightG>>8) & 0x1F)<<5) | ((rightB>>8) & 0x1F); + } + + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererGouraudWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRGouraudWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureBlend.cpp b/src/dep/src/irrlicht/CTRTextureBlend.cpp new file mode 100644 index 0000000..a740330 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureBlend.cpp @@ -0,0 +1,712 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureBlend : public IBurningShader +{ +public: + + //! constructor + CTRTextureBlend(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setZCompareFunc ( u32 func); + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + + u32 ZCompare; + +}; + +//! constructor +CTRTextureBlend::CTRTextureBlend(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureBlend"); + #endif + + ZCompare = 1; +} + + +void CTRTextureBlend::setZCompareFunc ( u32 func) +{ + ZCompare = func; +} + +/*! +*/ +void CTRTextureBlend::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + + f32 inversew = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSEW + inversew = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, + &IT[0], + f32_to_fixPoint ( line.t0[0].x,inversew), + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t0[0] += slopeT0; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSEW + inversew = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, + &IT[0], + f32_to_fixPoint ( line.t0[0].x,inversew), + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t0[0] += slopeT0; +#endif + }break; + } // zcompare + +} + +void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureBlend(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureBlend(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureDetailMap2.cpp b/src/dep/src/irrlicht/CTRTextureDetailMap2.cpp new file mode 100644 index 0000000..7f17164 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureDetailMap2.cpp @@ -0,0 +1,690 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureDetailMap2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureDetailMap2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureDetailMap2::CTRTextureDetailMap2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureDetailMap2"); + #endif +} + + + +/*! +*/ +void CTRTextureDetailMap2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0, tx1; + tFixPoint ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); + tx1 = f32_to_fixPoint ( line.t1[0].x,inversew); + ty1 = f32_to_fixPoint ( line.t1[0].y,inversew); + +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); + tx1 = f32_to_fixPoint ( line.t1[0].x ); + ty1 = f32_to_fixPoint ( line.t1[0].y ); +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 ); + +#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) ) + + // bias half color + r1 += -FIX_POINT_HALF_COLOR; + g1 += -FIX_POINT_HALF_COLOR; + b1 += -FIX_POINT_HALF_COLOR; + + r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) ); + g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) ); + b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) ); + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureDetailMap2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureDetailMap2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureFlat.cpp b/src/dep/src/irrlicht/CTRTextureFlat.cpp new file mode 100644 index 0000000..f104c02 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureFlat.cpp @@ -0,0 +1,340 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureFlat : public CTRTextureGouraud +{ +public: + + CTRTextureFlat(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRTextureFlat"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + spanTx = leftTx; + spanTy = leftTy; + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + } + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureFlat(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureFlat(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr diff --git a/src/dep/src/irrlicht/CTRTextureFlatWire.cpp b/src/dep/src/irrlicht/CTRTextureFlatWire.cpp new file mode 100644 index 0000000..5c51c2f --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureFlatWire.cpp @@ -0,0 +1,314 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureFlatWire : public CTRTextureGouraud +{ +public: + + CTRTextureFlatWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRTextureFlatWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + } + + } + + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureFlatWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraud.cpp b/src/dep/src/irrlicht/CTRTextureGouraud.cpp new file mode 100644 index 0000000..8dbbe82 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraud.cpp @@ -0,0 +1,469 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" +#include "os.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! constructor +CTRTextureGouraud::CTRTextureGouraud(IZBuffer* zbuffer) + : RenderTarget(0), ZBuffer(zbuffer), SurfaceWidth(0), SurfaceHeight(0), + BackFaceCullingEnabled(true), lockedZBuffer(0), + lockedSurface(0), lockedTexture(0), lockedTextureWidth(0), + textureXMask(0), textureYMask(0), Texture(0) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraud"); + #endif + + if (ZBuffer) + zbuffer->grab(); +} + + + +//! destructor +CTRTextureGouraud::~CTRTextureGouraud() +{ + if (RenderTarget) + RenderTarget->drop(); + + if (ZBuffer) + ZBuffer->drop(); + + if (Texture) + Texture->drop(); +} + + + +//! sets the Texture +void CTRTextureGouraud::setTexture(video::IImage* texture) +{ + if (Texture) + Texture->drop(); + + Texture = texture; + + if (Texture) + { + Texture->grab(); + lockedTextureWidth = Texture->getDimension().Width; + + textureXMask = lockedTextureWidth-1; + textureYMask = Texture->getDimension().Height-1; + } +} + + + + +//! en or disables the backface culling +void CTRTextureGouraud::setBackfaceCulling(bool enabled) +{ + BackFaceCullingEnabled = enabled; +} + + + +//! sets a render target +void CTRTextureGouraud::setRenderTarget(video::IImage* surface, const core::rect& viewPort) +{ + if (RenderTarget) + RenderTarget->drop(); + + RenderTarget = surface; + + if (RenderTarget) + { + SurfaceWidth = RenderTarget->getDimension().Width; + SurfaceHeight = RenderTarget->getDimension().Height; + RenderTarget->grab(); + ViewPortRect = viewPort; + } +} + + + +//! draws an indexed triangle list +void CTRTextureGouraud::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRedSigned(v1->Color)<<8; + leftG = rightG = video::getGreenSigned(v1->Color)<<8; + leftB = rightB = video::getBlueSigned(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRedSigned(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRedSigned(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRedSigned(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRedSigned(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + spanZValue = leftZValue+tDiffLeft*spanZStep; + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + spanZTarget = zTarget + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + u16 color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + *hSpanBegin = video::RGB16(video::getRedSigned(color) * (spanR>>8) >>2, video::getGreenSigned(color) * (spanG>>8) >>2, video::getBlueSigned(color) * (spanB>>8) >>2); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRedSigned(v2->Color)<<8; + rightG = video::getGreenSigned(v2->Color)<<8; + rightB = video::getBlueSigned(v2->Color)<<8; + rightStepR = (s32)(((video::getRedSigned(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreenSigned(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlueSigned(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRedSigned(v2->Color)<<8; + leftG = video::getGreenSigned(v2->Color)<<8; + leftB = video::getBlueSigned(v2->Color)<<8; + leftStepR = (s32)(((video::getRedSigned(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreenSigned(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlueSigned(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraud(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraud(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraud.h b/src/dep/src/irrlicht/CTRTextureGouraud.h new file mode 100644 index 0000000..c05b917 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraud.h @@ -0,0 +1,67 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__ +#define __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__ + +#include "ITriangleRenderer.h" + +namespace irr +{ +namespace video +{ + //! CTRTextureGouraud class + class CTRTextureGouraud : public ITriangleRenderer + { + public: + + //! constructor + CTRTextureGouraud(IZBuffer* zbuffer); + + //! destructor + virtual ~CTRTextureGouraud(); + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); + + //! en or disables the backface culling + virtual void setBackfaceCulling(bool enabled = true); + + //! sets the Texture + virtual void setTexture(video::IImage* texture); + + protected: + + //! vertauscht zwei vertizen + inline void swapVertices(const S2DVertex** v1, const S2DVertex** v2) + { + const S2DVertex* b = *v1; + *v1 = *v2; + *v2 = b; + } + + video::IImage* RenderTarget; + core::rect ViewPortRect; + + IZBuffer* ZBuffer; + + s32 SurfaceWidth; + s32 SurfaceHeight; + bool BackFaceCullingEnabled; + TZBufferType* lockedZBuffer; + u16* lockedSurface; + u16* lockedTexture; + s32 lockedTextureWidth; + s32 textureXMask, textureYMask; + video::IImage* Texture; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CTRTextureGouraud2.cpp b/src/dep/src/irrlicht/CTRTextureGouraud2.cpp new file mode 100644 index 0000000..c1b8fde --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraud2.cpp @@ -0,0 +1,703 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraud2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraud2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraud2::CTRTextureGouraud2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraud2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraud2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + +#ifdef IPOL_C0 + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + tx0 = f32_to_fixPoint ( line.t0[0].x, inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y, inversew); + +#ifdef IPOL_C0 + r1 = f32_to_fixPoint ( line.c[0].y ,inversew ); + g1 = f32_to_fixPoint ( line.c[0].z ,inversew ); + b1 = f32_to_fixPoint ( line.c[0].w ,inversew ); +#endif + +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); +#ifdef IPOL_C0 + getTexel_plain2 ( r1, g1, b1, line.c[0] ); +#endif +#endif + +#ifdef IPOL_C0 + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + dst[i] = fix_to_color ( imulFix ( r0, r1 ), + imulFix ( g0, g1 ), + imulFix ( b0, b1 ) + ); +#else + +#ifdef BURNINGVIDEO_RENDERER_FAST + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 ); +#else + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + dst[i] = fix_to_color ( r0, g0, b0 ); +#endif + +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureGouraud2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraud2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudAdd.cpp b/src/dep/src/irrlicht/CTRTextureGouraudAdd.cpp new file mode 100644 index 0000000..1779a89 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudAdd.cpp @@ -0,0 +1,421 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" +#include "os.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudAdd : public CTRTextureGouraud +{ +public: + + //! constructor + CTRTextureGouraudAdd(IZBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); + +protected: + +}; + +//! constructor +CTRTextureGouraudAdd::CTRTextureGouraudAdd(IZBuffer* zbuffer) +: CTRTextureGouraud(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAdd"); + #endif +} + + +//! draws an indexed triangle list +void CTRTextureGouraudAdd::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + spanZValue = leftZValue+tDiffLeft*spanZStep; + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + spanZTarget = zTarget + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + //*spanZTarget = spanZValue; + color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + + int basis = *hSpanBegin; + int r = (video::getRed(basis)<<3) + (video::getRed(color)<<3); + if (r > 255) r = 255; + int g = (video::getGreen(basis)<<3) + (video::getGreen(color)<<3); + if (g > 255) g = 255; + int b = (video::getBlue(basis)<<3) + (video::getBlue(color)<<3); + if (b > 255) b = 255; + + *hSpanBegin = video::RGB16(r, g, b); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudAdd(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudAdd2.cpp b/src/dep/src/irrlicht/CTRTextureGouraudAdd2.cpp new file mode 100644 index 0000000..84918da --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudAdd2.cpp @@ -0,0 +1,711 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAdd2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAdd2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAdd2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudAdd2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), + d + f32_to_fixPoint ( line.t0[0].y,inversew) ) + ); +#else + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x), + d + f32_to_fixPoint ( line.t0[0].y) ) + ); + +#endif +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = clampfix_maxcolor ( r1 + r0 ); + g2 = clampfix_maxcolor ( g1 + g0 ); + b2 = clampfix_maxcolor ( b1 + b0 ); + + dst[i] = fix_to_color ( r2, g2, b2 ); +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAdd2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAdd2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudAddNoZ2.cpp b/src/dep/src/irrlicht/CTRTextureGouraudAddNoZ2.cpp new file mode 100644 index 0000000..612b6a7 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudAddNoZ2.cpp @@ -0,0 +1,672 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +//#define USE_ZBUFFER +#define IPOL_W +//#define CMP_W +//#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAddNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAddNoZ2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAddNoZ2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudAddNoZ2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef IPOL_Z + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef IPOL_Z + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef IPOL_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif + { +#ifdef IPOL_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); +#endif + + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = clampfix_maxcolor ( r1 + r0 ); + g2 = clampfix_maxcolor ( g1 + g0 ); + b2 = clampfix_maxcolor ( b1 + b0 ); + + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef IPOL_Z + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef IPOL_Z + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAddNoZ2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAddNoZ2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudAlpha.cpp b/src/dep/src/irrlicht/CTRTextureGouraudAlpha.cpp new file mode 100644 index 0000000..4b44815 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudAlpha.cpp @@ -0,0 +1,734 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAlpha2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setParam ( u32 index, f32 value); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + + u32 AlphaRef; +}; + +//! constructor +CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAlpha2"); + #endif + + AlphaRef = 0; +} + + +/*! +*/ +void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value) +{ +#ifdef BURNINGVIDEO_RENDERER_FAST + AlphaRef = core::floor32 ( value * 256.f ); +#else + AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); +#endif +} + +/*! +*/ +void CTRTextureGouraudAlpha2::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPointu a0; + tFixPointu r0, g0, b0; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + +#ifdef INVERSE_W + + inversew = fix_inverse32 ( line.w[0] ); + + u32 argb = getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), + d + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + +#else + + u32 argb = getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x), + d + f32_to_fixPoint ( line.t0[0].y) + ); + +#endif + + const u32 alpha = ( argb >> 24 ); + if ( alpha >= AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], argb, alpha ); + } + + +#else + + inversew = fix_inverse32 ( line.w[0] ); + + getSample_texture ( a0, r0, g0, b0, + &IT[0], + f32_to_fixPoint ( line.t0[0].x,inversew), + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + + if ( a0 >= AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], + fix_to_color ( r0,g0, b0 ), + fixPointu_to_u32 ( a0 ) + ); + } +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAlpha(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAlpha2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/src/dep/src/irrlicht/CTRTextureGouraudAlphaNoZ.cpp new file mode 100644 index 0000000..fb0f97d --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudAlphaNoZ.cpp @@ -0,0 +1,732 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAlphaNoZ : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAlphaNoZ(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setParam ( u32 index, f32 value); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + + u32 AlphaRef; +}; + +//! constructor +CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAlphaNoZ"); + #endif + + AlphaRef = 0; +} + + +/*! +*/ +void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value) +{ +#ifdef BURNINGVIDEO_RENDERER_FAST + AlphaRef = core::floor32 ( value * 256.f ); +#else + AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); +#endif +} + +/*! +*/ +void CTRTextureGouraudAlphaNoZ::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPointu a0; + tFixPointu r0, g0, b0; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + +#ifdef INVERSE_W + + inversew = fix_inverse32 ( line.w[0] ); + + u32 argb = getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), + d + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + +#else + + u32 argb = getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x), + d + f32_to_fixPoint ( line.t0[0].y) + ); + +#endif + + const u32 alpha = ( argb >> 24 ); + if ( alpha >= AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], argb, alpha ); + } + + +#else + + inversew = fix_inverse32 ( line.w[0] ); + + getSample_texture ( a0, r0, g0, b0, + &IT[0], + f32_to_fixPoint ( line.t0[0].x,inversew), + f32_to_fixPoint ( line.t0[0].y,inversew) + ); + + if ( a0 >= AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], + fix_to_color ( r0,g0, b0 ), + fixPointu_to_u32 ( a0 ) + ); + } +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAlphaNoZ(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAlphaNoZ(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudNoZ.cpp b/src/dep/src/irrlicht/CTRTextureGouraudNoZ.cpp new file mode 100644 index 0000000..7e8e652 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudNoZ.cpp @@ -0,0 +1,366 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" +#include "SColor.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudNoZ : public CTRTextureGouraud +{ +public: + + CTRTextureGouraudNoZ() + : CTRTextureGouraud(0) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWireNoZ"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightStepR = (s32)(((video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftStepR = (s32)(((video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + *hSpanBegin = video::RGB16(video::getRed(color) * (spanR>>8) >>2, video::getGreen(color) * (spanG>>8) >>2, video::getBlue(color) * (spanB>>8) >>2); + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + ++hSpanBegin; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + Texture->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraudNoZ() +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudNoZ(); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudNoZ2.cpp b/src/dep/src/irrlicht/CTRTextureGouraudNoZ2.cpp new file mode 100644 index 0000000..1b44056 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudNoZ2.cpp @@ -0,0 +1,677 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#ifdef BURNINGVIDEO_RENDERER_FAST + #define SUBTEXEL + #define INVERSE_W +#else + #define SUBTEXEL + #define INVERSE_W +#endif + +//#define USE_ZBUFFER +#define IPOL_W +//#define CMP_W +//#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudNoZ2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(IDepthBuffer* zbuffer) +: IBurningShader(0) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudNoZ2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudNoZ2::scanline_bilinear ( ) +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); +#endif + dst[i] = getTexel_plain ( &IT[0], tx0, ty0 ); + +/* + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + dst[i] = fix_to_color ( 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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudNoZ2() +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudNoZ2( 0 ); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudVertexAlpha2.cpp b/src/dep/src/irrlicht/CTRTextureGouraudVertexAlpha2.cpp new file mode 100644 index 0000000..5a08278 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudVertexAlpha2.cpp @@ -0,0 +1,720 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureVertexAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureVertexAlpha2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureVertexAlpha2::CTRTextureVertexAlpha2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureVertexAlpha2"); + #endif +} + + + +/*! +*/ +void CTRTextureVertexAlpha2::scanline_bilinear ( ) +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +//#define __TEST_THIS + +#ifdef __TEST_THIS + +#else + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + +#ifdef IPOL_C0 + tFixPoint a3; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef __TEST_THIS + + inversew = fix_inverse32 ( line.w[0] ); + + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), + f32_to_fixPoint ( line.t0[0].y,inversew) ) + ); + +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); + +#ifdef IPOL_C0 + a3 = f32_to_fixPoint ( line.c[0].y,inversew ); +#endif + +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); + +#ifdef IPOL_C0 + a3 = f32_to_fixPoint ( line.c[0].y ); +#endif + + +#endif + + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + color_to_fix ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) ); + g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) ); + b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) ); +#else + r2 = clampfix_maxcolor ( r1 + r0 ); + g2 = clampfix_maxcolor ( g1 + g0 ); + b2 = clampfix_maxcolor ( b1 + b0 ); +#endif + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureVertexAlpha2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureVertexAlpha2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureGouraudWire.cpp b/src/dep/src/irrlicht/CTRTextureGouraudWire.cpp new file mode 100644 index 0000000..f57210b --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureGouraudWire.cpp @@ -0,0 +1,361 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudWire : public CTRTextureGouraud +{ +public: + + CTRTextureGouraudWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget;//, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + + // höhe des dreiecks berechnen + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + color = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((leftTx>>8)&textureXMask)]; + *(targetSurface + leftx) = video::RGB16(video::getRed(color) * (leftR>>8) >>2, video::getGreen(color) * (leftG>>8) >>2, video::getBlue(color) * (leftR>>8) >>2); + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + color = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + *(targetSurface + rightx) = video::RGB16(video::getRed(color) * (rightR>>8) >>2, video::getGreen(color) * (rightG>>8) >>2, video::getBlue(color) * (rightR>>8) >>2); + } + + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraudWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr diff --git a/src/dep/src/irrlicht/CTRTextureLightMap2_Add.cpp b/src/dep/src/irrlicht/CTRTextureLightMap2_Add.cpp new file mode 100644 index 0000000..0c7d066 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureLightMap2_Add.cpp @@ -0,0 +1,705 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_Add : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_Add(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_Add::CTRTextureLightMap2_Add(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_Add"); + #endif +} + + + +/*! +*/ +REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + +#ifdef INVERSE_W + + const f32 inversew = fix_inverse32 ( line.w[0] ); + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + dst[i] = PixelAdd32 ( + getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), + d + f32_to_fixPoint ( line.t0[0].y,inversew) ), + getTexel_plain ( &IT[1], d + f32_to_fixPoint ( line.t1[0].x,inversew), + d + f32_to_fixPoint ( line.t1[0].y,inversew) ) + ); +#else + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + dst[i] = PixelAdd32 ( + getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x), + d + f32_to_fixPoint ( line.t0[0].y) ), + getTexel_plain ( &IT[1], d + f32_to_fixPoint ( line.t1[0].x), + d + f32_to_fixPoint ( line.t1[0].y) ) + ); + +#endif + +#else + const f32 inversew = fix_inverse32 ( line.w[0] ); + + getSample_texture ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t0[1].x,inversew), f32_to_fixPoint ( line.t0[1].y,inversew) ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ), + clampfix_maxcolor ( g0 + g1 ), + clampfix_maxcolor ( b0 + b1 ) + ); +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_Add(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_Add(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureLightMap2_M1.cpp b/src/dep/src/irrlicht/CTRTextureLightMap2_M1.cpp new file mode 100644 index 0000000..912cf38 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureLightMap2_M1.cpp @@ -0,0 +1,678 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M1 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M1(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear2 (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M1::CTRTextureLightMap2_M1(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M1"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + + a = (f32) i + subPixel; + + line.t0[1] = (line.t0[1] - line.t0[0]) * invDeltaX; + line.t1[1] = (line.t1[1] - line.t1[0]) * invDeltaX; + + line.t0[0] += line.t0[1] * a; + line.t1[0] += line.t1[1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + dst[i] = PixelMul32 ( + getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), + d + f32_to_fixPoint ( line.t0[0].y,inversew) ), + getTexel_plain ( &IT[1], d + f32_to_fixPoint ( line.t1[0].x,inversew), + d + f32_to_fixPoint ( line.t1[0].y,inversew) ) + ); + + +#else + + + getSample_texture ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t1[0].x,inversew), f32_to_fixPoint ( line.t1[0].y,inversew) ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) ) + ); +#endif + + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t0[0] += line.t0[1]; + line.t1[0] += line.t1[1]; + } + +} + + + + + +void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M1(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M1(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTRTextureLightMap2_M2.cpp b/src/dep/src/irrlicht/CTRTextureLightMap2_M2.cpp new file mode 100644 index 0000000..d20721a --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureLightMap2_M2.cpp @@ -0,0 +1,674 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear2 (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M2::CTRTextureLightMap2_M2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M2"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + + a = (f32) i + subPixel; + + line.t0[1] = (line.t0[1] - line.t0[0]) * invDeltaX; + line.t1[1] = (line.t1[1] - line.t1[0]) * invDeltaX; + + line.t0[0] += line.t0[1] * a; + line.t1[0] += line.t1[1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + getSample_texture ( r0, g0, b0, &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), d + f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], d + f32_to_fixPoint ( line.t1[0].x,inversew), d + f32_to_fixPoint ( line.t1[0].y,inversew) ); +#else + getSample_texture ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t1[0].x,inversew), f32_to_fixPoint ( line.t1[0].y,inversew) ); + +#endif + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t0[0] += line.t0[1]; + line.t1[0] += line.t1[1]; + } + +} + + + +void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureLightMap2_M4.cpp b/src/dep/src/irrlicht/CTRTextureLightMap2_M4.cpp new file mode 100644 index 0000000..d06d0de --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureLightMap2_M4.cpp @@ -0,0 +1,1404 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M4 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M4(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + + void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + void scanline_bilinear (); + void scanline_bilinear2_mag (); + void scanline_bilinear2_min (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M4"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const fp24 b = (line.w[1] - line.w[0]) * invDeltaX; + fp24 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + + a = (f32) i + subPixel; + + line.t0[1] = (line.t0[1] - line.t0[0]) * invDeltaX; + line.t1[1] = (line.t1[1] - line.t1[0]) * invDeltaX; + + line.t0[0] += line.t0[1] * a; + line.t1[0] += line.t1[1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + getSample_texture ( r0, g0, b0, &IT[0], d + f32_to_fixPoint ( line.t0[0].x,inversew), d + f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], d + f32_to_fixPoint ( line.t1[0].x,inversew), d + f32_to_fixPoint ( line.t1[0].y,inversew) ); +#else + getSample_texture ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), f32_to_fixPoint ( line.t0[0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t1[0].x,inversew), f32_to_fixPoint ( line.t1[0].y,inversew) ); + +#endif + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t0[0] += line.t0[1]; + line.t1[0] += line.t1[1]; + } + +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + + a = (f32) i + subPixel; + + line.t0[1] = (line.t0[1] - line.t0[0]) * invDeltaX; + line.t1[1] = (line.t1[1] - line.t1[0]) * invDeltaX; + + line.t0[0] += line.t0[1] * a; + line.t1[0] += line.t1[1] * a; + + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + getTexel_fix ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t0[0].x,inversew), f32_to_fixPoint ( line.t0[0].y,inversew) ); + getTexel_fix ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t1[0].x,inversew), f32_to_fixPoint ( line.t1[0].y,inversew) ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t0[0] += line.t0[1]; + line.t1[0] += line.t1[1]; + } + +} + + +#if 0 +/*! +*/ +REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPointu tx0, tx1; + tFixPointu ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); + tx1 = f32_to_fixPoint ( line.t1[0].x,inversew); + ty1 = f32_to_fixPoint ( line.t1[0].y,inversew); + +#ifdef IPOL_C0 + r3 = f32_to_fixPoint ( line.c[0].y ,inversew ); + g3 = f32_to_fixPoint ( line.c[0].z ,inversew ); + b3 = f32_to_fixPoint ( line.c[0].w ,inversew ); +#endif + +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); + tx1 = f32_to_fixPoint ( line.t1[0].x ); + ty1 = f32_to_fixPoint ( line.t1[0].y ); + +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); + +#ifdef IPOL_C0 + r2 = imulFix ( r0, r3 ); + g2 = imulFix ( g0, g3 ); + b2 = imulFix ( b0, b3 ); + + r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) ); +/* + r2 = r3 << 8; + g2 = g3 << 8; + b2 = b3 << 8; +*/ +#else + r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ); +#endif + + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} +#endif + + +#ifdef BURNINGVIDEO_RENDERER_FAST + +void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + if ( IT[0].lodLevel <= 2 ) + drawTriangle_Mag ( a, b, c ); + else + drawTriangle_Min ( a, b, c ); +} + +void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2_min (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2_min (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) + +#else + +void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) + +#endif + +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2_mag (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear2_mag (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M4(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M4(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureLightMapGouraud2_M4.cpp b/src/dep/src/irrlicht/CTRTextureLightMapGouraud2_M4.cpp new file mode 100644 index 0000000..44846e0 --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureLightMapGouraud2_M4.cpp @@ -0,0 +1,718 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRGTextureLightMap2_M4 : public IBurningShader +{ +public: + + //! constructor + CTRGTextureLightMap2_M4(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGTextureLightMap2_M4::CTRGTextureLightMap2_M4(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRGTextureLightMap2_M4"); + #endif +} + + + +/*! +*/ +void CTRGTextureLightMap2_M4::scanline_bilinear () +{ + 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 slopeT0; +#endif +#ifdef IPOL_T1 + sVec2 slopeT1; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( 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 + slopeT0 = (line.t0[1] - line.t0[0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT1 = (line.t1[1] - line.t1[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.t0[0] += slopeT0 * subPixel; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1 * subPixel; +#endif +#endif + + dst = lockedSurface + ( line.y * SurfaceWidth ) + xStart; + +#ifdef USE_ZBUFFER + z = lockedZBuffer + ( line.y * SurfaceWidth ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0, tx1; + tFixPoint ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = f32_to_fixPoint ( line.t0[0].x,inversew); + ty0 = f32_to_fixPoint ( line.t0[0].y,inversew); + tx1 = f32_to_fixPoint ( line.t1[0].x,inversew); + ty1 = f32_to_fixPoint ( line.t1[0].y,inversew); + +#ifdef IPOL_C0 + r3 = f32_to_fixPoint ( line.c[0].y ,inversew ); + g3 = f32_to_fixPoint ( line.c[0].z ,inversew ); + b3 = f32_to_fixPoint ( line.c[0].w ,inversew ); +#endif + +#else + tx0 = f32_to_fixPoint ( line.t0[0].x ); + ty0 = f32_to_fixPoint ( line.t0[0].y ); + tx1 = f32_to_fixPoint ( line.t1[0].x ); + ty1 = f32_to_fixPoint ( line.t1[0].y ); + +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); + +#ifdef IPOL_C0 + r2 = imulFix ( r0, r3 ); + g2 = imulFix ( g0, g3 ); + b2 = imulFix ( b0, b3 ); + + r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) ); +/* + r2 = r3 << 8; + g2 = g3 << 8; + b2 = b3 << 8; +*/ +#else + r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ); +#endif + + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#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.t0[0] += slopeT0; +#endif +#ifdef IPOL_T1 + line.t1[0] += slopeT1; +#endif + } + +} + +void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + + if ( F32_LOWER_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t0[0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t1[0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // query access to TexMaps + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + +#ifdef IPOL_T0 + IT[0].data = (tVideoSample*)IT[0].Texture->lock(); +#endif + +#ifdef IPOL_T1 + IT[1].data = (tVideoSample*)IT[1].Texture->lock(); +#endif + + + + // rasterize upper sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t0[1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t1[1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // 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 + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t0[0] = a->Tex[0] + scan.slopeT0[0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t1[0] = a->Tex[1] + scan.slopeT1[0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT0[1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t0[1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT1[1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t1[1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0] * subPixel; + scan.t0[1] += scan.slopeT0[1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0] * subPixel; + scan.t1[1] += scan.slopeT1[1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t0[scan.left] = scan.t0[0]; + line.t0[scan.right] = scan.t0[1]; +#endif + +#ifdef IPOL_T1 + line.t1[scan.left] = scan.t1[0]; + line.t1[scan.right] = scan.t1[1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t0[0] += scan.slopeT0[0]; + scan.t0[1] += scan.slopeT0[1]; +#endif + +#ifdef IPOL_T1 + scan.t1[0] += scan.slopeT1[0]; + scan.t1[1] += scan.slopeT1[1]; +#endif + + } + } + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +#ifdef IPOL_T0 + IT[0].Texture->unlock(); +#endif + +#ifdef IPOL_T1 + IT[1].Texture->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGTextureLightMap2_M4(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGTextureLightMap2_M4(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CTRTextureWire2.cpp b/src/dep/src/irrlicht/CTRTextureWire2.cpp new file mode 100644 index 0000000..18c647f --- /dev/null +++ b/src/dep/src/irrlicht/CTRTextureWire2.cpp @@ -0,0 +1,322 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureWire2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureWire2(IDepthBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + virtual void drawLine ( const s4DVertex *a,const s4DVertex *b); + + + +private: + void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const; + void renderLine ( const s4DVertex *a,const s4DVertex *b ) const; + +}; + +//! constructor +CTRTextureWire2::CTRTextureWire2(IDepthBuffer* zbuffer) +: IBurningShader(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureWire2"); + #endif +} + + +// swap integer with xor +static inline void swap_xor ( s32 &a, s32 &b ) +{ + a ^= b; + b ^= a; + a ^= b; +} + + +/*! +*/ +void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const +{ + + int pitch0 = SurfaceWidth << VIDEO_SAMPLE_GRANULARITY; + int pitch1 = SurfaceWidth << 2; + + int aposx = (int) a->Pos.x; + int aposy = (int) a->Pos.y; + int bposx = (int) b->Pos.x; + int bposy = (int) b->Pos.y; + + int dx = bposx - aposx; + int dy = bposy - aposy; + + int c; + int m; + int d = 0; + int run; + + tVideoSample *dst; +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY; + int yInc0 = pitch0; + + int xInc1 = 4; + int yInc1 = pitch1; + + tVideoSample color; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + tFixPoint r0, g0, b0; + getSample_color ( r0, g0, b0, a->Color[0] ); + color = fix_to_color ( r0, g0, b0 ); +#else + color = (tVideoSample) 0xFFFFFFFF; +#endif + + if ( dx < 0 ) + { + xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY); + xInc1 = -4; + dx = -dx; + } + + if ( dy > dx ) + { + swap_xor ( dx, dy ); + swap_xor ( xInc0, yInc0 ); + swap_xor ( xInc1, yInc1 ); + } + + if ( 0 == dx ) + return; + + dst = (tVideoSample*) ( (u8*) lockedSurface + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) ); +#ifdef USE_ZBUFFER + z = (fp24*) ( (u8*) lockedZBuffer + ( aposy * pitch1 ) + (aposx << 2 ) ); +#endif + + c = dx << 1; + m = dy << 1; + +#ifdef IPOL_Z + f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx); + f32 dataZ = a->Pos.z; +#endif + +#ifdef IPOL_W + fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx ); + fp24 dataW = a->Pos.w; +#endif + + run = dx; + while ( run ) + { +#ifdef CMP_Z + if ( *z >= dataZ ) +#endif +#ifdef CMP_W + if ( dataW >= *z ) +#endif + { +#ifdef WRITE_Z + *z = dataZ; +#endif +#ifdef WRITE_W + *z = dataW; +#endif + + *dst = color; + + } + + dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc +#ifdef IPOL_Z + z = (fp24*) ( (u8*) z + xInc1 ); +#endif +#ifdef IPOL_W + z = (fp24*) ( (u8*) z + xInc1 ); +#endif + + d += m; + if ( d > dx ) + { + dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc +#ifdef IPOL_Z + z = (fp24*) ( (u8*) z + yInc1 ); +#endif +#ifdef IPOL_W + z = (fp24*) ( (u8*) z + yInc1 ); +#endif + + d -= c; + } + run -= 1; +#ifdef IPOL_Z + dataZ += slopeZ; +#endif +#ifdef IPOL_W + dataW += slopeW; +#endif + + } + +} + +void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanLineData line; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + + renderLine ( a, b ); + renderLine ( b, c ); + renderLine ( a, c ); + + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +} + + +void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b) +{ + + // query access to TexMaps + + // sort on height, y + if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b); + + lockedSurface = (tVideoSample*)RenderTarget->lock(); + +#ifdef USE_ZBUFFER + lockedZBuffer = ZBuffer->lock(); +#endif + + renderLine ( a, b ); + RenderTarget->unlock(); + +#ifdef USE_ZBUFFER + ZBuffer->unlock(); +#endif + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureGouraudWire2(IDepthBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureWire2(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/dep/src/irrlicht/CTerrainSceneNode.cpp b/src/dep/src/irrlicht/CTerrainSceneNode.cpp new file mode 100644 index 0000000..e6f68e0 --- /dev/null +++ b/src/dep/src/irrlicht/CTerrainSceneNode.cpp @@ -0,0 +1,1384 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spintz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks +// go to him. + +#include "CTerrainSceneNode.h" +#include "CTerrainTriangleSelector.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "SMeshBufferLightMap.h" +#include "SViewFrustum.h" +#include "irrMath.h" +#include "os.h" +#include "IGUIFont.h" +#include "IFileSystem.h" +#include "IReadFile.h" + +namespace irr +{ +namespace scene +{ + + //! constructor + CTerrainSceneNode::CTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, + io::IFileSystem* fs, s32 id, s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) + : ITerrainSceneNode(parent, mgr, id, position, rotation, scale), + TerrainData(patchSize, maxLOD, position, rotation, scale), + VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false), + OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false), + OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), + OldCameraRotation(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), + CameraMovementDelta(10.0f), CameraRotationDelta(1.0f), + TCoordScale1(1.0f), TCoordScale2(1.0f), FileSystem(fs) + { + #ifdef _DEBUG + setDebugName("CTerrainSceneNode"); + #endif + + if (FileSystem) + FileSystem->grab(); + + setAutomaticCulling( scene::EAC_OFF ); + } + + + //! destructor + CTerrainSceneNode::~CTerrainSceneNode ( ) + { + if (TerrainData.LODDistanceThreshold) + delete [] TerrainData.LODDistanceThreshold; + + if (TerrainData.Patches) + delete [] TerrainData.Patches; + + if (FileSystem) + FileSystem->drop(); + } + + + //! Initializes the terrain data. Loads the vertices from the heightMapFile + bool CTerrainSceneNode::loadHeightMap( io::IReadFile* file, video::SColor vertexColor, s32 smoothFactor ) + { + if( !file ) + return false; + + u32 startTime = os::Timer::getRealTime(); + video::IImage* heightMap = SceneManager->getVideoDriver()->createImageFromFile( file ); + + if( !heightMap ) + { + os::Printer::print( "Was not able to load heightmap." ); + return false; + } + + HeightmapFile = file->getFileName(); + + // Get the dimension of the heightmap data + TerrainData.Size = heightMap->getDimension().Width; + + switch( TerrainData.PatchSize ) + { + case ETPS_9: + if( TerrainData.MaxLOD > 3 ) + { + TerrainData.MaxLOD = 3; + } + break; + case ETPS_17: + if( TerrainData.MaxLOD > 4 ) + { + TerrainData.MaxLOD = 4; + } + break; + case ETPS_33: + if( TerrainData.MaxLOD > 5 ) + { + TerrainData.MaxLOD = 5; + } + break; + case ETPS_65: + if( TerrainData.MaxLOD > 6 ) + { + TerrainData.MaxLOD = 6; + } + break; + case ETPS_129: + if( TerrainData.MaxLOD > 7 ) + { + TerrainData.MaxLOD = 7; + } + break; + } + + // --- Generate vertex data from heightmap ---- + // resize the vertex array for the mesh buffer one time ( makes loading faster ) + SMeshBufferLightMap* pMeshBuffer = new SMeshBufferLightMap(); + pMeshBuffer->Vertices.set_used( TerrainData.Size * TerrainData.Size ); + + video::S3DVertex2TCoords vertex; + vertex.Normal.set( 0.0f, 1.0f, 0.0f ); + vertex.Color = vertexColor; + + // Read the heightmap to get the vertex data + // Apply positions changes, scaling changes + const f32 tdSize = 1.0f/(f32)(TerrainData.Size-1); + s32 index = 0; + for( s32 x = 0; x < TerrainData.Size; ++x ) + { + for( s32 z = 0; z < TerrainData.Size; ++z ) + { + vertex.Pos.X = (f32)x; + video::SColor pixelColor(heightMap->getPixel(x,z)); + vertex.Pos.Y = (f32) pixelColor.getLuminance(); + vertex.Pos.Z = (f32)z; + + vertex.TCoords.X = vertex.TCoords2.X = x * tdSize; + vertex.TCoords.Y = vertex.TCoords2.Y = z * tdSize; + + pMeshBuffer->Vertices[index] = vertex; + ++index; + } + } + + // drop heightMap, no longer needed + heightMap->drop(); + + //! Terrain smoothing. Applause to DeusXL! + // http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=91272#91272 + + s32 run; + + for( run = 0; run < smoothFactor; ++run ) + { + for( index = 2; index < (TerrainData.Size * TerrainData.Size - 2); ++index) + { + pMeshBuffer->Vertices[index].Pos.Y = + (pMeshBuffer->Vertices[index - 2].Pos.Y + pMeshBuffer->Vertices[index - 1].Pos.Y + + pMeshBuffer->Vertices[index + 1].Pos.Y + pMeshBuffer->Vertices[index + 2].Pos.Y) / 4.0f; + } + } + + for( run = 0; run < smoothFactor; ++run) + { + for( index = TerrainData.Size; index < (TerrainData.Size * (TerrainData.Size - 1)); ++index) + { + pMeshBuffer->Vertices[index].Pos.Y = + (pMeshBuffer->Vertices[index - TerrainData.Size].Pos.Y + + pMeshBuffer->Vertices[index + TerrainData.Size].Pos.Y ) / 2.0f; + } + } + + + // calculate smooth normals for the vertices + calculateNormals( pMeshBuffer ); + + // add the MeshBuffer to the mesh + Mesh.addMeshBuffer( pMeshBuffer ); + const u32 vertexCount = pMeshBuffer->getVertexCount(); + + // We copy the data to the renderBuffer, after the normals have been calculated. + RenderBuffer.Vertices.set_used( vertexCount ); + + for( u32 i = 0; i < vertexCount; ++i ) + { + RenderBuffer.Vertices[i] = pMeshBuffer->Vertices[i]; + RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; + RenderBuffer.Vertices[i].Pos += TerrainData.Position; + } + + // We no longer need the pMeshBuffer + pMeshBuffer->drop(); + + // calculate all the necessary data for the patches and the terrain + calculateDistanceThresholds(); + createPatches(); + calculatePatchData(); + + // set the default rotation pivot point to the terrain nodes center + TerrainData.RotationPivot = TerrainData.Center; + + // Rotate the vertices of the terrain by the rotation + // specified. Must be done after calculating the terrain data, + // so we know what the current center of the terrain is. + setRotation( TerrainData.Rotation ); + + // Pre-allocate memory for indices + RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * + TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); + + const u32 endTime = os::Timer::getRealTime(); + + c8 tmp[255]; + sprintf(tmp, "Generated terrain data (%dx%d) in %.4f seconds", + TerrainData.Size, TerrainData.Size, ( endTime - startTime ) / 1000.0f ); + os::Printer::log( tmp ); + + return true; + } + + + //! Initializes the terrain data. Loads the vertices from the heightMapFile + bool CTerrainSceneNode::loadHeightMapRAW( io::IReadFile* file, s32 bitsPerPixel, video::SColor vertexColor, s32 smoothFactor ) + { + if( !file ) + return false; + + // start reading + u32 startTime = os::Timer::getTime(); + + // get file size + const long fileSize = file->getSize(); + const s32 bytesPerPixel = bitsPerPixel / 8; + + // Get the dimension of the heightmap data + TerrainData.Size = core::floor32(sqrtf( (f32)( fileSize / bytesPerPixel ) )); + + switch( TerrainData.PatchSize ) + { + case ETPS_9: + if( TerrainData.MaxLOD > 3 ) + { + TerrainData.MaxLOD = 3; + } + break; + case ETPS_17: + if( TerrainData.MaxLOD > 4 ) + { + TerrainData.MaxLOD = 4; + } + break; + case ETPS_33: + if( TerrainData.MaxLOD > 5 ) + { + TerrainData.MaxLOD = 5; + } + break; + case ETPS_65: + if( TerrainData.MaxLOD > 6 ) + { + TerrainData.MaxLOD = 6; + } + break; + case ETPS_129: + if( TerrainData.MaxLOD > 7 ) + { + TerrainData.MaxLOD = 7; + } + break; + } + + // --- Generate vertex data from heightmap ---- + // resize the vertex array for the mesh buffer one time ( makes loading faster ) + SMeshBufferLightMap* pMeshBuffer = new SMeshBufferLightMap(); + pMeshBuffer->Vertices.reallocate( TerrainData.Size * TerrainData.Size ); + + video::S3DVertex2TCoords vertex; + vertex.Normal.set( 0.0f, 1.0f, 0.0f ); + vertex.Color = vertexColor; + + // Read the heightmap to get the vertex data + // Apply positions changes, scaling changes + const f32 tdSize = 1.0f/(f32)(TerrainData.Size-1); + for( s32 x = 0; x < TerrainData.Size; ++x ) + { + for( s32 z = 0; z < TerrainData.Size; ++z ) + { + vertex.Pos.X = (f32)x; + + if( file->read( &vertex.Pos.Y, bytesPerPixel ) != bytesPerPixel ) + { + os::Printer::print("Error reading heightmap RAW file."); + pMeshBuffer->drop(); + return false; + } + + vertex.Pos.Z = (f32)z; + + vertex.TCoords.X = vertex.TCoords2.X = x * tdSize; + vertex.TCoords.Y = vertex.TCoords2.Y = z * tdSize; + + pMeshBuffer->Vertices.push_back( vertex ); + } + } + + //! Terrain smoothing. Applause to DeusXL! + // http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=91272#91272 + + s32 run; + s32 index; + + for( run = 0; run < smoothFactor; ++run ) + { + for( index = 2; index < (TerrainData.Size * TerrainData.Size - 2); ++index) + { + pMeshBuffer->Vertices[index].Pos.Y = + (pMeshBuffer->Vertices[index - 2].Pos.Y + pMeshBuffer->Vertices[index - 1].Pos.Y + + pMeshBuffer->Vertices[index + 1].Pos.Y + pMeshBuffer->Vertices[index + 2].Pos.Y) / 4.0f; + } + } + + for( run = 0; run < smoothFactor; ++run) + { + for( index = TerrainData.Size; index < (TerrainData.Size * (TerrainData.Size - 1)); ++index) + { + pMeshBuffer->Vertices[index].Pos.Y = + (pMeshBuffer->Vertices[index - TerrainData.Size].Pos.Y + + pMeshBuffer->Vertices[index + TerrainData.Size].Pos.Y ) / 2.0f; + } + } + + // calculate smooth normals for the vertices + calculateNormals( pMeshBuffer ); + + // add the MeshBuffer to the mesh + Mesh.addMeshBuffer( pMeshBuffer ); + const u32 vertexCount = pMeshBuffer->getVertexCount(); + + // We copy the data to the renderBuffer, after the normals have been calculated. + RenderBuffer.Vertices.set_used( vertexCount ); + + for( u32 i = 0; i < vertexCount; i++ ) + { + RenderBuffer.Vertices[i] = pMeshBuffer->Vertices[i]; + RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; + RenderBuffer.Vertices[i].Pos += TerrainData.Position; + } + + // We no longer need the pMeshBuffer + pMeshBuffer->drop(); + + // calculate all the necessary data for the patches and the terrain + calculateDistanceThresholds(); + createPatches(); + calculatePatchData(); + + // set the default rotation pivot point to the terrain nodes center + TerrainData.RotationPivot = TerrainData.Center; + + // Rotate the vertices of the terrain by the rotation specified. Must be done + // after calculating the terrain data, so we know what the current center of the + // terrain is. + setRotation( TerrainData.Rotation ); + + // Pre-allocate memory for indices + RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * + TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); + + u32 endTime = os::Timer::getTime(); + + c8 tmp[255]; + sprintf( tmp, "Generated terrain data (%dx%d) in %.4f seconds", + TerrainData.Size, TerrainData.Size, (endTime - startTime) / 1000.0f ); + os::Printer::print( tmp ); + + return true; + } + + + //! Sets the scale of the scene node. + //! \param scale: New scale of the node + void CTerrainSceneNode::setScale(const core::vector3df& scale) + { + TerrainData.Scale = scale; + applyTransformation(); + ForceRecalculation = true; + } + + //! Sets the rotation of the node. This only modifies + //! the relative rotation of the node. + //! \param rotation: New rotation of the node in degrees. + void CTerrainSceneNode::setRotation(const core::vector3df& rotation) + { + TerrainData.Rotation = rotation; + applyTransformation(); + ForceRecalculation = true; + } + + //! Sets the pivot point for rotation of this node. This is useful for the TiledTerrainManager to + //! rotate all terrain tiles around a global world point. + //! NOTE: The default for the RotationPivot will be the center of the individual tile. + void CTerrainSceneNode::setRotationPivot( const core::vector3df& pivot ) + { + UseDefaultRotationPivot = false; + TerrainData.RotationPivot = pivot; + } + + //! Sets the position of the node. + //! \param newpos: New postition of the scene node. + void CTerrainSceneNode::setPosition ( const core::vector3df& newpos ) + { + TerrainData.Position = newpos; + applyTransformation(); + ForceRecalculation = true; + } + + //! Apply transformation changes( scale, position, rotation ) + void CTerrainSceneNode::applyTransformation() + { + if( !Mesh.getMeshBufferCount() ) + return; + + TerrainData.Position = TerrainData.Position; + video::S3DVertex2TCoords* meshVertices = (video::S3DVertex2TCoords*)Mesh.getMeshBuffer( 0 )->getVertices(); + s32 vtxCount = Mesh.getMeshBuffer( 0 )->getVertexCount(); + core::matrix4 rotMatrix; + rotMatrix.setRotationDegrees( TerrainData.Rotation ); + + for( s32 i = 0; i < vtxCount; ++i ) + { + RenderBuffer.Vertices[i].Pos = meshVertices[i].Pos * TerrainData.Scale + TerrainData.Position; + + RenderBuffer.Vertices[i].Pos -= TerrainData.RotationPivot; + rotMatrix.inverseRotateVect( RenderBuffer.Vertices[i].Pos ); + RenderBuffer.Vertices[i].Pos += TerrainData.RotationPivot; + } + + calculateDistanceThresholds( true ); + calculatePatchData(); + } + + //! Updates the scene nodes indices if the camera has moved or rotated by a certain + //! threshold, which can be changed using the SetCameraMovementDeltaThreshold and + //! SetCameraRotationDeltaThreshold functions. This also determines if a given patch + //! for the scene node is within the view frustum and if it's not the indices are not + //! generated for that patch. + void CTerrainSceneNode::OnRegisterSceneNode() + { + if (!IsVisible || !SceneManager->getActiveCamera()) + return; + + preRenderLODCalculations(); + preRenderIndicesCalculations(); + ISceneNode::OnRegisterSceneNode(); + ForceRecalculation = false; + } + + void CTerrainSceneNode::preRenderLODCalculations() + { + 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 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 (!ForceRecalculation) + { + 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::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 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() + { + IndicesToRender = 0; + s32 index11; + s32 index21; + s32 index12; + s32 index22; + + // Then generate the indices for all patches that are visible. + for( s32 i = 0; i < TerrainData.PatchCount; ++i ) + { + for( s32 j = 0; j < TerrainData.PatchCount; ++j ) + { + s32 index = i * TerrainData.PatchCount + j; + if( TerrainData.Patches[index].CurrentLOD >= 0 ) + { + s32 x = 0; + s32 z = 0; + + // calculate the step we take this patch, based on the patches current LOD + s32 step = 1 << TerrainData.Patches[index].CurrentLOD; + + // Loop through patch and generate indices + while( z < TerrainData.CalcPatchSize ) + { + index11 = getIndex( j, i, index, x, z ); + index21 = getIndex( j, i, index, x + step, z ); + index12 = getIndex( j, i, index, x, z + step ); + index22 = getIndex( j, i, index, x + step, z + step ); + + RenderBuffer.Indices[IndicesToRender++] = index12; + RenderBuffer.Indices[IndicesToRender++] = index11; + RenderBuffer.Indices[IndicesToRender++] = index22; + RenderBuffer.Indices[IndicesToRender++] = index22; + RenderBuffer.Indices[IndicesToRender++] = index11; + RenderBuffer.Indices[IndicesToRender++] = index21; + + // increment index position horizontally + x += step; + + if ( x >= TerrainData.CalcPatchSize ) // we've hit an edge + { + x = 0; + z += step; + } + } + } + } + } + + if ( DynamicSelectorUpdate && TriangleSelector ) + { + CTerrainTriangleSelector* selector = (CTerrainTriangleSelector*)TriangleSelector; + selector->setTriangleData ( this, -1 ); + } + } + + + //! Render the scene node + void CTerrainSceneNode::render() + { + if (!IsVisible || !SceneManager->getActiveCamera()) + return; + + if (!Mesh.getMeshBufferCount()) + return; + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + core::matrix4 identity; + driver->setTransform (video::ETS_WORLD, identity); + + driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial()); + + // For use with geomorphing + driver->drawVertexPrimitiveList( + RenderBuffer.getVertices(), RenderBuffer.getVertexCount(), + RenderBuffer.getIndices(), IndicesToRender / 3, + video::EVT_2TCOORDS, EPT_TRIANGLES); + + // for debug purposes only: + if (DebugDataVisible) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox( TerrainData.BoundingBox, video::SColor(0,255,255,255)); + + const s32 count = TerrainData.PatchCount * TerrainData.PatchCount; + s32 visible = 0; + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + for( s32 j = 0; j < count; ++j ) + { + driver->draw3DBox( TerrainData.Patches[j].BoundingBox, video::SColor(0,255,0,0)); + visible += ( TerrainData.Patches[j].CurrentLOD >= 0 ); + } + + static u32 lastTime = 0; + + const u32 now = os::Timer::getRealTime(); + if ( now - lastTime > 1000 ) + { + char buf[64]; + sprintf ( buf, "Count: %d, Visible: %d", count, visible ); + os::Printer::print ( buf ); + + lastTime = now; + } + } + } + + //! Return the bounding box of the entire terrain. + const core::aabbox3d& CTerrainSceneNode::getBoundingBox() const + { + return TerrainData.BoundingBox; + } + + //! Return the bounding box of a patch + const core::aabbox3d& CTerrainSceneNode::getBoundingBox( s32 patchX, s32 patchZ ) const + { + return TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].BoundingBox; + } + + //! Gets the meshbuffer data based on a specified Level of Detail. + //! \param mb: A reference to an SMeshBuffer object + //! \param LOD: The Level Of Detail you want the indices from. + void CTerrainSceneNode::getMeshBufferForLOD(SMeshBufferLightMap& mb, s32 LOD ) const + { + if (!Mesh.getMeshBufferCount()) + return; + + if ( LOD < 0 ) + LOD = 0; + else if ( LOD > TerrainData.MaxLOD - 1 ) + LOD = TerrainData.MaxLOD - 1; + + s32 numVertices = Mesh.getMeshBuffer( 0 )->getVertexCount ( ); + mb.Vertices.reallocate ( numVertices ); + video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)Mesh.getMeshBuffer ( 0 )->getVertices ( ); + + s32 i; + for (i=0; i= TerrainData.CalcPatchSize) // we've hit an edge + { + x = 0; + z += step; + } + } + } + } + } + + //! Gets the indices for a specified patch at a specified Level of Detail. + //! \param mb: A reference to an array of u32 indices. + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \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, + //! then it will retrieve the triangles at the highest LOD ( 0 ). + //! \return: Number if indices put into the buffer. + s32 CTerrainSceneNode::getIndicesForPatch(core::array& indices, s32 patchX, s32 patchZ, s32 LOD) + { + if ( patchX < 0 || patchX > TerrainData.PatchCount - 1 || patchZ < 0 || patchZ > TerrainData.PatchCount - 1 ) + return -1; + + if ( LOD < -1 || LOD > TerrainData.MaxLOD - 1 ) + return -1; + + s32 rv = 0; + core::array cLODs; + bool setLODs = false; + + // If LOD of -1 was passed in, use the CurrentLOD of the patch specified + if ( LOD == -1 ) + { + LOD = TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].CurrentLOD; + } + else + { + getCurrentLODOfPatches(cLODs); + setCurrentLODOfPatches(LOD); + setLODs = true; + } + + if ( LOD < 0 ) + return -2; // Patch not visible, don't generate indices. + + // calculate the step we take for this LOD + s32 step = 1 << LOD; + + // Generate the indices for the specified patch at the specified LOD + s32 index = patchX * TerrainData.PatchCount + patchZ; + + s32 x = 0; + s32 z = 0; + s32 index11; + s32 index21; + s32 index12; + s32 index22; + + indices.set_used ( TerrainData.PatchSize * TerrainData.PatchSize * 6 ); + + // Loop through patch and generate indices + while (z= TerrainData.CalcPatchSize) // we've hit an edge + { + x = 0; + z += step; + } + } + + if ( setLODs ) + setCurrentLODOfPatches (cLODs); + + return rv; + } + + //! Populates an array with the CurrentLOD of each patch. + //! \param LODs: A reference to a core::array to hold the values + //! \return Returns the number of elements in the array + s32 CTerrainSceneNode::getCurrentLODOfPatches(core::array& LODs) const + { + s32 numLODs; + LODs.clear ( ); + + for ( numLODs = 0; numLODs < TerrainData.PatchCount * TerrainData.PatchCount; numLODs++ ) + LODs.push_back ( TerrainData.Patches[numLODs].CurrentLOD ); + + return LODs.size(); + } + + + //! Manually sets the LOD of a patch + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to set the patch to. + void CTerrainSceneNode::setLODOfPatch( s32 patchX, s32 patchZ, s32 LOD ) + { + TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].CurrentLOD = LOD; + } + + + //! Override the default generation of distance thresholds for determining the LOD a patch + //! is rendered at. + bool CTerrainSceneNode::overrideLODDistance(s32 LOD, f64 newDistance) + { + OverrideDistanceThreshold = true; + + if ( LOD < 0 || LOD > TerrainData.MaxLOD - 1 ) + return false; + + TerrainData.LODDistanceThreshold[LOD] = newDistance * newDistance; + + return true; + } + + //! Creates a planar texture mapping on the terrain + //! \param resolution: resolution of the planar mapping. This is the value + //! specifying the relation between world space and texture coordinate space. + void CTerrainSceneNode::scaleTexture(f32 resolution, f32 resolution2) + { + TCoordScale1 = resolution; + TCoordScale2 = resolution2; + + const f32 resBySize = resolution / (f32)(TerrainData.Size-1); + const f32 res2BySize = resolution2 / (f32)(TerrainData.Size-1); + u32 index = 0; + f32 xval = 0, zval; + f32 x2val = 0, z2val=0; + for (s32 x=0; xCurrentLOD && + (vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD)) != 0 ) + { + vX = vX - vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD ); + } + } + else + if ( vZ == (u32)TerrainData.CalcPatchSize ) // bottom border + { + if (TerrainData.Patches[PatchIndex].Bottom && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Bottom->CurrentLOD && + (vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD)) != 0) + { + vX = vX - vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD ); + } + } + + // left border + if ( vX == 0 ) + { + if (TerrainData.Patches[PatchIndex].Left && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Left->CurrentLOD && + ( vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD ) ) != 0) + { + vZ = vZ - vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD ); + } + } + else + if ( vX == (u32)TerrainData.CalcPatchSize ) // right border + { + if (TerrainData.Patches[PatchIndex].Right && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Right->CurrentLOD && + ( vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD ) ) != 0) + { + vZ = vZ - vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD ); + } + } + + if ( vZ >= (u32)TerrainData.PatchSize ) + vZ = TerrainData.CalcPatchSize; + + if ( vX >= (u32)TerrainData.PatchSize ) + vX = TerrainData.CalcPatchSize; + + return (vZ + ((TerrainData.CalcPatchSize) * PatchZ)) * TerrainData.Size + + (vX + ((TerrainData.CalcPatchSize) * PatchX)); + } + + //! calculate smooth normals + void CTerrainSceneNode::calculateNormals ( SMeshBufferLightMap* pMeshBuffer ) + { + s32 count; + core::vector3df a, b, c, t; + + for (s32 x=0; x0 && z>0) + { + a = pMeshBuffer->Vertices[(x-1)*TerrainData.Size+z-1].Pos; + b = pMeshBuffer->Vertices[(x-1)*TerrainData.Size+z].Pos; + c = pMeshBuffer->Vertices[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + a = pMeshBuffer->Vertices[(x-1)*TerrainData.Size+z-1].Pos; + b = pMeshBuffer->Vertices[x*TerrainData.Size+z-1].Pos; + c = pMeshBuffer->Vertices[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + count += 2; + } + + // top right + if (x>0 && zVertices[(x-1)*TerrainData.Size+z].Pos; + b = pMeshBuffer->Vertices[(x-1)*TerrainData.Size+z+1].Pos; + c = pMeshBuffer->Vertices[x*TerrainData.Size+z+1].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + a = pMeshBuffer->Vertices[(x-1)*TerrainData.Size+z].Pos; + b = pMeshBuffer->Vertices[x*TerrainData.Size+z+1].Pos; + c = pMeshBuffer->Vertices[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + count += 2; + } + + // bottom right + if (xVertices[x*TerrainData.Size+z+1].Pos; + b = pMeshBuffer->Vertices[x*TerrainData.Size+z].Pos; + c = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z+1].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + a = pMeshBuffer->Vertices[x*TerrainData.Size+z+1].Pos; + b = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z+1].Pos; + c = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + count += 2; + } + + // bottom left + if (x0) + { + a = pMeshBuffer->Vertices[x*TerrainData.Size+z-1].Pos; + b = pMeshBuffer->Vertices[x*TerrainData.Size+z].Pos; + c = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + a = pMeshBuffer->Vertices[x*TerrainData.Size+z-1].Pos; + b = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z].Pos; + c = pMeshBuffer->Vertices[(x+1)*TerrainData.Size+z-1].Pos; + b -= a; + c -= a; + t = b.crossProduct ( c ); + t.normalize ( ); + normal += t; + + count += 2; + } + + if ( count != 0 ) + { + normal.normalize ( ); + } + else + { + normal.set( 0.0f, 1.0f, 0.0f ); + } + + pMeshBuffer->Vertices[x * TerrainData.Size + z].Normal = normal; + } + } + } + + //! create patches, stuff that needs to be done only once for patches goes here. + void CTerrainSceneNode::createPatches() + { + TerrainData.PatchCount = (TerrainData.Size - 1) / ( TerrainData.CalcPatchSize ); + + if (TerrainData.Patches) + delete [] TerrainData.Patches; + + TerrainData.Patches = new SPatch[TerrainData.PatchCount * TerrainData.PatchCount]; + } + + //! used to calculate the internal STerrainData structure both at creation and after scaling/position calls. + void CTerrainSceneNode::calculatePatchData() + { + // Reset the Terrains Bounding Box for re-calculation + TerrainData.BoundingBox = core::aabbox3df ( 999999.9f, 999999.9f, 999999.9f, -999999.9f, -999999.9f, -999999.9f ); + + for( s32 x = 0; x < TerrainData.PatchCount; ++x ) + { + for( s32 z = 0; z < TerrainData.PatchCount; ++z ) + { + s32 index = x * TerrainData.PatchCount + z; + TerrainData.Patches[index].CurrentLOD = 0; + + // For each patch, calculate the bounding box ( mins and maxes ) + TerrainData.Patches[index].BoundingBox = core::aabbox3df (999999.9f, 999999.9f, 999999.9f, + -999999.9f, -999999.9f, -999999.9f ); + + for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx ) + for( s32 zz = z*(TerrainData.CalcPatchSize); zz <= ( z + 1 ) * TerrainData.CalcPatchSize; ++zz ) + TerrainData.Patches[index].BoundingBox.addInternalPoint( RenderBuffer.Vertices[xx * TerrainData.Size + zz].Pos ); + + // Reconfigure the bounding box of the terrain as a whole + TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox ); + + // get center of Patch + TerrainData.Patches[index].Center = TerrainData.Patches[index].BoundingBox.getCenter(); + + // Assign Neighbours + // Top + if( x > 0 ) + TerrainData.Patches[index].Top = &TerrainData.Patches[(x-1) * TerrainData.PatchCount + z]; + else + TerrainData.Patches[index].Top = 0; + + // Bottom + if( x < TerrainData.PatchCount - 1 ) + TerrainData.Patches[index].Bottom = &TerrainData.Patches[(x+1) * TerrainData.PatchCount + z]; + else + TerrainData.Patches[index].Bottom = 0; + + // Left + if( z > 0 ) + TerrainData.Patches[index].Left = &TerrainData.Patches[x * TerrainData.PatchCount + z - 1]; + else + TerrainData.Patches[index].Left = 0; + + // Right + if( z < TerrainData.PatchCount - 1 ) + TerrainData.Patches[index].Right = &TerrainData.Patches[x * TerrainData.PatchCount + z + 1]; + else + TerrainData.Patches[index].Right = 0; + + if ( TerrainData.Patches[index].DebugText ) + { + TerrainData.Patches[index].DebugText->setPosition ( TerrainData.Patches[index].Center ); + } + + } + } + + // get center of Terrain + TerrainData.Center = TerrainData.BoundingBox.getCenter(); + + // if the default rotation pivot is still being used, update it. + if( UseDefaultRotationPivot ) + { + TerrainData.RotationPivot = TerrainData.Center; + } + } + + + //! used to calculate or recalculate the distance thresholds + void CTerrainSceneNode::calculateDistanceThresholds(bool scalechanged) + { + // Only update the LODDistanceThreshold if it's not manually changed + if (!OverrideDistanceThreshold) + { + if( TerrainData.LODDistanceThreshold ) + { + delete [] TerrainData.LODDistanceThreshold; + } + + // Determine new distance threshold for determining what LOD to draw patches at + TerrainData.LODDistanceThreshold = new f64[TerrainData.MaxLOD]; + + for (s32 i=0; i& lodarray) + { + for (s32 i=0; i= 0 && X < TerrainData.Size && Z >= 0 && Z <= TerrainData.Size ) + { + const video::S3DVertex2TCoords* Vertices = (const video::S3DVertex2TCoords*)Mesh.getMeshBuffer( 0 )->getVertices(); + const core::vector3df& a = Vertices[ X * TerrainData.Size + Z ].Pos; + const core::vector3df& b = Vertices[ (X + 1) * TerrainData.Size + Z ].Pos; + const core::vector3df& c = Vertices[ X * TerrainData.Size + ( Z + 1 ) ].Pos; + const core::vector3df& d = Vertices[ (X + 1) * TerrainData.Size + ( Z + 1 ) ].Pos; + + // offset from integer position + const f32 dx = pos.X - X; + const f32 dz = pos.Z - Z; + + if( dx > dz ) + height = a.Y + (d.Y - b.Y)*dz + (b.Y - a.Y)*dx; + else + height = a.Y + (d.Y - c.Y)*dx + (c.Y - a.Y)*dz; + + height *= TerrainData.Scale.Y; + height += TerrainData.Position.Y; + } + + return height; + } + + + //! Writes attributes of the scene node. + void CTerrainSceneNode::serializeAttributes(io::IAttributes* out, + io::SAttributeReadWriteOptions* options) const + { + ISceneNode::serializeAttributes(out, options); + + out->addString("Heightmap", HeightmapFile.c_str()); + out->addFloat("TextureScale1", TCoordScale1); + out->addFloat("TextureScale2", TCoordScale2); + } + + + //! Reads attributes of the scene node. + void CTerrainSceneNode::deserializeAttributes(io::IAttributes* in, + io::SAttributeReadWriteOptions* options) + { + core::stringc newHeightmap = in->getAttributeAsString("Heightmap"); + f32 tcoordScale1 = in->getAttributeAsFloat("TextureScale1"); + f32 tcoordScale2 = in->getAttributeAsFloat("TextureScale2"); + + // set possible new heightmap + + if (newHeightmap.size() > 0 && + newHeightmap != HeightmapFile) + { + io::IReadFile* file = FileSystem->createAndOpenFile(newHeightmap.c_str()); + if (file) + { + loadHeightMap(file, video::SColor(255,255,255,255), 0); + file->drop(); + } + else + os::Printer::log("could not open heightmap", newHeightmap.c_str()); + } + + // set possible new scale + + if (core::equals(tcoordScale1, 0.f)) + tcoordScale1 = 1.0f; + + if (core::equals(tcoordScale2, 0.f)) + tcoordScale2 = 1.0f; + + if (!core::equals(tcoordScale1, TCoordScale1) || + !core::equals(tcoordScale2, TCoordScale2)) + { + scaleTexture(tcoordScale1, tcoordScale2); + } + + ISceneNode::deserializeAttributes(in, options); + } + + + //! Creates a clone of this scene node and its children. + ISceneNode* CTerrainSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) + { + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CTerrainSceneNode* nb = new CTerrainSceneNode( + newParent, newManager, FileSystem, ID, + 4, ETPS_17, getPosition(), getRotation(), getScale()); + + nb->cloneMembers(this, newManager); + + // instead of cloning the data structures, recreate the terrain. + // (temporary solution) + + // load file + + io::IReadFile* file = FileSystem->createAndOpenFile(HeightmapFile.c_str()); + if (file) + { + nb->loadHeightMap(file, video::SColor(255,255,255,255), 0); + file->drop(); + } + + // scale textures + + nb->scaleTexture(TCoordScale1, TCoordScale2); + + // copy materials + + for (unsigned int m = 0; mMesh.getMeshBufferCount()>m && + nb->Mesh.getMeshBuffer(m) && + Mesh.getMeshBuffer(m)) + { + nb->Mesh.getMeshBuffer(m)->getMaterial() = + Mesh.getMeshBuffer(m)->getMaterial(); + } + } + + nb->RenderBuffer.Material = RenderBuffer.Material; + + // finish + + nb->drop(); + return nb; + } + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CTerrainSceneNode.h b/src/dep/src/irrlicht/CTerrainSceneNode.h new file mode 100644 index 0000000..7fbb552 --- /dev/null +++ b/src/dep/src/irrlicht/CTerrainSceneNode.h @@ -0,0 +1,338 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spintz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks go to him. + +#ifndef __C_TERRAIN_SCENE_NODE_H__ +#define __C_TERRAIN_SCENE_NODE_H__ + +#include "ITerrainSceneNode.h" +#include "SMesh.h" +#include "IReadFile.h" +#include "ITextSceneNode.h" + +namespace irr +{ +namespace io +{ + class IFileSystem; +} +namespace scene +{ + //! A scene node for displaying terrain using the geo mip map algorithm. + /** The code for the TerrainSceneNode is based on the GeoMipMapSceneNode + * developed by Spintz. He made it available for Irrlicht and allowed it to be + * distributed under this licence. I only modified some parts. A lot of thanks go to him. + **/ + class CTerrainSceneNode : public ITerrainSceneNode + { + public: + + //! constructor + //! \param parent: The node which this node is a child of. Making this node a child of another node, or + //! making it a parent of another node is yet untested and most likely does not work properly. + //! \param mgr: Pointer to the scene manager. + //! \param id: The id of the node + //! \param maxLOD: The maximum LOD ( Level of Detail ) for the node. + //! \param patchSize: An E_GEOMIPMAP_PATCH_SIZE enumeration defining the size of each patch of the terrain. + //! \param position: The absolute position of this node. + //! \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + //! \param scale: The scale factor for the terrain. If you're using a heightmap of size 128x128 and would like + //! your terrain to be 12800x12800 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ). + //! If you use a Y scaling factor of 0.0f, then your terrain will be flat. + CTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, io::IFileSystem* fs, s32 id, + s32 maxLOD = 4, E_TERRAIN_PATCH_SIZE patchSize = ETPS_17, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + virtual ~CTerrainSceneNode(); + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + virtual bool loadHeightMap(io::IReadFile* file, + video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 ); + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + virtual bool loadHeightMapRAW(io::IReadFile* file, s32 bitsPerPixel = 16, + video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 ); + + //! Returns the material based on the zero based index i. This scene node only uses + //! 1 material. + //! \param i: Zero based index i. UNUSED, left in for virtual purposes. + //! \return Returns the single material this scene node uses. + virtual video::SMaterial& getMaterial ( u32 i ) + { + return Mesh.getMeshBuffer(i)->getMaterial(); + } + + //! Returns amount of materials used by this scene node ( always 1 ) + //! \return Returns current count of materials used by this scene node ( always 1 ) + virtual u32 getMaterialCount() const + { + return Mesh.getMeshBufferCount(); + } + + //! Gets the last scaling factor applied to the scene node. This value only represents the + //! last scaling factor presented to the node. For instance, if you make create the node + //! with a scale factor of ( 1.0f, 1.0f, 1.0f ) then call setScale ( 50.0f, 5.0f, 50.0f ), + //! then make another call to setScale with the values ( 2.0f, 2.0f, 2.0f ), this will return + //! core::vector3df ( 2.0f, 2.0f, 2.0f ), although the total scaling of the scene node is + //! core::vector3df ( 100.0f, 10.0f, 100.0f ). + //! \return Returns the last scaling factor passed to the scene node. + virtual core::vector3df getScale() const + { + return TerrainData.Scale; + } + + //! Scales the scene nodes vertices by the vector specified. + //! \param scale: Scaling factor to apply to the node. + virtual void setScale(const core::vector3df& scale); + + //! Gets the last rotation factor applied to the scene node. + //! \return Returns the last rotation factor applied to the scene node. + virtual const core::vector3df& getRotation() const + { + return TerrainData.Rotation; + } + + //! Rotates the node. This only modifies the relative rotation of the node. + //! \param rotation: New rotation of the node in degrees. + virtual void setRotation(const core::vector3df& rotation); + + //! Sets the pivot point for rotation of this node. This is useful for the TiledTerrainManager to + //! rotate all terrain tiles around a global world point. + //! NOTE: The default for the RotationPivot will be the center of the individual tile. + virtual void setRotationPivot( const core::vector3df& pivot ); + + //! Gets the last positioning vector applied to the scene node. + //! \return Returns the last position vector applied to the scene node. + virtual const core::vector3df getPosition() const + { + return TerrainData.Position; + } + + //! Moves the scene nodes vertices by the vector specified. + //! \param newpos: Vector specifying how much to move each vertex of the scene node. + virtual void setPosition(const core::vector3df& newpos); + + //! Updates the scene nodes indices if the camera has moved or rotated by a certain + //! threshold, which can be changed using the SetCameraMovementDeltaThreshold and + //! SetCameraRotationDeltaThreshold functions. This also determines if a given patch + //! for the scene node is within the view frustum and if it's not the indices are not + //! generated for that patch. + virtual void OnRegisterSceneNode(); + + //! Render the scene node + virtual void render(); + + //! Return the bounding box of the entire terrain. + virtual const core::aabbox3d& getBoundingBox() const; + + //! Return the bounding box of a patch + virtual const core::aabbox3d& getBoundingBox(s32 patchX, s32 patchZ) const; + + //! Return the number of indices currently used to draw the scene node. + virtual u32 getIndexCount() const { return IndicesToRender; } + + //! Returns the mesh + virtual IMesh* getMesh() { return &Mesh; } + + //! Gets the meshbuffer data based on a specified Level of Detail. + //! \param mb: A reference to an SMeshBufferLightMap object + //! \param LOD: The Level Of Detail you want the indices from. + virtual void getMeshBufferForLOD(SMeshBufferLightMap& mb, s32 LOD ) const; + + //! Gets the indices for a specified patch at a specified Level of Detail. + //! \param indices: A reference to an array of u32 indices. + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \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, + //! then it will retrieve the triangles at the highest LOD ( 0 ). + //! \return: Number if indices put into the buffer. + virtual s32 getIndicesForPatch(core::array& indices, + s32 patchX, s32 patchZ, s32 LOD = 0 ); + + //! Populates an array with the CurrentLOD of each patch. + //! \param LODs: A reference to a core::array to hold the values + //! \return Returns the number of elements in the array + virtual s32 getCurrentLODOfPatches(core::array& LODs) const; + + //! Manually sets the LOD of a patch + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to set the patch to. + virtual void setLODOfPatch( s32 patchX, s32 patchZ, s32 LOD ); + + //! Returns center of terrain. + virtual const core::vector3df& getTerrainCenter() const + { + return TerrainData.Center; + } + + //! Returns center of terrain. + virtual f32 getHeight( f32 x, f32 y ) const; + + //! Sets the movement camera threshold which is used to determine when to recalculate + //! indices for the scene node. The default value is 10.0f. + virtual void setCameraMovementDelta(f32 delta) + { + CameraMovementDelta = delta; + } + + //! Sets the rotation camera threshold which is used to determine when to recalculate + //! indices for the scene node. The default value is 1.0f. + virtual void setCameraRotationDelta(f32 delta) + { + CameraRotationDelta = delta; + } + + //! Sets whether or not the node should dynamically update it's associated selector when + //! the geomipmap data changes. + //! param bVal: Boolean value representing whether or not to update selector dynamically. + //! NOTE: Temporarily disabled while working out issues with DynamicSelectorUpdate + virtual void setDynamicSelectorUpdate(bool bVal ) { DynamicSelectorUpdate = false; } + //virtual void setDynamicSelectorUpdate ( bool bVal ) { DynamicSelectorUpdate = bVal; } + + //! 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 + //! 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 + //! work best with your new terrain size. + virtual bool overrideLODDistance( s32 LOD, f64 newDistance ); + + //! Scales the two textures + virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const {return ESNT_TERRAIN;} + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, + io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, + io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent, + ISceneManager* newManager); + + private: + + friend class CTerrainTriangleSelector; + friend class CTiledTerrainSceneNodeManager; + + struct SPatch + { + SPatch() + : CurrentLOD(-1), DebugText(0), + Top(0), Bottom(0), Right(0), Left(0) + { + } + + s32 CurrentLOD; + core::aabbox3df BoundingBox; + core::vector3df Center; + scene::ITextSceneNode* DebugText; + SPatch* Top; + SPatch* Bottom; + SPatch* Right; + SPatch* Left; + }; + + struct STerrainData + { + STerrainData() + : Size(0), PatchSize(0), CalcPatchSize(0), + PatchCount(0), MaxLOD(0), + BoundingBox(core::aabbox3df( 99999.9f, 99999.9f, 99999.9f, -99999.9f, -99999.9f, -99999.9f)), + LODDistanceThreshold(0), Patches(0) + { + } + + STerrainData(s32 patchSize, s32 maxLOD, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) + : Size(0), Position(position), Rotation(rotation), Scale(scale), + PatchSize(patchSize), CalcPatchSize(patchSize-1), + PatchCount(0), MaxLOD(maxLOD), + BoundingBox(core::aabbox3df( 99999.9f, 99999.9f, 99999.9f, -99999.9f, -99999.9f, -99999.9f)), + LODDistanceThreshold(0), Patches(0) + { + } + + s32 Size; + core::vector3df Position; + core::vector3df Rotation; + core::vector3df RotationPivot; + core::vector3df Scale; + core::vector3df Center; + s32 PatchSize; + s32 CalcPatchSize; + s32 PatchCount; + s32 MaxLOD; + core::aabbox3df BoundingBox; + f64* LODDistanceThreshold; + SPatch* Patches; + }; + + virtual void preRenderLODCalculations(); + virtual void preRenderLODCalculations_old(); + virtual void preRenderIndicesCalculations(); + + //! 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; + + //! calculate smooth normals + void calculateNormals(SMeshBufferLightMap* pMeshBuffer ); + + //! create patches, stuff that needs to only be done once for patches goes here. + void createPatches(); + + //! calculate the internal STerrainData structure + void calculatePatchData(); + + //! calculate or recalculate the distance thresholds + void calculateDistanceThresholds(bool scalechanged = false); + + //! sets the CurrentLOD of all patches to the specified LOD + void setCurrentLODOfPatches(s32 i); + + //! sets the CurrentLOD of TerrainData patches to the LODs specified in the array + void setCurrentLODOfPatches(core::array& lodarray); + + //! Apply transformation changes( scale, position, rotation ) + void applyTransformation(); + + STerrainData TerrainData; + SMesh Mesh; + SMeshBufferLightMap RenderBuffer; + u32 VerticesToRender; + u32 IndicesToRender; + + bool DynamicSelectorUpdate; + bool OverrideDistanceThreshold; + bool UseDefaultRotationPivot; + bool ForceRecalculation; + + core::vector3df OldCameraPosition; + core::vector3df OldCameraRotation; + f32 CameraMovementDelta; + f32 CameraRotationDelta; + + // needed for (de)serialization + f32 TCoordScale1; + f32 TCoordScale2; + core::stringc HeightmapFile; + io::IFileSystem* FileSystem; + }; + + +} // end namespace scene +} // end namespace irr + +#endif // __C_TERRAIN_SCENE_NODE_H__ + diff --git a/src/dep/src/irrlicht/CTerrainTriangleSelector.cpp b/src/dep/src/irrlicht/CTerrainTriangleSelector.cpp new file mode 100644 index 0000000..f2c3582 --- /dev/null +++ b/src/dep/src/irrlicht/CTerrainTriangleSelector.cpp @@ -0,0 +1,190 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTerrainTriangleSelector.h" +#include "CTerrainSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD ) +: SceneNode ( node ) +{ + #ifdef _DEBUG + setDebugName ("CTerrainTriangleSelector"); + #endif + + setTriangleData ( node, LOD ); +} + +//! destructor +CTerrainTriangleSelector::~CTerrainTriangleSelector() +{ + TrianglePatches.TrianglePatchArray.clear ( ); +} + +//! Clears and sets triangle data +void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD) +{ + core::triangle3df tri; + core::array indices; + CTerrainSceneNode* terrainNode = (CTerrainSceneNode*)node; + + // Get pointer to the GeoMipMaps vertices + video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)terrainNode->RenderBuffer.getVertices(); + + // Clear current data + TrianglePatches.TotalTriangles = 0; + TrianglePatches.NumPatches = terrainNode->TerrainData.PatchCount * terrainNode->TerrainData.PatchCount; + + TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches); + for (int o=0; oTerrainData.PatchCount; ++x ) + { + for(s32 z = 0; z < terrainNode->TerrainData.PatchCount; ++z ) + { + s32 tIndex = x * terrainNode->TerrainData.PatchCount + z; + TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0; + TrianglePatches.TrianglePatchArray[tIndex].Box = terrainNode->getBoundingBox( x, z ); + u32 indexCount = terrainNode->getIndicesForPatch( indices, x, z, LOD ); + + TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3); + for(u32 i = 0; i < indexCount; i += 3 ) + { + tri.pointA = vertices[indices[i+0]].Pos; + tri.pointB = vertices[indices[i+1]].Pos; + tri.pointC = vertices[indices[i+2]].Pos; + TrianglePatches.TrianglePatchArray[tIndex].Triangles.push_back(tri); + ++TrianglePatches.TrianglePatchArray[tIndex].NumTriangles; + } + + TrianglePatches.TotalTriangles += TrianglePatches.TrianglePatchArray[tIndex].NumTriangles; + } + } +} + +//! Gets all triangles. +void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform ) const +{ + s32 count = TrianglePatches.TotalTriangles; + + if (count > arraySize) + count = arraySize; + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& box, + const core::matrix4* transform) const +{ + s32 count = TrianglePatches.TotalTriangles; + + if (count > arraySize) + count = arraySize; + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& line, + const core::matrix4* transform) const +{ + s32 count = TrianglePatches.TotalTriangles; + + if (count > arraySize) + count = arraySize; + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& box, const core::matrix4* transform = 0 ) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles ( core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform = 0 ) const; + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount ( ) const; + +private: + + friend class CTerrainSceneNode; + + struct SGeoMipMapTrianglePatch + { + core::array Triangles; + s32 NumTriangles; + core::aabbox3df Box; + }; + + struct SGeoMipMapTrianglePatches + { + SGeoMipMapTrianglePatches ( ) + { + TotalTriangles = 0; + NumPatches = 0; + } + + core::array TrianglePatchArray; + s32 NumPatches; + u32 TotalTriangles; + }; + + ITerrainSceneNode* SceneNode; + SGeoMipMapTrianglePatches TrianglePatches; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_TERRAIN_TRIANGLE_SELECTOR_H__ + diff --git a/src/dep/src/irrlicht/CTextSceneNode.cpp b/src/dep/src/irrlicht/CTextSceneNode.cpp new file mode 100644 index 0000000..8c58d9a --- /dev/null +++ b/src/dep/src/irrlicht/CTextSceneNode.cpp @@ -0,0 +1,418 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTextSceneNode.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "IGUISpriteBank.h" +#include "SMeshBuffer.h" +#include "os.h" + + +namespace irr +{ +namespace scene +{ + + +//! constructor +CTextSceneNode::CTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font, scene::ISceneCollisionManager* coll, + const core::vector3df& position, const wchar_t* text, + video::SColor color) + : ITextSceneNode(parent, mgr, id, position), Text(text), Color(color), + Font(font), Coll(coll) + +{ + #ifdef _DEBUG + setDebugName("CTextSceneNode"); + #endif + + if (Font) + Font->grab(); + + setAutomaticCulling(scene::EAC_OFF); +} + +//! destructor +CTextSceneNode::~CTextSceneNode() +{ + if (Font) + Font->drop(); +} + +void CTextSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + ISceneNode::OnRegisterSceneNode(); + } +} + +//! renders the node. +void CTextSceneNode::render() +{ + if (!Font || !Coll) + return; + + core::position2d pos = Coll->getScreenCoordinatesFrom3DPosition(getAbsolutePosition(), + SceneManager->getActiveCamera()); + + core::rect r(pos, core::dimension2d(1,1)); + Font->draw(Text.c_str(), r, Color, true, true); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CTextSceneNode::getBoundingBox() const +{ + return Box; +} + +//! sets the text string +void CTextSceneNode::setText(const wchar_t* text) +{ + Text = text; +} + + +//! sets the color of the text +void CTextSceneNode::setTextColor(video::SColor color) +{ + Color = color; +} + + +//!--------------------------------- CBillboardTextSceneNode ---------------------------------------------- + + +//! constructor +CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font,const wchar_t* text, + const core::vector3df& position, const core::dimension2d& size, + video::SColor shade_top,video::SColor shade_bottom ) +: ITextSceneNode(parent, mgr, id, position), + Font(0), Shade_top(shade_top), Shade_bottom(shade_bottom), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CBillboardTextSceneNode"); + #endif + + Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + Material.MaterialTypeParam = 0.5f; + Material.BackfaceCulling = false; + Material.Lighting = false; + Material.ZBuffer = false; + Material.ZWriteEnable = false; + + if (font) + { + // doesn't support other font types + if (font->getType() == gui::EGFT_BITMAP) + { + Font = (gui::IGUIFontBitmap*)font; + Font->grab(); + + // mesh with one buffer per texture + Mesh = new SMesh(); + for (u32 i=0; igetSpriteBank()->getTextureCount(); ++i) + { + SMeshBuffer *mb = new SMeshBuffer(); + mb->Material = Material; + mb->Material.setTexture(0, Font->getSpriteBank()->getTexture(i)); + Mesh->addMeshBuffer(mb); + mb->drop(); + } + } + else + { + os::Printer::log("Sorry, CBillboardTextSceneNode does not support this font type", ELL_INFORMATION); + } + } + + setText(text); + setSize(size); + + setAutomaticCulling ( scene::EAC_BOX ); +} + + + +CBillboardTextSceneNode::~CBillboardTextSceneNode() +{ + if (Font) + Font->drop(); + + if (Mesh) + Mesh->drop(); + +} + + +//! sets the text string +void CBillboardTextSceneNode::setText(const wchar_t* text) +{ + Text = text; + + Symbol.clear(); + + // clear mesh + for (u32 j=0; j < Mesh->getMeshBufferCount(); ++j) + { + ((SMeshBuffer*)Mesh->getMeshBuffer(j))->Indices.clear(); + ((SMeshBuffer*)Mesh->getMeshBuffer(j))->Vertices.clear(); + } + + if (!Font) + return; + + const core::array< core::rect > &sourceRects = Font->getSpriteBank()->getPositions(); + const core::array< gui::SGUISprite > &sprites = Font->getSpriteBank()->getSprites(); + + f32 dim[2]; + f32 tex[4]; + + u32 i; + for ( i = 0; i != Text.size (); ++i ) + { + SSymbolInfo info; + + u32 spriteno = Font->getSpriteNoFromChar( &text[i] ); + u32 rectno = sprites[spriteno].Frames[0].rectNumber; + u32 texno = sprites[spriteno].Frames[0].textureNumber; + + dim[0] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Width ); + dim[1] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Height ); + + const core::rect& s = sourceRects[rectno]; + + // add space for letter to buffer + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(texno); + u32 firstInd = buf->Indices.size(); + u32 firstVert = buf->Vertices.size(); + buf->Indices.set_used(firstInd + 6); + buf->Vertices.set_used(firstVert + 4); + + tex[0] = (s.LowerRightCorner.X * dim[0]) + 0.5f*dim[0]; // half pixel + tex[1] = (s.LowerRightCorner.Y * dim[1]) + 0.5f*dim[1]; + tex[2] = (s.UpperLeftCorner.Y * dim[1]) - 0.5f*dim[1]; + tex[3] = (s.UpperLeftCorner.X * dim[0]) - 0.5f*dim[0]; + + buf->Vertices[firstVert+0].TCoords.set(tex[0], tex[1]); + buf->Vertices[firstVert+1].TCoords.set(tex[0], tex[2]); + buf->Vertices[firstVert+2].TCoords.set(tex[3], tex[2]); + buf->Vertices[firstVert+3].TCoords.set(tex[3], tex[1]); + + buf->Vertices[firstVert+0].Color = Shade_bottom; + buf->Vertices[firstVert+3].Color = Shade_bottom; + buf->Vertices[firstVert+1].Color = Shade_top; + buf->Vertices[firstVert+2].Color = Shade_top; + + buf->Indices[firstInd+0] = firstVert+0; + buf->Indices[firstInd+1] = firstVert+2; + buf->Indices[firstInd+2] = firstVert+1; + buf->Indices[firstInd+3] = firstVert+0; + buf->Indices[firstInd+4] = firstVert+3; + buf->Indices[firstInd+5] = firstVert+2; + + wchar_t *tp = 0; + if (i>0) + tp = &Text[i-1]; + + info.Width = (f32)s.getWidth(); + info.bufNo = texno; + info.Kerning = (f32)Font->getKerningWidth(&Text[i], tp); + info.firstInd = firstInd; + info.firstVert = firstVert; + + Symbol.push_back(info); + + } +} + + +//! pre render event +void CBillboardTextSceneNode::OnRegisterSceneNode() +{ + if (!IsVisible || !Font || !Mesh) + return; + + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + if (!camera) + return; + + // get text width + f32 textLength = 0.f; + u32 i; + for(i=0; i!=Symbol.size(); ++i) + { + SSymbolInfo &info = Symbol[i]; + textLength += info.Kerning + info.Width; + } + if (textLength<0.0f) + textLength=1.0f; + +// const core::matrix4 &m = camera->getViewFrustum()->Matrices[ video::ETS_VIEW ]; + + // make billboard look to camera + core::vector3df pos = getAbsolutePosition(); + + core::vector3df campos = camera->getAbsolutePosition(); + core::vector3df target = camera->getTarget(); + core::vector3df up = camera->getUpVector(); + core::vector3df view = target - campos; + view.normalize(); + + core::vector3df horizontal = up.crossProduct(view); + if ( horizontal.getLength() == 0 ) + { + horizontal.set(up.Y,up.X,up.Z); + } + + horizontal.normalize(); + core::vector3df space = horizontal; + + horizontal *= 0.5f * Size.Width; + + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * Size.Height; + + view *= -1.0f; + + // center text + pos += space * (Size.Width * -0.5f); + + for ( i = 0; i!= Symbol.size(); ++i ) + { + SSymbolInfo &info = Symbol[i]; + f32 infw = info.Width / textLength; + f32 infk = info.Kerning / textLength; + f32 w = (Size.Width * infw * 0.5f); + pos += space * w; + + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo); + + buf->Vertices[info.firstVert+0].Normal = view; + buf->Vertices[info.firstVert+1].Normal = view; + buf->Vertices[info.firstVert+2].Normal = view; + buf->Vertices[info.firstVert+3].Normal = view; + + buf->Vertices[info.firstVert+0].Pos = pos + (space * w) + vertical; + buf->Vertices[info.firstVert+1].Pos = pos + (space * w) - vertical; + buf->Vertices[info.firstVert+2].Pos = pos - (space * w) - vertical; + buf->Vertices[info.firstVert+3].Pos = pos - (space * w) + vertical; + + pos += space * (Size.Width*infk + w); + } + + // make bounding box + + for (i=0; i< Mesh->getMeshBufferCount() ; ++i) + ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox(); + Mesh->recalculateBoundingBox(); + + BBox = Mesh->getBoundingBox(); + core::matrix4 mat = getAbsoluteTransformation(); + mat.makeInverse(); + mat.transformBox(BBox); + + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CBillboardTextSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + // draw + core::matrix4 mat; + driver->setTransform(video::ETS_WORLD, mat); + + + + u32 i; + for ( i = 0; i < Mesh->getMeshBufferCount(); ++i ) + { + driver->setMaterial(Mesh->getMeshBuffer(i)->getMaterial()); + driver->drawMeshBuffer(Mesh->getMeshBuffer(i)); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(BBox, video::SColor(0,208,195,152)); + } + +} + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBillboardTextSceneNode::getBoundingBox() const +{ + return BBox; +} + + +//! sets the size of the billboard +void CBillboardTextSceneNode::setSize(const core::dimension2d& size) +{ + Size = size; + + if (Size.Width == 0.0f) + Size.Width = 1.0f; + + if (Size.Height == 0.0f ) + Size.Height = 1.0f; + + //f32 avg = (size.Width + size.Height)/6; + //BBox.MinEdge.set(-avg,-avg,-avg); + //BBox.MaxEdge.set(avg,avg,avg); +} + + +video::SMaterial& CBillboardTextSceneNode::getMaterial(u32 i) +{ + if (Mesh && Mesh->getMeshBufferCount() > i ) + return Mesh->getMeshBuffer(i)->getMaterial(); + else + return Material; +} + + +//! returns amount of materials used by this scene node. +u32 CBillboardTextSceneNode::getMaterialCount() const +{ + if (Mesh) + return Mesh->getMeshBufferCount(); + else + return 0; +} + + +//! gets the size of the billboard +const core::dimension2d& CBillboardTextSceneNode::getSize() +{ + return Size; +} + + + + +//! sets the color of the text +void CBillboardTextSceneNode::setTextColor(video::SColor color) +{ + Color = color; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CTextSceneNode.h b/src/dep/src/irrlicht/CTextSceneNode.h new file mode 100644 index 0000000..81edb42 --- /dev/null +++ b/src/dep/src/irrlicht/CTextSceneNode.h @@ -0,0 +1,129 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TEXT_SCENE_NODE_H_INCLUDED__ +#define __C_TEXT_SCENE_NODE_H_INCLUDED__ + +#include "ITextSceneNode.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "ISceneCollisionManager.h" +#include "SMesh.h" + +namespace irr +{ +namespace scene +{ + + + class CTextSceneNode : public ITextSceneNode + { + public: + + //! constructor + CTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font, scene::ISceneCollisionManager* coll, + const core::vector3df& position = core::vector3df(0,0,0), const wchar_t* text=0, + video::SColor color=video::SColor(100,0,0,0)); + + //! destructor + virtual ~CTextSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the text string + virtual void setText(const wchar_t* text); + + //! sets the color of the text + virtual void setTextColor(video::SColor color); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_TEXT; } + + private: + + core::stringw Text; + video::SColor Color; + gui::IGUIFont* Font; + scene::ISceneCollisionManager* Coll; + core::aabbox3d Box; + }; + + class CBillboardTextSceneNode : public ITextSceneNode + { + public: + + CBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font,const wchar_t* text, + const core::vector3df& position, const core::dimension2d& size, + video::SColor shade_top, video::SColor shade_bottom); + + //! destructor + virtual ~CBillboardTextSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the text string + virtual void setText(const wchar_t* text); + + //! sets the color of the text + virtual void setTextColor(video::SColor color); + + //! sets the size of the billboard + virtual void setSize(const core::dimension2d& size); + + //! gets the size of the billboard + virtual const core::dimension2d& getSize(); + + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_TEXT; } + + private: + + core::stringw Text; + video::SColor Color; + gui::IGUIFontBitmap* Font; + + core::dimension2d Size; + core::aabbox3d BBox; + video::SMaterial Material; + + video::SColor Shade_top; + video::SColor Shade_bottom; + struct SSymbolInfo + { + u32 bufNo; + f32 Width; + f32 Kerning; + u32 firstInd; + u32 firstVert; + }; + + core::array < SSymbolInfo > Symbol; + + SMesh *Mesh; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CTimer.h b/src/dep/src/irrlicht/CTimer.h new file mode 100644 index 0000000..f1326fb --- /dev/null +++ b/src/dep/src/irrlicht/CTimer.h @@ -0,0 +1,102 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_C_TIMER_H_INCLUDED__ +#define __C_IRR_C_TIMER_H_INCLUDED__ + +#include "ITimer.h" +#include "os.h" + +namespace irr +{ + //! Device independent implementation of the timer + class CTimer : public ITimer + { + public: + + CTimer() + { + os::Timer::initTimer(); + } + + //! Returns current real time in milliseconds of the system. + /** This value does not start with 0 when the application starts. + For example in one implementation the value returned could be the + amount of milliseconds which have elapsed since the system was started. */ + virtual u32 getRealTime() const + { + return os::Timer::getRealTime(); + } + + //! Returns current virtual time in milliseconds. + /** This value starts with 0 and can be manipulated using setTime(), stopTimer(), + startTimer(), etc. This value depends on the set speed of the timer if the timer + is stopped, etc. If you need the system time, use getRealTime() */ + virtual u32 getTime() const + { + return os::Timer::getTime(); + } + + //! sets current virtual time + virtual void setTime(u32 time) + { + os::Timer::setTime(time); + } + + //! Stops the game timer. + /** The timer is reference counted, which means everything which calls + stopTimer() will also have to call startTimer(), otherwise the timer may not start/stop + corretly again. */ + virtual void stop() + { + os::Timer::stopTimer(); + } + + //! Starts the game timer. + /** The timer is reference counted, which means everything which calls + stopTimer() will also have to call startTimer(), otherwise the timer may not start/stop + corretly again. */ + virtual void start() + { + os::Timer::startTimer(); + } + + //! Sets the speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual void setSpeed(f32 speed = 1.0f) + { + os::Timer::setSpeed(speed); + } + + //! Returns current speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual f32 getSpeed() const + { + return os::Timer::getSpeed(); + } + + //! Returns if game timer is currently stopped + virtual bool isStopped() const + { + bool ret = os::Timer::isStopped(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; + } + + //! Advances the virtual time + /** Makes the virtual timer update the time value based on the real time. This is + called automaticly when calling IrrlichtDevice::run(), but you can call it manually + if you don't use this method. */ + virtual void tick() + { + os::Timer::tick(); + } + }; + +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/CTriangleBBSelector.cpp b/src/dep/src/irrlicht/CTriangleBBSelector.cpp new file mode 100644 index 0000000..fdd142d --- /dev/null +++ b/src/dep/src/irrlicht/CTriangleBBSelector.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTriangleBBSelector.h" +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CTriangleBBSelector::CTriangleBBSelector(ISceneNode* node) +: CTriangleSelector(node) +{ + #ifdef _DEBUG + setDebugName("CTriangleBBSelector"); + #endif + + Triangles.set_used(12); // a box has 12 triangles. +} + + + +//! Gets all triangles. +void CTriangleBBSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform) const +{ + if (!SceneNode) + return; + + // construct triangles + core::aabbox3d box = SceneNode->getBoundingBox(); + core::vector3df edges[8]; + box.getEdges(edges); + + Triangles[0].set( edges[3], edges[0], edges[2]); + Triangles[1].set( edges[3], edges[1], edges[0]); + + Triangles[2].set( edges[3], edges[2], edges[7]); + Triangles[3].set( edges[7], edges[2], edges[6]); + + Triangles[4].set( edges[7], edges[6], edges[4]); + Triangles[5].set( edges[5], edges[7], edges[4]); + + Triangles[6].set( edges[5], edges[4], edges[0]); + Triangles[7].set( edges[5], edges[0], edges[1]); + + Triangles[8].set( edges[1], edges[3], edges[7]); + Triangles[9].set( edges[1], edges[7], edges[5]); + + Triangles[10].set(edges[0], edges[6], edges[2]); + Triangles[11].set(edges[0], edges[4], edges[6]); + + // call parent + CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CTriangleBBSelector.h b/src/dep/src/irrlicht/CTriangleBBSelector.h new file mode 100644 index 0000000..b373aeb --- /dev/null +++ b/src/dep/src/irrlicht/CTriangleBBSelector.h @@ -0,0 +1,33 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_BB_SELECTOR_H_INCLUDED__ +#define __C_TRIANGLE_BB_SELECTOR_H_INCLUDED__ + +#include "CTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! Stupid triangle selector without optimization +class CTriangleBBSelector : public CTriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + CTriangleBBSelector(ISceneNode* node); + + //! Gets all triangles. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform=0) const; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CTriangleSelector.cpp b/src/dep/src/irrlicht/CTriangleSelector.cpp new file mode 100644 index 0000000..89cb74e --- /dev/null +++ b/src/dep/src/irrlicht/CTriangleSelector.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTriangleSelector.h" +#include "ISceneNode.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CTriangleSelector::CTriangleSelector(ISceneNode* node) +: SceneNode(node) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif +} + + +//! constructor +CTriangleSelector::CTriangleSelector(IMesh* mesh, ISceneNode* node) +: SceneNode(node) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + const u32 cnt = mesh->getMeshBufferCount(); + for (u32 i=0; igetMeshBuffer(i); + + s32 idxCnt = buf->getIndexCount(); + const u16* const indices = buf->getIndices(); + core::triangle3df tri; + + switch (buf->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buf->getVertices(); + for (s32 j=0; jgetVertices(); + for (s32 j=0; jgetVertices(); + for (s32 j=0; j box, ISceneNode* node) +: SceneNode(node) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + // TODO +} + + +//! Gets all triangles. +void CTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform) const +{ + s32 cnt = Triangles.size(); + if (cnt > arraySize) + cnt = arraySize; + + core::matrix4 mat; + + if (transform) + mat = *transform; + + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + for (s32 i=0; i& box, + const core::matrix4* transform) const +{ + // return all triangles + getTriangles(triangles, arraySize, outTriangleCount, transform); +} + + +//! Gets all triangles which have or may have contact with a 3d line. +void CTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::line3d& line, + const core::matrix4* transform) const +{ + // return all triangles + getTriangles(triangles, arraySize, outTriangleCount, transform); +} + + +//! Returns amount of all available triangles in this selector +s32 CTriangleSelector::getTriangleCount() const +{ + return Triangles.size(); +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CTriangleSelector.h b/src/dep/src/irrlicht/CTriangleSelector.h new file mode 100644 index 0000000..6143eef --- /dev/null +++ b/src/dep/src/irrlicht/CTriangleSelector.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "ITriangleSelector.h" +#include "IMesh.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +class ISceneNode; + +//! Stupid triangle selector without optimization +class CTriangleSelector : public ITriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + CTriangleSelector(ISceneNode* node); + + //! Constructs a selector based on a mesh + CTriangleSelector(IMesh* mesh, ISceneNode* node); + + //! Constructs a selector based on a bounding box + CTriangleSelector(core::aabbox3d box, ISceneNode* node); + + //! Gets all triangles. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform=0) const; + + //! Gets all triangles which lie within a specific bounding box. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount() const; + +protected: + + ISceneNode* SceneNode; + mutable core::array Triangles; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CVideoModeList.cpp b/src/dep/src/irrlicht/CVideoModeList.cpp new file mode 100644 index 0000000..5067a5a --- /dev/null +++ b/src/dep/src/irrlicht/CVideoModeList.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CVideoModeList.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CVideoModeList::CVideoModeList() +{ + Desktop.depth = 0; + Desktop.size = core::dimension2d(0,0); +} + + +//! destructor +CVideoModeList::~CVideoModeList() +{ +} + + + +void CVideoModeList::setDesktop(s32 desktopDepth, const core::dimension2d& desktopSize) +{ + Desktop.depth = desktopDepth; + Desktop.size = desktopSize; +} + + +//! Gets amount of video modes in the list. +s32 CVideoModeList::getVideoModeCount() const +{ + return (s32)VideoModes.size(); +} + + + +//! Returns the screen size of a video mode in pixels. +core::dimension2d CVideoModeList::getVideoModeResolution(s32 modeNumber) const +{ + if (modeNumber < 0 || modeNumber > (s32)VideoModes.size()) + return core::dimension2d(0,0); + + return VideoModes[modeNumber].size; +} + + + +//! Returns the pixel depth of a video mode in bits. +s32 CVideoModeList::getVideoModeDepth(s32 modeNumber) const +{ + if (modeNumber < 0 || modeNumber > (s32)VideoModes.size()) + return 0; + + return VideoModes[modeNumber].depth; +} + + +//! Returns current desktop screen resolution. +core::dimension2d CVideoModeList::getDesktopResolution() const +{ + return Desktop.size; +} + + +//! Returns the pixel depth of a video mode in bits. +s32 CVideoModeList::getDesktopDepth() const +{ + return Desktop.depth; +} + + + +//! adds a new mode to the list +void CVideoModeList::addMode(const core::dimension2d& size, s32 depth) +{ + SVideoMode m; + m.depth = depth; + m.size = size; + + for (u32 i=0; i getVideoModeResolution(s32 modeNumber) const; + + //! Returns the pixel depth of a video mode in bits. + virtual s32 getVideoModeDepth(s32 modeNumber) const; + + //! Returns current desktop screen resolution. + virtual core::dimension2d getDesktopResolution() const; + + //! Returns the pixel depth of a video mode in bits. + virtual s32 getDesktopDepth() const; + + //! adds a new mode to the list + void addMode(const core::dimension2d& size, s32 depth); + + void setDesktop(s32 desktopDepth, const core::dimension2d& desktopSize); + + private: + + struct SVideoMode + { + core::dimension2d size; + s32 depth; + + bool operator==(const SVideoMode& other) const + { + return size == other.size && depth == other.depth; + } + + bool operator <(const SVideoMode& other) const + { + return (size.Width < other.size.Width || + (size.Width == other.size.Width && + size.Height < other.size.Height) || + (size.Width == other.size.Width && + size.Height == other.size.Height && + depth < other.depth)); + } + }; + + core::array VideoModes; + SVideoMode Desktop; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/CWaterSurfaceSceneNode.cpp b/src/dep/src/irrlicht/CWaterSurfaceSceneNode.cpp new file mode 100644 index 0000000..443dbe5 --- /dev/null +++ b/src/dep/src/irrlicht/CWaterSurfaceSceneNode.cpp @@ -0,0 +1,171 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CWaterSurfaceSceneNode.h" +#include "ISceneManager.h" +#include "IMeshManipulator.h" +#include "IMeshCache.h" +#include "S3DVertex.h" +#include "SMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CWaterSurfaceSceneNode::CWaterSurfaceSceneNode(f32 waveHeight, f32 waveSpeed, f32 waveLength, + IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) +: CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale), WaveLength(waveLength), + WaveSpeed(waveSpeed), WaveHeight(waveHeight), OriginalMesh(0) +{ + #ifdef _DEBUG + setDebugName("CWaterSurfaceSceneNode"); + #endif + + // create copy of the mesh + if (!mesh) + return; + + // Mesh is set in CMeshSceneNode constructor, now it is moved to OriginalMesh + IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(mesh); + OriginalMesh = Mesh; + Mesh = clone; +} + + + +//! destructor +CWaterSurfaceSceneNode::~CWaterSurfaceSceneNode() +{ + // Mesh is dropped in CMeshSceneNode destructor + if (OriginalMesh) + OriginalMesh->drop(); +} + + + +//! frame +void CWaterSurfaceSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this); + + animateWaterSurface(); + + CMeshSceneNode::OnRegisterSceneNode(); + } +} + + + +void CWaterSurfaceSceneNode::animateWaterSurface() +{ + if (!Mesh) + return; + + u32 meshBufferCount = Mesh->getMeshBufferCount(); + f32 time = os::Timer::getTime() / WaveSpeed; + + for (u32 b=0; bgetMeshBuffer(b)->getVertexCount(); + + switch(Mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = + (video::S3DVertex*)Mesh->getMeshBuffer(b)->getVertices(); + + video::S3DVertex* v2 = + (video::S3DVertex*)OriginalMesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; igetMeshBuffer(b)->getVertices(); + + video::S3DVertex2TCoords* v2 = + (video::S3DVertex2TCoords*)OriginalMesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; igetMeshBuffer(b)->getVertices(); + + video::S3DVertexTangents* v2 = + (video::S3DVertexTangents*)OriginalMesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; igetMeshManipulator()->recalculateNormals(Mesh); +} + + + +//! Writes attributes of the scene node. +void CWaterSurfaceSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addFloat("WaveLength", WaveLength); + out->addFloat("WaveSpeed", WaveSpeed); + out->addFloat("WaveHeight", WaveHeight); + + CMeshSceneNode::serializeAttributes(out, options); + // serialize original mesh + out->setAttribute("Mesh", SceneManager->getMeshCache()->getMeshFilename(OriginalMesh)); +} + + +//! Reads attributes of the scene node. +void CWaterSurfaceSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + WaveLength = in->getAttributeAsFloat("WaveLength"); + WaveSpeed = in->getAttributeAsFloat("WaveSpeed"); + WaveHeight = in->getAttributeAsFloat("WaveHeight"); + + if (Mesh) + { + Mesh->drop(); + Mesh = OriginalMesh; + OriginalMesh = 0; + } + // deserialize original mesh + CMeshSceneNode::deserializeAttributes(in, options); + + if (Mesh) + { + IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(Mesh); + OriginalMesh = Mesh; + Mesh = clone; + } +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CWaterSurfaceSceneNode.h b/src/dep/src/irrlicht/CWaterSurfaceSceneNode.h new file mode 100644 index 0000000..c880f76 --- /dev/null +++ b/src/dep/src/irrlicht/CWaterSurfaceSceneNode.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_WATER_SURFACE_SCENE_NODE_H_INCLUDED__ +#define __C_WATER_SURFACE_SCENE_NODE_H_INCLUDED__ + +#include "CMeshSceneNode.h" + +namespace irr +{ +namespace scene +{ + + // TODO: It seems that we have to overwrite setMesh as it should replace + // OriginalMesh + class CWaterSurfaceSceneNode : public CMeshSceneNode + { + public: + + //! constructor + CWaterSurfaceSceneNode(f32 waveHeight, f32 waveSpeed, f32 waveLength, + IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CWaterSurfaceSceneNode(); + + //! frame + virtual void OnRegisterSceneNode(); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_WATER_SURFACE; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void animateWaterSurface(); + void addWave(core::vector3df& dest, const core::vector3df source, f32 time) + { + dest.Y = source.Y + + (sinf(((source.X/WaveLength) + time)) * WaveHeight) + + (cosf(((source.Z/WaveLength) + time)) * WaveHeight); + } + + f32 WaveLength; + f32 WaveSpeed; + f32 WaveHeight; + IMesh* OriginalMesh; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CWriteFile.cpp b/src/dep/src/irrlicht/CWriteFile.cpp new file mode 100644 index 0000000..c3e9ae3 --- /dev/null +++ b/src/dep/src/irrlicht/CWriteFile.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CWriteFile.h" +#include + +namespace irr +{ +namespace io +{ + + +CWriteFile::CWriteFile(const c8* fileName, bool append) +: FileSize(0) +{ + #ifdef _DEBUG + setDebugName("CWriteFile"); + #endif + + Filename = fileName; + openFile(append); +} + + + +CWriteFile::~CWriteFile() +{ + if (File) + fclose(File); +} + + + +//! returns if file is open +inline bool CWriteFile::isOpen() const +{ + return File != 0; +} + + + +//! returns how much was read +s32 CWriteFile::write(const void* buffer, u32 sizeToWrite) +{ + if (!isOpen()) + return 0; + + return fwrite(buffer, 1, sizeToWrite, File); +} + + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CWriteFile::seek(long finalPos, bool relativeMovement) +{ + if (!isOpen()) + return false; + + return fseek(File, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET) == 0; +} + + + +//! returns where in the file we are. +long CWriteFile::getPos() const +{ + return ftell(File); +} + + + +//! opens the file +void CWriteFile::openFile(bool append) +{ + if (Filename.size() == 0) + { + File = 0; + return; + } + + File = fopen(Filename.c_str(), append ? "ab" : "wb"); + + if (File) + { + // get FileSize + + fseek(File, 0, SEEK_END); + FileSize = ftell(File); + fseek(File, 0, SEEK_SET); + } +} + + + +//! returns name of file +const c8* CWriteFile::getFileName() const +{ + return Filename.c_str(); +} + + + +IWriteFile* createWriteFile(const c8* fileName, bool append) +{ + CWriteFile* file = new CWriteFile(fileName, append); + if (file->isOpen()) + return file; + + file->drop(); + return 0; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CWriteFile.h b/src/dep/src/irrlicht/CWriteFile.h new file mode 100644 index 0000000..fe64d5b --- /dev/null +++ b/src/dep/src/irrlicht/CWriteFile.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_WRITE_FILE_H_INCLUDED__ +#define __C_WRITE_FILE_H_INCLUDED__ + +#include +#include "IWriteFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for writing a real file to disk. + */ + class CWriteFile : public IWriteFile + { + public: + + CWriteFile(const wchar_t* fileName, bool append); + CWriteFile(const c8* fileName, bool append); + + virtual ~CWriteFile(); + + //! Reads an amount of bytes from the file. + virtual s32 write(const void* buffer, u32 sizeToWrite); + + //! Changes position in file, returns true if successful. + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! Returns the current position in the file. + virtual long getPos() const; + + //! Returns name of file. + virtual const c8* getFileName() const; + + //! returns if file is open + bool isOpen() const; + + private: + + //! opens the file + void openFile(bool append); + + core::stringc Filename; + FILE* File; + long FileSize; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CXMLReader.cpp b/src/dep/src/irrlicht/CXMLReader.cpp new file mode 100644 index 0000000..3dbcf73 --- /dev/null +++ b/src/dep/src/irrlicht/CXMLReader.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CXMLReaderImpl.h" +#include "CXMLReader.h" +#include "IReadFile.h" + +namespace irr +{ +namespace io +{ + //! Irrlicht implementation of the file read callback for the xml parser + class CIrrXMLFileReadCallBack : public IFileReadCallBack + { + public: + + //! construct from FILE pointer + CIrrXMLFileReadCallBack(IReadFile* file) + : ReadFile(file) + { + ReadFile->grab(); + } + + //! destructor + virtual ~CIrrXMLFileReadCallBack() + { + ReadFile->drop(); + } + + //! Reads an amount of bytes from the file. + virtual int read(void* buffer, int sizeToRead) + { + return ReadFile->read(buffer, sizeToRead); + } + + //! Returns size of file in bytes + virtual long getSize() const + { + return ReadFile->getSize(); + } + + private: + + IReadFile* ReadFile; + }; // end class CMyXMLFileReadCallBack + + + // now create an implementation for IXMLReader using irrXML. + + //! Creates an instance of a wide character xml parser. + IXMLReader* createIXMLReader(IReadFile* file) + { + if (!file) + return 0; + + return new CXMLReaderImpl(new CIrrXMLFileReadCallBack(file)); + } + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + IXMLReaderUTF8* createIXMLReaderUTF8(IReadFile* file) + { + if (!file) + return 0; + + return new CXMLReaderImpl(new CIrrXMLFileReadCallBack(file)); + } + +} // end namespace +} // end namespace diff --git a/src/dep/src/irrlicht/CXMLReader.h b/src/dep/src/irrlicht/CXMLReader.h new file mode 100644 index 0000000..67e98f8 --- /dev/null +++ b/src/dep/src/irrlicht/CXMLReader.h @@ -0,0 +1,26 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_XML_READER_H_INCLUDED__ +#define __C_XML_READER_H_INCLUDED__ + +#include "IXMLReader.h" + +namespace irr +{ +namespace io +{ + class IReadFile; + + //! creates an IXMLReader + IXMLReader* createIXMLReader(IReadFile* file); + + //! creates an IXMLReader + IXMLReaderUTF8* createIXMLReaderUTF8(IReadFile* file); + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/dep/src/irrlicht/CXMLReaderImpl.h b/src/dep/src/irrlicht/CXMLReaderImpl.h new file mode 100644 index 0000000..e51b744 --- /dev/null +++ b/src/dep/src/irrlicht/CXMLReaderImpl.h @@ -0,0 +1,797 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __ICXML_READER_IMPL_H_INCLUDED__ +#define __ICXML_READER_IMPL_H_INCLUDED__ + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" +#include "fast_atof.h" + +#ifdef _DEBUG +#define IRR_DEBUGPRINT(x) printf((x)); +#else // _DEBUG +#define IRR_DEBUGPRINT(x) +#endif // _DEBUG + + +namespace irr +{ +namespace io +{ + + +//! implementation of the IrrXMLReader +template +class CXMLReaderImpl : public IIrrXMLReader +{ +public: + + //! Constructor + CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true) + : TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE), + SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII) + { + if (!callback) + return; + + storeTargetFormat(); + + // read whole xml file + + readFile(callback); + + // clean up + + if (deleteCallBack) + delete callback; + + // create list with special characters + + createSpecialCharacterList(); + + // set pointer to text begin + P = TextBegin; + } + + + //! Destructor + virtual ~CXMLReaderImpl() + { + delete [] TextData; + } + + + //! Reads forward to the next xml node. + //! \return Returns false, if there was no further node. + virtual bool read() + { + // if not end reached, parse the node + if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0) + { + parseCurrentNode(); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const + { + return CurrentNodeType; + } + + + //! Returns attribute count of the current XML node. + virtual unsigned int getAttributeCount() const + { + return Attributes.size(); + } + + + //! Returns name of an attribute. + virtual const char_type* getAttributeName(int idx) const + { + if ((u32)idx >= Attributes.size()) + return 0; + + return Attributes[idx].Name.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(int idx) const + { + if ((unsigned int)idx >= Attributes.size()) + return 0; + + return Attributes[idx].Value.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + return attr->Value.c_str(); + } + + + //! Returns the value of an attribute + virtual const char_type* getAttributeValueSafe(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return EmptyString.c_str(); + + return attr->Value.c_str(); + } + + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(const char_type* name) const + { + return (int)getAttributeValueAsFloat(name); + } + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(int idx) const + { + return (int)getAttributeValueAsFloat(idx); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + core::stringc c = attr->Value.c_str(); + return core::fast_atof(c.c_str()); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(int idx) const + { + const char_type* attrvalue = getAttributeValue(idx); + if (!attrvalue) + return 0; + + core::stringc c = attrvalue; + return core::fast_atof(c.c_str()); + } + + + //! Returns the name of the current node. + virtual const char_type* getNodeName() const + { + return NodeName.c_str(); + } + + + //! Returns data of the current node. + virtual const char_type* getNodeData() const + { + return NodeName.c_str(); + } + + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const + { + return IsEmptyElement; + } + + //! Returns format of the source xml file. + virtual ETEXT_FORMAT getSourceFormat() const + { + return SourceFormat; + } + + //! Returns format of the strings returned by the parser. + virtual ETEXT_FORMAT getParserFormat() const + { + return TargetFormat; + } + +private: + + // Reads the current xml node + void parseCurrentNode() + { + char_type* start = P; + + // more forward until '<' found + while(*P != L'<' && *P) + ++P; + + if (!*P) + return; + + if (P - start > 0) + { + // we found some text, store it + if (setText(start, P)) + return; + } + + ++P; + + // based on current token, parse and report next element + switch(*P) + { + case L'/': + parseClosingXMLElement(); + break; + case L'?': + ignoreDefinition(); + break; + case L'!': + if (!parseCDATA()) + parseComment(); + break; + default: + parseOpeningXMLElement(); + break; + } + } + + + //! sets the state that text was found. Returns true if set should be set + bool setText(char_type* start, char_type* end) + { + // check if text is more than 2 characters, and if not, check if there is + // only white space, so that this text won't be reported + if (end - start < 3) + { + char_type* p = start; + for(; p != end; ++p) + if (!isWhiteSpace(*p)) + break; + + if (p == end) + return false; + } + + // set current text to the parsed text, and replace xml special characters + core::string s(start, (int)(end - start)); + NodeName = replaceSpecialCharacters(s); + + // current XML node type is text + CurrentNodeType = EXN_TEXT; + + return true; + } + + + + //! ignores an xml definition like + void ignoreDefinition() + { + CurrentNodeType = EXN_UNKNOWN; + + // move until end marked with '>' reached + while(*P != L'>') + ++P; + + ++P; + } + + + //! parses a comment + void parseComment() + { + CurrentNodeType = EXN_COMMENT; + P += 1; + + char_type *pCommentBegin = P; + + int count = 1; + + // move until end of comment reached + while(count) + { + if (*P == L'>') + --count; + else + if (*P == L'<') + ++count; + + ++P; + } + + P -= 3; + NodeName = core::string(pCommentBegin+2, (int)(P - pCommentBegin-2)); + P += 3; + } + + + //! parses an opening xml element and reads attributes + void parseOpeningXMLElement() + { + CurrentNodeType = EXN_ELEMENT; + IsEmptyElement = false; + Attributes.clear(); + + // find name + const char_type* startName = P; + + // find end of element + while(*P != L'>' && !isWhiteSpace(*P)) + ++P; + + const char_type* endName = P; + + // find Attributes + while(*P != L'>') + { + if (isWhiteSpace(*P)) + ++P; + else + { + if (*P != L'/') + { + // we've got an attribute + + // read the attribute names + const char_type* attributeNameBegin = P; + + while(!isWhiteSpace(*P) && *P != L'=') + ++P; + + const char_type* attributeNameEnd = P; + ++P; + + // read the attribute value + // check for quotes and single quotes, thx to murphy + while( (*P != L'\"') && (*P != L'\'') && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type attributeQuoteChar = *P; + + ++P; + const char_type* attributeValueBegin = P; + + while(*P != attributeQuoteChar && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type* attributeValueEnd = P; + ++P; + + SAttribute attr; + attr.Name = core::string(attributeNameBegin, + (int)(attributeNameEnd - attributeNameBegin)); + + core::string s(attributeValueBegin, + (int)(attributeValueEnd - attributeValueBegin)); + + attr.Value = replaceSpecialCharacters(s); + Attributes.push_back(attr); + } + else + { + // tag is closed directly + ++P; + IsEmptyElement = true; + break; + } + } + } + + // check if this tag is closing directly + if (endName > startName && *(endName-1) == L'/') + { + // directly closing tag + IsEmptyElement = true; + endName--; + } + + NodeName = core::string(startName, (int)(endName - startName)); + + ++P; + } + + + //! parses an closing xml tag + void parseClosingXMLElement() + { + CurrentNodeType = EXN_ELEMENT_END; + IsEmptyElement = false; + Attributes.clear(); + + ++P; + const char_type* pBeginClose = P; + + while(*P != L'>') + ++P; + + NodeName = core::string(pBeginClose, (int)(P - pBeginClose)); + ++P; + } + + //! parses a possible CDATA section, returns false if begin was not a CDATA section + bool parseCDATA() + { + if (*(P+1) != L'[') + return false; + + CurrentNodeType = EXN_CDATA; + + // skip '' && + (*(P-1) == L']') && + (*(P-2) == L']')) + { + cDataEnd = P - 2; + } + + ++P; + } + + if ( cDataEnd ) + NodeName = core::string(cDataBegin, (int)(cDataEnd - cDataBegin)); + else + NodeName = ""; + + return true; + } + + + // structure for storing attribute-name pairs + struct SAttribute + { + core::string Name; + core::string Value; + }; + + // finds a current attribute by name, returns 0 if not found + const SAttribute* getAttributeByName(const char_type* name) const + { + if (!name) + return 0; + + core::string n = name; + + for (int i=0; i<(int)Attributes.size(); ++i) + if (Attributes[i].Name == n) + return &Attributes[i]; + + return 0; + } + + // replaces xml special characters in a string and creates a new one + core::string replaceSpecialCharacters( + core::string& origstr) + { + int pos = origstr.findFirst(L'&'); + int oldPos = 0; + + if (pos == -1) + return origstr; + + core::string newstr; + + while(pos != -1 && pos < (int)origstr.size()-2) + { + // check if it is one of the special characters + + int specialChar = -1; + for (int i=0; i<(int)SpecialCharacters.size(); ++i) + { + const char_type* p = &origstr.c_str()[pos]+1; + + if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1)) + { + specialChar = i; + break; + } + } + + if (specialChar != -1) + { + newstr.append(origstr.subString(oldPos, pos - oldPos)); + newstr.append(SpecialCharacters[specialChar][0]); + pos += SpecialCharacters[specialChar].size(); + } + else + { + newstr.append(origstr.subString(oldPos, pos - oldPos + 1)); + pos += 1; + } + + // find next & + oldPos = pos; + pos = origstr.findNext(L'&', pos); + } + + if (oldPos < (int)origstr.size()-1) + newstr.append(origstr.subString(oldPos, origstr.size()-oldPos)); + + return newstr; + } + + + + //! reads the xml file and converts it into the wanted character format. + bool readFile(IFileReadCallBack* callback) + { + int size = callback->getSize(); + size += 4; // We need two terminating 0's at the end. + // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4. + + char* data8 = new char[size]; + + if (!callback->read(data8, size-4)) + { + delete [] data8; + return false; + } + + // add zeros at end + + data8[size-1] = 0; + data8[size-2] = 0; + data8[size-3] = 0; + data8[size-4] = 0; + + char16* data16 = reinterpret_cast(data8); + char32* data32 = reinterpret_cast(data8); + + // now we need to convert the data to the desired target format + // based on the byte order mark. + + const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF; + const int UTF16_BE = 0xFFFE; + const int UTF16_LE = 0xFEFF; + const int UTF32_BE = 0xFFFE0000; + const int UTF32_LE = 0x0000FEFF; + + // check source for all utf versions and convert to target data format + + if (size >= 4 && data32[0] == (char32)UTF32_BE) + { + // UTF-32, big endian + SourceFormat = ETF_UTF32_BE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 4 && data32[0] == (char32)UTF32_LE) + { + // UTF-32, little endian + SourceFormat = ETF_UTF32_LE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_BE) + { + // UTF-16, big endian + SourceFormat = ETF_UTF16_BE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_LE) + { + // UTF-16, little endian + SourceFormat = ETF_UTF16_LE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2]) + { + // UTF-8 + SourceFormat = ETF_UTF8; + convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header + } + else + { + // ASCII + SourceFormat = ETF_ASCII; + convertTextData(data8, data8, size); + } + + return true; + } + + + //! converts the text file into the desired format. + //! \param source: begin of the text (without byte order mark) + //! \param pointerToStore: pointer to text data block which can be + //! stored or deleted based on the nesessary conversion. + //! \param sizeWithoutHeader: Text size in characters without header + template + void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader) + { + // convert little to big endian if necessary + if (sizeof(src_char_type) > 1 && + isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat)) + convertToLittleEndian(source); + + // check if conversion is necessary: + if (sizeof(src_char_type) == sizeof(char_type)) + { + // no need to convert + TextBegin = (char_type*)source; + TextData = (char_type*)pointerToStore; + TextSize = sizeWithoutHeader; + } + else + { + // convert source into target data format. + // TODO: implement a real conversion. This one just + // copies bytes. This is a problem when there are + // unicode symbols using more than one character. + + TextData = new char_type[sizeWithoutHeader]; + + for (int i=0; i + void convertToLittleEndian(src_char_type* t) + { + if (sizeof(src_char_type) == 4) + { + // 32 bit + + while(*t) + { + *t = ((*t & 0xff000000) >> 24) | + ((*t & 0x00ff0000) >> 8) | + ((*t & 0x0000ff00) << 8) | + ((*t & 0x000000ff) << 24); + ++t; + } + } + else + { + // 16 bit + + while(*t) + { + *t = (*t >> 8) | (*t << 8); + ++t; + } + } + } + + //! returns if a format is little endian + inline bool isLittleEndian(ETEXT_FORMAT f) + { + return f == ETF_ASCII || + f == ETF_UTF8 || + f == ETF_UTF16_LE || + f == ETF_UTF32_LE; + } + + + //! returns true if a character is whitespace + inline bool isWhiteSpace(char_type c) + { + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); + } + + + //! generates a list with xml special characters + void createSpecialCharacterList() + { + // list of strings containing special symbols, + // the first character is the special character, + // the following is the symbol string without trailing &. + + SpecialCharacters.push_back("&"); + SpecialCharacters.push_back("gt;"); + SpecialCharacters.push_back("\"quot;"); + SpecialCharacters.push_back("'apos;"); + + } + + + //! compares the first n characters of the strings + bool equalsn(const char_type* str1, const char_type* str2, int len) + { + int i; + for(i=0; str1[i] && str2[i] && i < len; ++i) + if (str1[i] != str2[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (str1[i] == 0 && str2[i] == 0); + } + + + //! stores the target text format + void storeTargetFormat() + { + // get target format. We could have done this using template specialization, + // but VisualStudio 6 don't like it and we want to support it. + + switch(sizeof(char_type)) + { + case 1: + TargetFormat = ETF_UTF8; + break; + case 2: + TargetFormat = ETF_UTF16_LE; + break; + case 4: + TargetFormat = ETF_UTF32_LE; + break; + default: + TargetFormat = ETF_ASCII; // should never happen. + } + } + + + // instance variables: + + char_type* TextData; // data block of the text file + char_type* P; // current point in text to parse + char_type* TextBegin; // start of text to parse + unsigned int TextSize; // size of text to parse in characters, not bytes + + EXML_NODE CurrentNodeType; // type of the currently parsed node + ETEXT_FORMAT SourceFormat; // source format of the xml file + ETEXT_FORMAT TargetFormat; // output format of this parser + + core::string NodeName; // name of the node currently in + core::string EmptyString; // empty string to be returned by getSafe() methods + + bool IsEmptyElement; // is the currently parsed node empty? + + core::array< core::string > SpecialCharacters; // see createSpecialCharacterList() + + core::array Attributes; // attributes of current element + +}; // end CXMLReaderImpl + + +} // end namespace +} // end namespace + +#endif diff --git a/src/dep/src/irrlicht/CXMLWriter.cpp b/src/dep/src/irrlicht/CXMLWriter.cpp new file mode 100644 index 0000000..06b0b79 --- /dev/null +++ b/src/dep/src/irrlicht/CXMLWriter.cpp @@ -0,0 +1,249 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CXMLWriter.h" +#include +#include "irrString.h" +#include "IrrCompileConfig.h" + +namespace irr +{ +namespace io +{ + + +//! Constructor +CXMLWriter::CXMLWriter(IWriteFile* file) +: File(file), Tabs(0), TextWrittenLast(false) +{ + if (File) + File->grab(); +} + + + +//! Destructor +CXMLWriter::~CXMLWriter() +{ + if (File) + File->drop(); +} + + + +//! Writes a xml 1.0 header like +void CXMLWriter::writeXMLHeader() +{ + if (!File) + return; + + if (sizeof(wchar_t)==2) + { + const u16 h = 0xFEFF; + File->write(&h, 2); + } + else + { + const u32 h = 0x0000FEFF; + File->write(&h, sizeof(wchar_t)); + } + + const wchar_t* const p = L""; + File->write(p, wcslen(p)*sizeof(wchar_t)); + + writeLineBreak(); + TextWrittenLast = false; +} + + + +//! Writes an xml element with maximal 5 attributes +void CXMLWriter::writeElement(const wchar_t* name, bool empty, + const wchar_t* attr1Name, const wchar_t* attr1Value, + const wchar_t* attr2Name, const wchar_t* attr2Value, + const wchar_t* attr3Name, const wchar_t* attr3Value, + const wchar_t* attr4Name, const wchar_t* attr4Value, + const wchar_t* attr5Name, const wchar_t* attr5Value) +{ + if (!File || !name) + return; + + if (Tabs > 0) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + // write name + + File->write(L"<", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + + // write attributes + + writeAttribute(attr1Name, attr1Value); + writeAttribute(attr2Name, attr2Value); + writeAttribute(attr3Name, attr3Value); + writeAttribute(attr4Name, attr4Value); + writeAttribute(attr5Name, attr5Value); + + // write closing tag + if (empty) + File->write(L" />", 3*sizeof(wchar_t)); + else + { + File->write(L">", sizeof(wchar_t)); + ++Tabs; + } + + TextWrittenLast = false; +} + +//! Writes an xml element with any number of attributes +void CXMLWriter::writeElement(const wchar_t* name, bool empty, + core::array &names, + core::array &values) +{ + if (!File || !name) + return; + + if (Tabs > 0) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + // write name + + File->write(L"<", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + + // write attributes + u32 i=0; + for (; i < names.size() && i < values.size(); ++i) + writeAttribute(names[i].c_str(), values[i].c_str()); + + // write closing tag + if (empty) + File->write(L" />", 3*sizeof(wchar_t)); + else + { + File->write(L">", sizeof(wchar_t)); + ++Tabs; + } + + TextWrittenLast = false; +} + + +void CXMLWriter::writeAttribute(const wchar_t* name, const wchar_t* value) +{ + if (!name || !value) + return; + + File->write(L" ", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + File->write(L"=\"", 2*sizeof(wchar_t)); + writeText(value); + File->write(L"\"", sizeof(wchar_t)); +} + + +//! Writes a comment into the xml file +void CXMLWriter::writeComment(const wchar_t* comment) +{ + if (!File || !comment) + return; + + File->write(L"", 3*sizeof(wchar_t)); +} + + +//! Writes the closing tag for an element. Like +void CXMLWriter::writeClosingTag(const wchar_t* name) +{ + if (!File || !name) + return; + + --Tabs; + + if (Tabs > 0 && !TextWrittenLast) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + File->write(L"write(name, wcslen(name)*sizeof(wchar_t)); + File->write(L">", sizeof(wchar_t)); + TextWrittenLast = false; +} + + + +const CXMLWriter::XMLSpecialCharacters XMLWSChar[] = +{ + { L'&', L"&" }, + { L'<', L"<" }, + { L'>', L">" }, + { L'"', L""" }, + { L'\0', 0 } +}; + + +//! Writes a text into the file. All occurrences of special characters like +//! & (&), < (<), > (>), and " (") are automaticly replaced. +void CXMLWriter::writeText(const wchar_t* text) +{ + if (!File || !text) + return; + + core::stringw s; + const wchar_t* p = text; + + while(*p) + { + // check if it is matching + bool found = false; + for (s32 i=0; XMLWSChar[i].Character != '\0'; ++i) + if (*p == XMLWSChar[i].Character) + { + s.append(XMLWSChar[i].Symbol); + found = true; + break; + } + + if (!found) + s.append(*p); + ++p; + } + + // write new string + File->write(s.c_str(), s.size()*sizeof(wchar_t)); + TextWrittenLast = true; +} + + +//! Writes a line break +void CXMLWriter::writeLineBreak() +{ + if (!File) + return; + +#if defined(MACOSX) + File->write(L"\r", sizeof(wchar_t)); +#elif defined(_IRR_WINDOWS_API_) + File->write(L"\r\n", 2*sizeof(wchar_t)); +#else + File->write(L"\n", sizeof(wchar_t)); +#endif + +} + + +} // end namespace irr +} // end namespace io + diff --git a/src/dep/src/irrlicht/CXMLWriter.h b/src/dep/src/irrlicht/CXMLWriter.h new file mode 100644 index 0000000..723fc81 --- /dev/null +++ b/src/dep/src/irrlicht/CXMLWriter.h @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_XML_WRITER_H_INCLUDED__ +#define __C_XML_WRITER_H_INCLUDED__ + +#include +#include "IXMLWriter.h" +#include "IWriteFile.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing methods for making it easier to write XML files. + class CXMLWriter : public IXMLWriter + { + public: + + //! Constructor + CXMLWriter(IWriteFile* file); + + //! Destructor + virtual ~CXMLWriter(); + + //! Writes a xml 1.0 header like + virtual void writeXMLHeader(); + + //! Writes an xml element with maximal 5 attributes + virtual void writeElement(const wchar_t* name, bool empty=false, + const wchar_t* attr1Name = 0, const wchar_t* attr1Value = 0, + const wchar_t* attr2Name = 0, const wchar_t* attr2Value = 0, + const wchar_t* attr3Name = 0, const wchar_t* attr3Value = 0, + const wchar_t* attr4Name = 0, const wchar_t* attr4Value = 0, + const wchar_t* attr5Name = 0, const wchar_t* attr5Value = 0); + + //! Writes an xml element with any number of attributes + virtual void writeElement(const wchar_t* name, bool empty, + core::array &names, core::array &values); + + //! Writes a comment into the xml file + virtual void writeComment(const wchar_t* comment); + + //! Writes the closing tag for an element. Like
+ virtual void writeClosingTag(const wchar_t* name); + + //! Writes a text into the file. All occurrences of special characters like + //! & (&), < (<), > (>), and " (") are automaticly replaced. + virtual void writeText(const wchar_t* text); + + //! Writes a line break + virtual void writeLineBreak(); + + struct XMLSpecialCharacters + { + wchar_t Character; + const wchar_t* Symbol; + }; + + private: + + void writeAttribute(const wchar_t* att, const wchar_t* name); + + IWriteFile* File; + s32 Tabs; + + bool TextWrittenLast; + }; + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/dep/src/irrlicht/CXMeshFileLoader.cpp b/src/dep/src/irrlicht/CXMeshFileLoader.cpp new file mode 100644 index 0000000..c7c2582 --- /dev/null +++ b/src/dep/src/irrlicht/CXMeshFileLoader.cpp @@ -0,0 +1,2132 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_X_LOADER_ + +#include "CXMeshFileLoader.h" +#include "os.h" + +#include "fast_atof.h" +#include "coreutil.h" +#include "IVideoDriver.h" +#include "IReadFile.h" + +#ifdef _DEBUG +#define _XREADER_DEBUG +#endif +//#define BETTER_MESHBUFFER_SPLITTING_FOR_X + +namespace irr +{ +namespace scene +{ + +//! Constructor +CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr) +: SceneManager(smgr), AnimatedMesh(0), MajorVersion(0), MinorVersion(0), + BinaryFormat(false), BinaryNumCount(0), Buffer(0), P(0), End(0), + FloatSize(0), CurFrame(0) +{ +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CXMeshFileLoader::isALoadableFileExtension(const c8* filename) const +{ + return strstr(filename, ".x") != 0; +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* f) +{ + if (!f) + return 0; + + u32 time = os::Timer::getRealTime(); + + AnimatedMesh = new CSkinnedMesh(); + + if ( load(f) ) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } +#ifdef _XREADER_DEBUG + time = os::Timer::getRealTime() - time; + core::stringc tmpString = "Time to load "; + tmpString += BinaryFormat ? "binary" : "ascii"; + tmpString += " X file: "; + tmpString += time; + tmpString += "ms"; + os::Printer::log(tmpString.c_str()); +#endif + //Clear up + + MajorVersion=0; + MinorVersion=0; + BinaryFormat=0; + BinaryNumCount=0; + FloatSize=0; + P=0; + End=0; + CurFrame=0; + TemplateMaterials.clear(); + + delete [] Buffer; + Buffer = 0; + + for (u32 i=0; iMaterials.size()) + mesh->Materials.push_back(video::SMaterial()); + + u32 i; + + mesh->Buffers.reallocate(mesh->Materials.size()); + const u32 bufferOffset = AnimatedMesh->getMeshBufferCount(); + for (i=0; iMaterials.size(); ++i) + { + mesh->Buffers.push_back( AnimatedMesh->createBuffer() ); + mesh->Buffers.getLast()->Material = mesh->Materials[i]; + + if (!mesh->HasSkinning) + { + //Set up rigid animation + if (mesh->AttachedJointID!=-1) + { + AnimatedMesh->getAllJoints()[mesh->AttachedJointID]->AttachedMeshes.push_back( AnimatedMesh->getMeshBuffers().size()-1 ); + } + } + + } + + if (!mesh->HasVertexColors) + { + for (u32 j=0;jFaceMaterialIndices.size();++j) + { + for (u32 id=j*3+0;id<=j*3+2;++id) + { + mesh->Vertices[ mesh->Indices[id] ].Color = mesh->Buffers[mesh->FaceMaterialIndices[j]]->Material.DiffuseColor; + } + } + } + + #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X + { + //the same vertex can be used in many different meshbuffers, but it's slow to work out + + core::array< core::array< u32 > > verticesLinkIndex; + verticesLinkIndex.reallocate(mesh->Vertices.size()); + core::array< core::array< u16 > > verticesLinkBuffer; + verticesLinkBuffer.reallocate(mesh->Vertices.size()); + + for (i=0;iVertices.size();++i) + { + verticesLinkIndex.push_back( core::array< u32 >() ); + verticesLinkBuffer.push_back( core::array< u16 >() ); + } + + for (i=0;iFaceMaterialIndices.size();++i) + { + for (u32 id=i*3+0;id<=i*3+2;++id) + { + core::array< u32 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; + bool found=false; + + for (u32 j=0; j < Array.size(); ++j) + { + if (Array[j]==mesh->FaceMaterialIndices[i]) + { + found=true; + break; + } + } + + if (!found) + Array.push_back( mesh->FaceMaterialIndices[i] ); + } + } + + for (i=0;iVertices.size();++i) + { + core::array< u16 > &Array = verticesLinkBuffer[i]; + verticesLinkIndex[i].reallocate(Array.size()); + for (u32 j=0; j < Array.size(); ++j) + { + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ]; + verticesLinkIndex[i].push_back( buffer->Vertices_Standard.size() ); + buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); + } + } + + for (i=0;iFaceMaterialIndices.size();++i) + { + scene::SSkinMeshBuffer *buffer=mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; + + for (u32 id=i*3+0;id<=i*3+2;++id) + { + core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; + + for (u32 j=0;j< Array.size() ;++j) + { + if ( Array[j]== mesh->FaceMaterialIndices[i] ) + buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ][j] ); + } + } + } + + for (u32 j=0;jWeights.size();++j) + { + ISkinnedMesh::SWeight& Weight = (*mesh->Weights[j]); + + u32 id = Weight.vertex_id; + + if (id>=verticesLinkIndex.size()) + { + os::Printer::log("X loader: Weight id out of range", ELL_WARNING); + id=0; + } + + if (verticesLinkBuffer[id].size()==1) + { + Weight.vertex_id=verticesLinkIndex[id][0]; + Weight.buffer_id=verticesLinkBuffer[id][0]; + } + else if (verticesLinkBuffer[id].size() != 0) + { + for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k) + { + ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->createWeight(Joint); + WeightClone->strength = Weight.strength; + WeightClone->vertex_id = verticesLinkIndex[id][k]; + WeightClone->buffer_id = verticesLinkBuffer[id][k]; + } + } + } + } + #else + { + core::array< u32 > verticesLinkIndex; + core::array< u16 > verticesLinkBuffer; + verticesLinkBuffer.set_used(mesh->Vertices.size()); + verticesLinkIndex.set_used(mesh->Vertices.size()); + + // init with 0 + for (i=0;iVertices.size();++i) + { + verticesLinkBuffer[i]=0; + verticesLinkIndex[i]=0; + } + + // store meshbuffer number per vertex + for (i=0;iFaceMaterialIndices.size();++i) + { + for (u32 id=i*3+0;id<=i*3+2;++id) + { + verticesLinkBuffer[ mesh->Indices[id] ] = mesh->FaceMaterialIndices[i]; + } + } + + // store vertices in buffers and remember relation in verticesLinkIndex + u32* vCountArray = new u32[mesh->Buffers.size()]; + memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); + // count vertices in each buffer and reallocate + for (i=0;iVertices.size();++i) + ++vCountArray[verticesLinkBuffer[i]]; + for (i=0; i!=mesh->Buffers.size(); ++i) + mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]); + + // actually store vertices + for (i=0;iVertices.size();++i) + { + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ]; + + verticesLinkIndex[i] = buffer->Vertices_Standard.size(); + buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); + } + + // count indices per buffer and reallocate + memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); + for (i=0;iFaceMaterialIndices.size();++i) + ++vCountArray[ mesh->FaceMaterialIndices[i] ]; + for (i=0; i!=mesh->Buffers.size(); ++i) + mesh->Buffers[i]->Indices.reallocate(vCountArray[i]); + delete [] vCountArray; + // create indices per buffer + for (i=0;iFaceMaterialIndices.size();++i) + { + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; + for (u32 id=i*3+0;id!=i*3+3;++id) + buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ] ); + } + + + for (u32 j=0;jWeights.size();++j) + { + ISkinnedMesh::SWeight* weight = mesh->Weights[j]; + + u32 id = weight->vertex_id; + + if (id>=verticesLinkIndex.size()) + { + os::Printer::log("X loader: Weight id out of range", ELL_WARNING); + id=0; + } + + weight->vertex_id=verticesLinkIndex[id]; + weight->buffer_id=verticesLinkBuffer[id] + bufferOffset;; + } + } + #endif + + } + + return true; +} + + +//! Reads file into memory +bool CXMeshFileLoader::readFileIntoMemory(io::IReadFile* file) +{ + const long size = file->getSize(); + if (size < 12) + { + os::Printer::log("X File is too small.", ELL_WARNING); + return false; + } + + Buffer = new c8[size]; + + //! read all into memory + if (file->read(Buffer, size) != size) + { + os::Printer::log("Could not read from x file.", ELL_WARNING); + return false; + } + + End = Buffer + size; + + //! check header "xof " + if (strncmp(Buffer, "xof ", 4)!=0) + { + os::Printer::log("Not an x file, wrong header.", ELL_WARNING); + return false; + } + + //! read minor and major version, e.g. 0302 or 0303 + c8 tmp[3]; + tmp[2] = 0x0; + tmp[0] = Buffer[4]; + tmp[1] = Buffer[5]; + MajorVersion = core::strtol10(tmp); + + tmp[0] = Buffer[6]; + tmp[1] = Buffer[7]; + MinorVersion = core::strtol10(tmp); + + //! read format + if (strncmp(&Buffer[8], "txt ", 4) ==0) + BinaryFormat = false; + else if (strncmp(&Buffer[8], "bin ", 4) ==0) + BinaryFormat = true; + else + { + os::Printer::log("Only uncompressed x files currently supported.", ELL_WARNING); + return false; + } + BinaryNumCount=0; + + //! read float size + if (strncmp(&Buffer[12], "0032", 4) ==0) + FloatSize = 4; + else if (strncmp(&Buffer[12], "0064", 4) ==0) + FloatSize = 8; + else + { + os::Printer::log("Float size not supported.", ELL_WARNING); + return false; + } + + P = &Buffer[16]; + + readUntilEndOfLine(); + FilePath = stripPathFromString(file->getFileName(),true); + + return true; +} + + +//! Parses the file +bool CXMeshFileLoader::parseFile() +{ + while(parseDataObject()) + { + // loop + } + + return true; +} + + +//! Parses the next Data object in the file +bool CXMeshFileLoader::parseDataObject() +{ + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + return false; + + // parse specific object +#ifdef _XREADER_DEBUG + os::Printer::log("debug DataObject:", objectName.c_str() ); +#endif + + if (objectName == "template") + return parseDataObjectTemplate(); + else + if (objectName == "Frame") + { + return parseDataObjectFrame( 0 ); + } + else + if (objectName == "Mesh") + { + // some meshes have no frames at all + //CurFrame = AnimatedMesh->createJoint(0); + + //CurFrame->Meshes.push_back(SXMesh()); + //return parseDataObjectMesh(CurFrame->Meshes.getLast()); + + SXMesh *mesh=new SXMesh; + + //mesh->Buffer=AnimatedMesh->createBuffer(); + Meshes.push_back(mesh); + + return parseDataObjectMesh ( *mesh ); + } + else + if (objectName == "AnimationSet") + { + return parseDataObjectAnimationSet(); + } + else + if (objectName == "Material") + { + // template materials now available thanks to joeWright + TemplateMaterials.push_back(SXTemplateMaterial()); + TemplateMaterials.getLast().Name = getNextToken(); + return parseDataObjectMaterial(TemplateMaterials.getLast().Material); + } + else + if (objectName == "}") + { + os::Printer::log("} found in dataObject", ELL_WARNING); + return true; + } + + os::Printer::log("Unknown data object in animation of .x file", objectName.c_str(), ELL_WARNING); + + return parseUnknownDataObject(); +} + + +bool CXMeshFileLoader::parseDataObjectTemplate() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading template"); +#endif + + // parse a template data object. Currently not stored. + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { + os::Printer::log("Left delimiter in template data object missing.", + name.c_str(), ELL_ERROR); + return false; + } + + // read GUID + core::stringc guid = getNextToken(); + + // read and ignore data members + while(true) + { + core::stringc s = getNextToken(); + + if (s == "}") + break; + + if (s.size() == 0) + return false; + } + + return true; +} + + + +bool CXMeshFileLoader::parseDataObjectFrame( CSkinnedMesh::SJoint *Parent ) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading frame"); +#endif + + // A coordinate frame, or "frame of reference." The Frame template + // is open and can contain any object. The Direct3D extensions (D3DX) + // mesh-loading functions recognize Mesh, FrameTransformMatrix, and + // Frame template instances as child objects when loading a Frame + // instance. + + u32 JointID=0; + + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { + os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING); + return false; + } + + CSkinnedMesh::SJoint *joint=0; + + if (name.size()) + { + for (u32 n=0;n < AnimatedMesh->getAllJoints().size();++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==name) + { + joint=AnimatedMesh->getAllJoints()[n]; + JointID=n; + break; + } + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint ", name.c_str()); +#endif + joint=AnimatedMesh->createJoint(Parent); + joint->Name=name; + JointID=AnimatedMesh->getAllJoints().size()-1; + } + else + { +#ifdef _XREADER_DEBUG + os::Printer::log("using joint ", name.c_str()); +#endif + if (Parent) + Parent->Children.push_back(joint); + } + + // Now inside a frame. + // read tokens until closing brace is reached. + + while(true) + { + core::stringc objectName = getNextToken(); + +#ifdef _XREADER_DEBUG + os::Printer::log("debug DataObject in frame:", objectName.c_str() ); +#endif + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // frame finished + } + else + if (objectName == "Frame") + { + + if (!parseDataObjectFrame(joint)) + return false; + } + else + if (objectName == "FrameTransformMatrix") + { + if (!parseDataObjectTransformationMatrix(joint->LocalMatrix)) + return false; + + //joint->LocalAnimatedMatrix + //joint->LocalAnimatedMatrix.makeInverse(); + //joint->LocalMatrix=tmp*joint->LocalAnimatedMatrix; + } + else + if (objectName == "Mesh") + { + /* + frame.Meshes.push_back(SXMesh()); + if (!parseDataObjectMesh(frame.Meshes.getLast())) + return false; + */ + SXMesh *mesh=new SXMesh; + + mesh->AttachedJointID=JointID; + + Meshes.push_back(mesh); + + if (!parseDataObjectMesh(*mesh)) + return false; + } + else + { + os::Printer::log("Unknown data object in frame in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading Transformation Matrix"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Transformation Matrix found in x file", ELL_WARNING); + return false; + } + + for (u32 i=0; i<4; ++i) + for (u32 j=0; j<4; ++j) + mat(i,j)=readFloat(); + + if (!checkForTwoFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Transformation Matrix found in x file", ELL_WARNING); + return false; + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Transformation Matrix found in x file", ELL_WARNING); + return false; + } + + return true; +} + + + +bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading mesh"); +#endif + + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { + os::Printer::log("No opening brace in Mesh found in x file", ELL_WARNING); + return false; + } + + // read vertex count + const u32 nVertices = readInt(); + + // read vertices + mesh.Vertices.set_used(nVertices); //luke: change + + for (u32 n=0; n polygonfaces; + u32 currentIndex = 0; + + for (u32 k=0; kgetAllJoints().size(); ++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName) + { + joint=AnimatedMesh->getAllJoints()[n]; + break; + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint for skinning ", TransformNodeName.c_str()); +#endif + joint=AnimatedMesh->createJoint(0); + joint->Name=TransformNodeName; + } + + // read vertex weights + const u32 nWeights = readInt(); + + // read vertex indices + u32 i; + + const u32 jointStart = joint->Weights.size(); + joint->Weights.reallocate(jointStart+nWeights); + + mesh.Weights.reallocate( mesh.Weights.size() + nWeights ); + + for (i=0; icreateWeight(joint); + + weight->buffer_id=0; + weight->vertex_id=readInt(); + + mesh.Weights.push_back(weight); + } + + // read vertex weights + + for (i=0; iWeights[i].strength = readFloat(); + + // read matrix offset + + // transforms the mesh vertices to the space of the bone + // When concatenated to the bone's transform, this provides the + // world space coordinates of the mesh as affected by the bone + core::matrix4& MatrixOffset = joint->GlobalInversedMatrix; + + for (i=0; i<4; ++i) + { + for (u32 j=0; j<4; ++j) + MatrixOffset(i,j) = readFloat(); + } + + if (!checkForTwoFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING); + return false; + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Skin Weights found in x file", ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading skin mesh header"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Skin Mesh header found in .x file", ELL_WARNING); + return false; + } + + mesh.MaxSkinWeightsPerVertex = readInt(); + mesh.MaxSkinWeightsPerFace = readInt(); + mesh.BoneCount = readInt(); + + if (!BinaryFormat) + getNextToken(); // skip semicolon + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in skin mesh header in x file", ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading mesh normals"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Mesh Normals found in x file", ELL_WARNING); + return false; + } + + // read count + const u32 nNormals = readInt(); + core::array normals; + normals.set_used(nNormals); + + // read normals + for (u32 i=0; i normalIndices; + normalIndices.set_used(mesh.Indices.size()); + + // read face normal indices + const u32 nFNormals = readInt(); + + u32 normalidx = 0; + core::array polygonfaces; + for (u32 k=0; k=mesh.Vertices.size()) + { + os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING); + return false; + } + readRGBA(mesh.Vertices[Index].Color); + checkForOneFollowingSemicolons(); + } + + if (!checkForOneFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Mesh Vertex Colors Array found in x file", ELL_WARNING); + return false; + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading mesh material list"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Mesh Material List found in x file", ELL_WARNING); + return false; + } + + // read material count + mesh.Materials.reallocate(readInt()); + + // read non triangulated face material index count + const u32 nFaceIndices = readInt(); + + if (nFaceIndices != mesh.IndexCountPerFace.size()) + { + os::Printer::log("Index count per face not equal to face material index count in x file.", ELL_WARNING); + return false; + } + + // read non triangulated face indices and create triangulated ones + mesh.FaceMaterialIndices.set_used( mesh.Indices.size() / 3); + u32 triangulatedindex = 0; + for (u32 tfi=0; tfigetVideoDriver()->getTexture ( TextureFileName.c_str() ); + // mesh path + if (!material.getTexture(0)) + { + TextureFileName=FilePath + stripPathFromString(TextureFileName,false); + material.setTexture(0, SceneManager->getVideoDriver()->getTexture ( TextureFileName.c_str() )); + } + // working directory + if (!material.getTexture(0)) + SceneManager->getVideoDriver()->getTexture ( stripPathFromString(TextureFileName,false).c_str() ); + } + else + { + os::Printer::log("Unknown data object in material in .x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimationSet() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading animation set"); +#endif + + core::stringc AnimationName; + + if (!readHeadOfDataObject(&AnimationName)) + { + os::Printer::log("No opening brace in Animation Set found in x file", ELL_WARNING); + return false; + } + + while(true) + { + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Animation set in x file.", ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // animation set finished + } + else + if (objectName == "Animation") + { + if (!parseDataObjectAnimation()) + return false; + } + else + { + os::Printer::log("Unknown data object in animation set in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimation() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading animation"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Animation found in x file", ELL_WARNING); + return false; + } + + //anim.closed = true; + //anim.linearPositionQuality = true; + CSkinnedMesh::SJoint animationDump; + + core::stringc FrameName; + + while(true) + { + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // animation finished + } + else + if (objectName == "AnimationKey") + { + if (!parseDataObjectAnimationKey(&animationDump)) + return false; + } + else + if (objectName == "AnimationOptions") + { + //TODO: parse options. + if (!parseUnknownDataObject()) + return false; + } + else + if (objectName == "{") + { + // read frame name + FrameName = getNextToken(); + + if (!checkForClosingBrace()) + { + os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); + return false; + } + } + else + { + os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + if (FrameName.size() != 0) + { +#ifdef _XREADER_DEBUG + os::Printer::log("getting name: ", FrameName.c_str()); +#endif + CSkinnedMesh::SJoint *joint=0; + + u32 n; + for (n=0;n < AnimatedMesh->getAllJoints().size();++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==FrameName) + { + joint=AnimatedMesh->getAllJoints()[n]; + break; + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint for animation ", FrameName.c_str()); +#endif + joint=AnimatedMesh->createJoint(0); + joint->Name=FrameName; + } + + joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size()); + for (n=0;nposition+=joint->LocalMatrix.getTranslation(); + + joint->PositionKeys.push_back(*key); + } + + joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size()); + for (n=0;nscale*=joint->LocalMatrix.getScale(); + + joint->ScaleKeys.push_back(*key); + } + + joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size()); + for (n=0;nrotation.X, key->rotation.Y, key->rotation.Z) ); + + tmpMatrix=joint->LocalMatrix*tmpMatrix; + + //key->rotation = core::quaternion(tmpMatrix); + + joint->RotationKeys.push_back(*key); + } + } + else + os::Printer::log("joint name was never given", ELL_WARNING); + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading animation key"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Animation Key found in x file", ELL_WARNING); + return false; + } + + // read key type + + const u32 keyType = readInt(); + + if (keyType > 4) + { + os::Printer::log("Unknown key type found in Animation Key in x file", ELL_WARNING); + return false; + } + + // read number of keys + const u32 numberOfKeys = readInt(); + + // eat the semicolon after the "0". if there are keys present, readInt() + // does this for us. If there aren't, we need to do it explicitly + if (numberOfKeys == 0) + checkForOneFollowingSemicolons(); + + for (u32 i=0; icreateRotationKey(joint); + key->frame=(f32)time; + key->rotation.set(X,Y,Z,W); + } + break; + case 1: //scale + case 2: //position + { + // read vectors + + // read count + if (readInt() != 3) + { + os::Printer::log("Expected 3 numbers in animation key in x file", ELL_WARNING); + return false; + } + + core::vector3df vector; + readVector3(vector); + + if (!checkForTwoFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon after vector animation key in x file", ELL_WARNING); + return false; + } + + if (keyType==2) + { + ISkinnedMesh::SPositionKey *key=AnimatedMesh->createPositionKey(joint); + key->frame=(f32)time; + key->position=vector; + } + else + { + ISkinnedMesh::SScaleKey *key=AnimatedMesh->createScaleKey(joint); + key->frame=(f32)time; + key->scale=vector; + } + } + break; + case 3: + case 4: + { + // read matrix + + // read count + if (readInt() != 16) + { + os::Printer::log("Expected 16 numbers in animation key in x file", ELL_WARNING); + return false; + } + + // read matrix + core::matrix4 Matrix; + + for (u32 m=0; m<4; ++m) + for (u32 n=0; n<4; ++n) + Matrix(m,n) = readFloat(); + + + //Matrix=joint->LocalMatrix*Matrix; + + if (!checkForTwoFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon after matrix animation key in x file", ELL_WARNING); + return false; + } + + //core::vector3df rotation = Matrix.getRotationDegrees(); + + ISkinnedMesh::SRotationKey *keyR=AnimatedMesh->createRotationKey(joint); + keyR->frame=(f32)time; + //keyR->rotation.set(rotation.X*core::DEGTORAD,rotation.Y*core::DEGTORAD,rotation.Z*core::DEGTORAD); + keyR->rotation= core::quaternion(Matrix); + + + ISkinnedMesh::SPositionKey *keyP=AnimatedMesh->createPositionKey(joint); + keyP->frame=(f32)time; + keyP->position=Matrix.getTranslation(); + + core::vector3df scale=Matrix.getScale(); + + //if (scale.X==0) scale.X=1; + //if (scale.Y==0) scale.Y=1; + //if (scale.Z==0) scale.Z=1; +/* + ISkinnedMesh::SScaleKey *keyS=AnimatedMesh->createScaleKey(joint); + keyS->frame=(f32)time; + keyS->scale=scale; +*/ + } + break; + } // end switch + } + + checkForOneFollowingSemicolons(); + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in animation key in x file", ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectTextureFilename(core::stringc& texturename) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading texture filename"); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Texture filename found in x file", ELL_WARNING); + return false; + } + + if (!getNextTokenAsString(texturename)) + { + os::Printer::log("Unknown syntax while reading texture filename string in x file", ELL_WARNING); + return false; + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Texture filename found in x file", ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseUnknownDataObject() +{ + // find opening delimiter + while(true) + { + core::stringc t = getNextToken(); + + if (t.size() == 0) + return false; + + if (t == "{") + break; + } + + u32 counter = 1; + + // parse until closing delimiter + + while(counter) + { + core::stringc t = getNextToken(); + + if (t.size() == 0) + return false; + + if (t == "{") + ++counter; + else + if (t == "}") + --counter; + } + + return true; +} + + +//! checks for closing curly brace, returns false if not there +bool CXMeshFileLoader::checkForClosingBrace() +{ + return (getNextToken() == "}"); +} + + +//! checks for one following semicolon, returns false if not there +bool CXMeshFileLoader::checkForOneFollowingSemicolons() +{ + if (BinaryFormat) + return true; + + return (getNextToken() == ";"); +} + + +//! checks for two following semicolons, returns false if they are not there +bool CXMeshFileLoader::checkForTwoFollowingSemicolons() +{ + if (BinaryFormat) + return true; + + for (u32 k=0; k<2; ++k) + { + if (getNextToken() != ";") + return false; + } + + return true; +} + + +//! reads header of dataobject including the opening brace. +//! returns false if error happened, and writes name of object +//! if there is one +bool CXMeshFileLoader::readHeadOfDataObject(core::stringc* outname) +{ + core::stringc nameOrBrace = getNextToken(); + if (nameOrBrace != "{") + { + if (outname) + (*outname) = nameOrBrace; + + if (getNextToken() != "{") + return false; + } + + return true; +} + + +//! returns next parseable token. Returns empty string if no token there +core::stringc CXMeshFileLoader::getNextToken() +{ + core::stringc s; + + // process binary-formatted file + if (BinaryFormat) + { + // in binary mode it will only return NAME and STRING token + // and (correctly) skip over other tokens. + + s16 tok = readBinWord(); + u32 len; + + // standalone tokens + switch (tok) { + case 1: + // name token + len = readBinDWord(); + s = core::stringc(P, len); + P += len; + return s; + case 2: + // string token + len = readBinDWord(); + s = core::stringc(P, len); + P += (len + 2); + return s; + case 3: + // integer token + P += 4; + return ""; + case 5: + // GUID token + P += 16; + return ""; + case 6: + len = readBinDWord(); + P += (len * 4); + return ""; + case 7: + len = readBinDWord(); + P += (len * FloatSize); + return ""; + case 0x0a: + return "{"; + case 0x0b: + return "}"; + case 0x0c: + return "("; + case 0x0d: + return ")"; + case 0x0e: + return "["; + case 0x0f: + return "]"; + case 0x10: + return "<"; + case 0x11: + return ">"; + case 0x12: + return "."; + case 0x13: + return ","; + case 0x14: + return ";"; + case 0x1f: + return "template"; + case 0x28: + return "WORD"; + case 0x29: + return "DWORD"; + case 0x2a: + return "FLOAT"; + case 0x2b: + return "DOUBLE"; + case 0x2c: + return "CHAR"; + case 0x2d: + return "UCHAR"; + case 0x2e: + return "SWORD"; + case 0x2f: + return "SDWORD"; + case 0x30: + return "void"; + case 0x31: + return "string"; + case 0x32: + return "unicode"; + case 0x33: + return "cstring"; + case 0x34: + return "array"; + } + } + // process text-formatted file + else + { + findNextNoneWhiteSpace(); + + if (P >= End) + return s; + + while((P < End) && !core::isspace(P[0])) + { + // either keep token delimiters when already holding a token, or return if first valid char + if (P[0]==';' || P[0]=='}' || P[0]=='{' || P[0]==',') + { + if (!s.size()) + { + s.append(P[0]); + ++P; + } + break; // stop for delimiter + } + s.append(P[0]); + ++P; + } + } + return s; +} + + +//! places pointer to next begin of a token, which must be a number, +// and ignores comments +void CXMeshFileLoader::findNextNoneWhiteSpaceNumber() +{ + if (BinaryFormat) + return; + + while(true) + { + while((P < End) && (P[0] != '-') && (P[0] != '.') && + !( core::isdigit(P[0]))) + ++P; + + if (P >= End) + return; + + // check if this is a comment + if ((P[0] == '/' && P[1] == '/') || P[0] == '#') + readUntilEndOfLine(); + else + break; + } +} + + +// places pointer to next begin of a token, and ignores comments +void CXMeshFileLoader::findNextNoneWhiteSpace() +{ + if (BinaryFormat) + return; + + while(true) + { + while((P < End) && core::isspace(P[0])) + ++P; + + if (P >= End) + return; + + // check if this is a comment + if ((P[0] == '/' && P[1] == '/') || + P[0] == '#') + readUntilEndOfLine(); + else + break; + } +} + + +//! reads a x file style string +bool CXMeshFileLoader::getNextTokenAsString(core::stringc& out) +{ + if (BinaryFormat) + { + out=getNextToken(); + return true; + } + findNextNoneWhiteSpace(); + + if (P >= End) + return false; + + if (P[0] != '"') + return false; + ++P; + + while(P < End && P[0]!='"') + { + out.append(P[0]); + ++P; + } + + if ( P[1] != ';' || P[0] != '"') + return false; + P+=2; + + return true; +} + + +void CXMeshFileLoader::readUntilEndOfLine() +{ + if (BinaryFormat) + return; + + while(P < End) + { + if (P[0] == '\n' || P[0] == '\r') + { + ++P; + return; + } + + ++P; + } +} + + +u16 CXMeshFileLoader::readBinWord() +{ + u8 *Q = (u8 *)P; + u16 tmp = 0; + tmp = Q[0] + (Q[1] << 8); + P += 2; + return tmp; +} + + +u32 CXMeshFileLoader::readBinDWord() +{ + u8 *Q = (u8 *)P; + u32 tmp = 0; + tmp = Q[0] + (Q[1] << 8) + (Q[2] << 16) + (Q[3] << 24); + P += 4; + return tmp; +} + + +u32 CXMeshFileLoader::readInt() +{ + if (BinaryFormat) + { + if (!BinaryNumCount) + { + u16 tmp = readBinWord(); // 0x06 or 0x03 + if (tmp == 0x06) + BinaryNumCount = readBinDWord(); + else + BinaryNumCount = 1; // single int + } + --BinaryNumCount; + return readBinDWord(); + } + else + { + findNextNoneWhiteSpaceNumber(); + return core::strtol10(P, &P); + } +} + + +f32 CXMeshFileLoader::readFloat() +{ + if (BinaryFormat) + { + if (!BinaryNumCount) + { + u16 tmp = readBinWord(); // 0x07 or 0x42 + if (tmp == 0x07) + BinaryNumCount = readBinDWord(); + else + BinaryNumCount = 1; // single int + } + --BinaryNumCount; + if (FloatSize == 8) + { + char tmp[8]; + memcpy(tmp, P, 8); + P += 8; + return (f32)(*(f64 *)tmp); + } + else + { + char tmp[4]; + memcpy(tmp, P, 4); + P += 4; + return *(f32 *)tmp; + } + } + findNextNoneWhiteSpaceNumber(); + f32 ftmp; + P = core::fast_atof_move(P, ftmp); + return ftmp; +} + + +// read 2-dimensional vector. Stops at semicolon after second value for text file format +bool CXMeshFileLoader::readVector2(core::vector2df& vec) +{ + vec.X = readFloat(); + vec.Y = readFloat(); + return true; +} + + +// read 3-dimensional vector. Stops at semicolon after third value for text file format +bool CXMeshFileLoader::readVector3(core::vector3df& vec) +{ + vec.X = readFloat(); + vec.Y = readFloat(); + vec.Z = readFloat(); + return true; +} + + +// read color without alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGB(video::SColorf& color) +{ + color.r = readFloat(); + color.g = readFloat(); + color.b = readFloat(); + color.a = 1.0f; + return checkForOneFollowingSemicolons(); +} + + +// read color with alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGBA(video::SColorf& color) +{ + color.r = readFloat(); + color.g = readFloat(); + color.b = readFloat(); + color.a = readFloat(); + return checkForOneFollowingSemicolons(); +} + + +// read color without alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGB(video::SColor& color) +{ + color.setRed( (u32)(readFloat()*255)) ; + color.setGreen( (u32)(readFloat()*255)) ; + color.setBlue( (u32)(readFloat()*255)) ; + color.setAlpha( 255 ); + return checkForOneFollowingSemicolons(); +} + + +// read color with alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGBA(video::SColor& color) +{ + color.setRed( (u32)(readFloat()*255)) ; + color.setGreen( (u32)(readFloat()*255)) ; + color.setBlue( (u32)(readFloat()*255)) ; + color.setAlpha( (u32)(readFloat()*255)) ; + return checkForOneFollowingSemicolons(); +} + + +core::stringc CXMeshFileLoader::stripPathFromString(core::stringc string, bool returnPath) +{ + s32 slashIndex=string.findLast('/'); // forward slash + s32 backSlash=string.findLast('\\'); // back slash + + if (backSlash>slashIndex) slashIndex=backSlash; + + if (slashIndex==-1)//no slashes found + if (returnPath) + return core::stringc(); //no path to return + else + return string; + + if (returnPath) + return string.subString(0, slashIndex + 1); + else + return string.subString(slashIndex+1, string.size() - (slashIndex+1)); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_X_LOADER_ + diff --git a/src/dep/src/irrlicht/CXMeshFileLoader.h b/src/dep/src/irrlicht/CXMeshFileLoader.h new file mode 100644 index 0000000..58e542c --- /dev/null +++ b/src/dep/src/irrlicht/CXMeshFileLoader.h @@ -0,0 +1,199 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_X_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_X_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "irrString.h" +#include "CSkinnedMesh.h" + + +namespace irr +{ +namespace io +{ + class IReadFile; +} // end namespace io +namespace scene +{ +class IMeshManipulator; + +//! Meshloader capable of loading x meshes. +class CXMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CXMeshFileLoader(scene::ISceneManager* smgr); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + struct SXTemplateMaterial + { + core::stringc Name; // template name from Xfile + video::SMaterial Material; // material + }; + + struct SXMesh + { + SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false), HasVertexColors(false) {} + // this mesh contains triangulated texture data. + // because in an .x file, faces can be made of more than 3 + // vertices, the indices data structure is triangulated during the + // loading process. The IndexCountPerFace array is filled during + // this triangulation process and stores how much indices belong to + // every face. This data structure can be ignored, because all data + // in this structure is triangulated. + + core::stringc Name; + + u32 MaxSkinWeightsPerVertex; + u32 MaxSkinWeightsPerFace; + u32 BoneCount; + + core::array< u32 > IndexCountPerFace; // default 3, but could be more + + core::array Buffers; + + core::array Vertices; + + core::array Indices; + + core::array FaceMaterialIndices; // index of material for each face + + core::array Materials; // material array + + s32 AttachedJointID; + + bool HasSkinning; + bool HasVertexColors; + + core::array Weights; + }; + +private: + + bool load(io::IReadFile* file); + + bool readFileIntoMemory(io::IReadFile* file); + + bool parseFile(); + + + bool parseDataObject(); + + bool parseDataObjectTemplate(); + + bool parseDataObjectFrame(CSkinnedMesh::SJoint *parent); + + bool parseDataObjectTransformationMatrix(core::matrix4 &mat); + + bool parseDataObjectMesh(SXMesh &mesh); + + bool parseDataObjectSkinWeights(SXMesh &mesh); + + bool parseDataObjectSkinMeshHeader(SXMesh &mesh); + + bool parseDataObjectMeshNormals(SXMesh &mesh); + + bool parseDataObjectMeshTextureCoords(SXMesh &mesh); + + bool parseDataObjectMeshVertexColors(SXMesh &mesh); + + bool parseDataObjectMeshMaterialList(SXMesh &mesh); + + bool parseDataObjectMaterial(video::SMaterial& material); + + bool parseDataObjectAnimationSet(); + + bool parseDataObjectAnimation(); + + bool parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint); + + bool parseDataObjectTextureFilename(core::stringc& texturename); + + bool parseUnknownDataObject(); + + //! places pointer to next begin of a token, and ignores comments + void findNextNoneWhiteSpace(); + + //! places pointer to next begin of a token, which must be a number, + // and ignores comments + void findNextNoneWhiteSpaceNumber(); + + //! returns next parseable token. Returns empty string if no token there + core::stringc getNextToken(); + + //! reads header of dataobject including the opening brace. + //! returns false if error happened, and writes name of object + //! if there is one + bool readHeadOfDataObject(core::stringc* outname=0); + + //! checks for closing curly brace, returns false if not there + bool checkForClosingBrace(); + + //! checks for one following semicolons, returns false if not there + bool checkForOneFollowingSemicolons(); + + //! checks for two following semicolons, returns false if they are not there + bool checkForTwoFollowingSemicolons(); + + //! reads a x file style string + bool getNextTokenAsString(core::stringc& out); + + void readUntilEndOfLine(); + + core::stringc stripPathFromString(core::stringc string, bool returnPath); + + u16 readBinWord(); + u32 readBinDWord(); + u32 readInt(); + f32 readFloat(); + bool readVector2(core::vector2df& vec); + bool readVector3(core::vector3df& vec); + bool readRGB(video::SColorf& color); + bool readRGBA(video::SColorf& color); + + bool readRGB(video::SColor& color); + bool readRGBA(video::SColor& color); + + ISceneManager* SceneManager; + + core::array *AllJoints; + + CSkinnedMesh* AnimatedMesh; + + u32 MajorVersion; + u32 MinorVersion; + bool BinaryFormat; + // counter for number arrays in binary format + u32 BinaryNumCount; + + c8* Buffer; + const c8* P; + c8* End; + c8 FloatSize; + core::stringc FilePath; + + CSkinnedMesh::SJoint *CurFrame; + + core::array Meshes; + + core::array TemplateMaterials; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CZBuffer.cpp b/src/dep/src/irrlicht/CZBuffer.cpp new file mode 100644 index 0000000..bc1a140 --- /dev/null +++ b/src/dep/src/irrlicht/CZBuffer.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CZBuffer.h" +#include "irrString.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! constructor +CZBuffer::CZBuffer(const core::dimension2d& size) +: Buffer(0), BufferEnd(0), Size(0,0), TotalSize(0) +{ + #ifdef _DEBUG + setDebugName("CZBuffer"); + #endif + + setSize(size); +} + + + +//! destructor +CZBuffer::~CZBuffer() +{ + delete [] Buffer; +} + + + +//! clears the zbuffer +void CZBuffer::clear() +{ + memset(Buffer, 0, (BufferEnd-Buffer)*sizeof(TZBufferType)); +} + + + +//! sets the new size of the zbuffer +void CZBuffer::setSize(const core::dimension2d& size) +{ + if (size == Size) + return; + + Size = size; + + delete [] Buffer; + + TotalSize = size.Width * size.Height; + Buffer = new TZBufferType[TotalSize]; + BufferEnd = Buffer + TotalSize; +} + + + +//! returns the size of the zbuffer +const core::dimension2d& CZBuffer::getSize() const +{ + return Size; +} + + + +//! locks the zbuffer +TZBufferType* CZBuffer::lock() +{ + return Buffer; +} + + + +//! unlocks the zbuffer +void CZBuffer::unlock() +{ +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a ZBuffer +IZBuffer* createZBuffer(const core::dimension2d& size) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CZBuffer(size); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/dep/src/irrlicht/CZBuffer.h b/src/dep/src/irrlicht/CZBuffer.h new file mode 100644 index 0000000..6714296 --- /dev/null +++ b/src/dep/src/irrlicht/CZBuffer.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Z_BUFFER_H_INCLUDED__ +#define __C_Z_BUFFER_H_INCLUDED__ + +#include "IZBuffer.h" + +namespace irr +{ +namespace video +{ + + class CZBuffer : public IZBuffer + { + public: + + //! constructor + CZBuffer(const core::dimension2d& size); + + //! destructor + virtual ~CZBuffer(); + + //! clears the zbuffer + virtual void clear(); + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size); + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const; + + //! locks the zbuffer + virtual TZBufferType* lock(); + + //! unlocks the zbuffer + virtual void unlock(); + + private: + + TZBufferType* Buffer; + TZBufferType* BufferEnd; + core::dimension2d Size; + s32 TotalSize; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/CZipReader.cpp b/src/dep/src/irrlicht/CZipReader.cpp new file mode 100644 index 0000000..1723dcd --- /dev/null +++ b/src/dep/src/irrlicht/CZipReader.cpp @@ -0,0 +1,484 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CZipReader.h" +#include "CFileList.h" +#include "CReadFile.h" +#include "os.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_ZLIB_ + #ifndef _IRR_USE_NON_SYSTEM_ZLIB_ + #include // use system lib + #else // _IRR_USE_NON_SYSTEM_ZLIB_ + #include "zlib/zlib.h" + #endif // _IRR_USE_NON_SYSTEM_ZLIB_ +#endif // _IRR_COMPILE_WITH_ZLIB_ + +namespace irr +{ +namespace io +{ + + +CZipReader::CZipReader(IReadFile* file, bool ignoreCase, bool ignorePaths) +: File(file), IgnoreCase(ignoreCase), IgnorePaths(ignorePaths) +{ + #ifdef _DEBUG + setDebugName("CZipReader"); + #endif + + if (File) + { + File->grab(); + + // scan local headers + while (scanLocalHeader()); + + // prepare file index for binary search + FileList.sort(); + } +} + +CZipReader::~CZipReader() +{ + if (File) + File->drop(); +} + + + +//! splits filename from zip file into useful filenames and paths +void CZipReader::extractFilename(SZipFileEntry* entry) +{ + s32 lorfn = entry->header.FilenameLength; // length of real file name + + if (!lorfn) + return; + + if (IgnoreCase) + entry->zipFileName.make_lower(); + + const c8* p = entry->zipFileName.c_str() + lorfn; + + // suche ein slash oder den anfang. + + while (*p!='/' && p!=entry->zipFileName.c_str()) + { + --p; + --lorfn; + } + + bool thereIsAPath = p != entry->zipFileName.c_str(); + + if (thereIsAPath) + { + // there is a path + ++p; + ++lorfn; + } + + entry->simpleFileName = p; + entry->path = ""; + + // pfad auch kopieren + if (thereIsAPath) + { + lorfn = (s32)(p - entry->zipFileName.c_str()); + + entry->path = entry->zipFileName.subString ( 0, lorfn ); + + //entry->path.append(entry->zipFileName, lorfn); + //entry->path.append ( "" ); + } + + if (!IgnorePaths) + entry->simpleFileName = entry->zipFileName; // thanks to Pr3t3nd3r for this fix +} + + + +//! scans for a local header, returns false if there is no more local file header. +bool CZipReader::scanLocalHeader() +{ + c8 tmp[1024]; + + SZipFileEntry entry; + entry.fileDataPosition = 0; + memset(&entry.header, 0, sizeof(SZIPFileHeader)); + + File->read(&entry.header, sizeof(SZIPFileHeader)); + +#ifdef __BIG_ENDIAN__ + entry.header.Sig = os::Byteswap::byteswap(entry.header.Sig); + entry.header.VersionToExtract = os::Byteswap::byteswap(entry.header.VersionToExtract); + entry.header.GeneralBitFlag = os::Byteswap::byteswap(entry.header.GeneralBitFlag); + entry.header.CompressionMethod = os::Byteswap::byteswap(entry.header.CompressionMethod); + entry.header.LastModFileTime = os::Byteswap::byteswap(entry.header.LastModFileTime); + entry.header.LastModFileDate = os::Byteswap::byteswap(entry.header.LastModFileDate); + entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32); + entry.header.DataDescriptor.CompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.CompressedSize); + entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize); + entry.header.FilenameLength = os::Byteswap::byteswap(entry.header.FilenameLength); + entry.header.ExtraFieldLength = os::Byteswap::byteswap(entry.header.ExtraFieldLength); +#endif + + if (entry.header.Sig != 0x04034b50) + return false; // local file headers end here. + + // read filename + entry.zipFileName.reserve(entry.header.FilenameLength+2); + File->read(tmp, entry.header.FilenameLength); + tmp[entry.header.FilenameLength] = 0x0; + entry.zipFileName = tmp; + + extractFilename(&entry); + + // move forward length of extra field. + + if (entry.header.ExtraFieldLength) + File->seek(entry.header.ExtraFieldLength, true); + + // if bit 3 was set, read DataDescriptor, following after the compressed data + if (entry.header.GeneralBitFlag & ZIP_INFO_IN_DATA_DESCRITOR) + { + // read data descriptor + File->read(&entry.header.DataDescriptor, sizeof(entry.header.DataDescriptor)); +#ifdef __BIG_ENDIAN__ + entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32); + entry.header.DataDescriptor.CompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.CompressedSize); + entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize); +#endif + } + + // store position in file + entry.fileDataPosition = File->getPos(); + + // move forward length of data + File->seek(entry.header.DataDescriptor.CompressedSize, true); + + #ifdef _DEBUG + //os::Debuginfo::print("added file from archive", entry.simpleFileName.c_str()); + #endif + + FileList.push_back(entry); + + return true; +} + + + +//! opens a file by file name +IReadFile* CZipReader::openFile(const c8* filename) +{ + s32 index = findFile(filename); + + if (index != -1) + return openFile(index); + + return 0; +} + + + +//! opens a file by index +IReadFile* CZipReader::openFile(s32 index) +{ + //0 - The file is stored (no compression) + //1 - The file is Shrunk + //2 - The file is Reduced with compression factor 1 + //3 - The file is Reduced with compression factor 2 + //4 - The file is Reduced with compression factor 3 + //5 - The file is Reduced with compression factor 4 + //6 - The file is Imploded + //7 - Reserved for Tokenizing compression algorithm + //8 - The file is Deflated + //9 - Reserved for enhanced Deflating + //10 - PKWARE Date Compression Library Imploding + + switch(FileList[index].header.CompressionMethod) + { + case 0: // no compression + { + File->seek(FileList[index].fileDataPosition); + return createLimitReadFile(FileList[index].simpleFileName.c_str(), File, FileList[index].header.DataDescriptor.UncompressedSize); + } + case 8: + { + #ifdef _IRR_COMPILE_WITH_ZLIB_ + + const u32 uncompressedSize = FileList[index].header.DataDescriptor.UncompressedSize; + const u32 compressedSize = FileList[index].header.DataDescriptor.CompressedSize; + + void* pBuf = new c8[ uncompressedSize ]; + if (!pBuf) + { + os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); + return 0; + } + + c8 *pcData = new c8[ compressedSize ]; + if (!pcData) + { + os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); + return 0; + } + + //memset(pcData, 0, compressedSize ); + File->seek(FileList[index].fileDataPosition); + File->read(pcData, compressedSize ); + + // Setup the inflate stream. + z_stream stream; + s32 err; + + stream.next_in = (Bytef*)pcData; + stream.avail_in = (uInt)compressedSize; + stream.next_out = (Bytef*)pBuf; + stream.avail_out = uncompressedSize; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + // Perform inflation. wbits < 0 indicates no zlib header inside the data. + err = inflateInit2(&stream, -MAX_WBITS); + if (err == Z_OK) + { + err = inflate(&stream, Z_FINISH); + inflateEnd(&stream); + if (err == Z_STREAM_END) + err = Z_OK; + err = Z_OK; + inflateEnd(&stream); + } + + + delete[] pcData; + + if (err != Z_OK) + { + os::Printer::log("Error decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); + delete [] (c8*)pBuf; + return 0; + } + else + return io::createMemoryReadFile(pBuf, uncompressedSize, FileList[index].zipFileName.c_str(), true); + + #else + return 0; // zlib not compiled, we cannot decompress the data. + #endif + } + default: + os::Printer::log("file has unsupported compression method.", FileList[index].simpleFileName.c_str(), ELL_ERROR); + return 0; + }; +} + + + +//! returns count of files in archive +s32 CZipReader::getFileCount() +{ + return FileList.size(); +} + + + +//! returns data of file +const SZipFileEntry* CZipReader::getFileInfo(s32 index) const +{ + return &FileList[index]; +} + + + +//! deletes the path from a filename +void CZipReader::deletePathFromFilename(core::stringc& filename) +{ + // delete path from filename + const c8* p = filename.c_str() + filename.size(); + + // suche ein slash oder den anfang. + + while (*p!='/' && *p!='\\' && p!=filename.c_str()) + --p; + + core::stringc newName; + + if (p != filename.c_str()) + { + ++p; + filename = p; + } +} + + + +//! returns fileindex +s32 CZipReader::findFile(const c8* simpleFilename) +{ + SZipFileEntry entry; + entry.simpleFileName = simpleFilename; + + if (IgnoreCase) + entry.simpleFileName.make_lower(); + + if (IgnorePaths) + deletePathFromFilename(entry.simpleFileName); + + s32 res = FileList.binary_search(entry); + + #ifdef _DEBUG + if (res == -1) + { + for (u32 i=0; iisOpen()) + return file; + + file->drop(); + return 0; + +} + +//! returns fileindex +s32 CUnZipReader::findFile(const c8* filename) +{ + IReadFile *file = openFile ( filename ); + if ( 0 == file ) + return -1; + file->drop (); + return 1; +} + +#else + +CUnZipReader::CUnZipReader( IFileSystem * parent, const c8* basename, bool ignoreCase, bool ignorePaths) + : CZipReader( 0, ignoreCase, ignorePaths ), Parent ( parent ) +{ + strcpy ( Buf, Parent->getWorkingDirectory () ); + + Parent->changeWorkingDirectoryTo ( basename ); + buildDirectory ( ); + Parent->changeWorkingDirectoryTo ( Buf ); + + FileList.sort(); +} + +void CUnZipReader::buildDirectory ( ) +{ + IFileList * list = new CFileList(); + + SZipFileEntry entry; + + const u32 size = list->getFileCount(); + for (u32 i = 0; i!= size; ++i) + { + if ( false == list->isDirectory( i ) ) + { + entry.zipFileName = list->getFullFileName ( i ); + entry.header.FilenameLength = entry.zipFileName.size (); + extractFilename(&entry); + FileList.push_back(entry); + } + else + { + const c8 * rel = list->getFileName ( i ); + + if (strcmp( rel, "." ) && strcmp( rel, ".." )) + { + Parent->changeWorkingDirectoryTo ( rel ); + buildDirectory (); + Parent->changeWorkingDirectoryTo ( ".." ); + } + } + } + + list->drop (); +} + +//! opens a file by file name +IReadFile* CUnZipReader::openFile(const c8* filename) +{ + s32 index = -1; + + if ( IgnorePaths ) + { + index = findFile(filename); + } + else + if ( FileList.size () ) + { + const core::stringc search = FileList[0].path + filename; + index = findFile( search.c_str() ); + } + + if (index == -1) + return 0; + + return createReadFile(FileList[index].zipFileName.c_str() ); +} +#endif + + +} // end namespace io +} // end namespace irr + diff --git a/src/dep/src/irrlicht/CZipReader.h b/src/dep/src/irrlicht/CZipReader.h new file mode 100644 index 0000000..6b37e72 --- /dev/null +++ b/src/dep/src/irrlicht/CZipReader.h @@ -0,0 +1,157 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ZIP_READER_H_INCLUDED__ +#define __C_ZIP_READER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace io +{ + + const s16 ZIP_FILE_ENCRYPTED = 0x0001; // set if the file is encrypted + const s16 ZIP_INFO_IN_DATA_DESCRITOR = 0x0008; // the fields crc-32, compressed size + // and uncompressed size are set to zero in the local + // header + +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( push, packing ) +# pragma pack( 1 ) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error compiler not supported +#endif + + + struct SZIPFileDataDescriptor + { + s32 CRC32; + s32 CompressedSize; + s32 UncompressedSize; + } PACK_STRUCT; + + struct SZIPFileHeader + { + s32 Sig; + s16 VersionToExtract; + s16 GeneralBitFlag; + s16 CompressionMethod; + s16 LastModFileTime; + s16 LastModFileDate; + SZIPFileDataDescriptor DataDescriptor; + s16 FilenameLength; + s16 ExtraFieldLength; + } PACK_STRUCT; + +// Default alignment +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop, packing ) +#endif + +#undef PACK_STRUCT + + + struct SZipFileEntry + { + core::stringc zipFileName; + core::stringc simpleFileName; + core::stringc path; + s32 fileDataPosition; // position of compressed data in file + SZIPFileHeader header; + + bool operator < (const SZipFileEntry& other) const + { + return simpleFileName < other.simpleFileName; + } + + + bool operator == (const SZipFileEntry& other) const + { + return simpleFileName == other.simpleFileName; + } + }; + + + +/*! + Zip file Reader written April 2002 by N.Gebhardt. + Doesn't decompress data, only reads the file and is able to + open uncompressed entries. +*/ + class CZipReader : public virtual IReferenceCounted + { + public: + + CZipReader(IReadFile* file, bool ignoreCase, bool ignorePaths); + virtual ~CZipReader(); + + //! opens a file by file name + virtual IReadFile* openFile(const c8* filename); + + //! opens a file by index + IReadFile* openFile(s32 index); + + //! returns count of files in archive + s32 getFileCount(); + + //! returns data of file + const SZipFileEntry* getFileInfo(s32 index) const; + + //! returns fileindex + s32 findFile(const c8* filename); + + private: + + //! scans for a local header, returns false if there is no more local file header. + bool scanLocalHeader(); + IReadFile* File; + + protected: + + //! splits filename from zip file into useful filenames and paths + void extractFilename(SZipFileEntry* entry); + + //! deletes the path from a filename + void deletePathFromFilename(core::stringc& filename); + + + bool IgnoreCase; + bool IgnorePaths; + core::array FileList; + }; + + + class CUnZipReader : public CZipReader + { + public: + + CUnZipReader( IFileSystem *parent, const c8* basename, bool ignoreCase, bool ignorePaths); + + //! opens a file by file name + virtual IReadFile* openFile(const c8* filename); + + //! returns fileindex + s32 findFile(const c8* filename); + + private: + + IFileSystem *Parent; + void buildDirectory (); + + core::stringc Base; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/IBurningShader.cpp b/src/dep/src/irrlicht/IBurningShader.cpp new file mode 100644 index 0000000..c96ff9e --- /dev/null +++ b/src/dep/src/irrlicht/IBurningShader.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_compile_config.h" +#include "IBurningShader.h" + +namespace irr +{ + +namespace video +{ + + const tFixPointu IBurningShader::dithermask[ 4 * 4] = + { + 0x00,0x80,0x20,0xa0, + 0xc0,0x40,0xe0,0x60, + 0x30,0xb0,0x10,0x90, + 0xf0,0x70,0xd0,0x50 + }; + + IBurningShader::IBurningShader(IDepthBuffer* zbuffer) + :RenderTarget(0),ZBuffer(zbuffer) + { + IT[0].Texture = 0; + IT[1].Texture = 0; + + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M1"); + #endif + + if (ZBuffer) + zbuffer->grab(); + } + + + //! destructor + IBurningShader::~IBurningShader() + { + if (RenderTarget) + RenderTarget->drop(); + + if (ZBuffer) + ZBuffer->drop(); + + if ( IT[0].Texture ) + IT[0].Texture->drop(); + + if ( IT[1].Texture ) + IT[1].Texture->drop(); + } + + //! sets a render target + void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect& viewPort) + { + if (RenderTarget) + RenderTarget->drop(); + + RenderTarget = surface; + + if (RenderTarget) + { + SurfaceWidth = RenderTarget->getDimension().Width; + RenderTarget->grab(); + } + } + + + //! sets the Texture + void IBurningShader::setTexture( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel) + { + sInternalTexture *it = &IT[stage]; + + if ( it->Texture) + it->Texture->drop(); + + it->Texture = texture; + + if ( it->Texture) + { + it->Texture->grab(); + + // select mignify and magnify ( lodLevel ) + //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS + it->lodLevel = lodLevel; + it->Texture->setCurrentMipMapLOD ( + core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ) + ); + + // prepare for optimal fixpoint + it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() ); + + it->textureXMask = s32_to_fixPoint ( it->Texture->getSize().Width - 1 ) & FIX_POINT_UNSIGNED_MASK; + it->textureYMask = s32_to_fixPoint ( it->Texture->getSize().Height - 1 ) & FIX_POINT_UNSIGNED_MASK; + } + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ diff --git a/src/dep/src/irrlicht/IBurningShader.h b/src/dep/src/irrlicht/IBurningShader.h new file mode 100644 index 0000000..7cf80a1 --- /dev/null +++ b/src/dep/src/irrlicht/IBurningShader.h @@ -0,0 +1,129 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BURNING_SHADER_H_INCLUDED__ +#define __I_BURNING_SHADER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "IReferenceCounted.h" +#include "irrMath.h" +#include "IImage.h" +#include "S2DVertex.h" +#include "rect.h" +#include "IDepthBuffer.h" +#include "S4DVertex.h" + + +namespace irr +{ + +namespace video +{ + + enum EBurningFFShader + { + ETR_FLAT = 0, + ETR_FLAT_WIRE, + ETR_GOURAUD, + ETR_GOURAUD_WIRE, + ETR_TEXTURE_FLAT, + ETR_TEXTURE_FLAT_WIRE, + ETR_TEXTURE_GOURAUD, + ETR_TEXTURE_GOURAUD_WIRE, + ETR_TEXTURE_GOURAUD_NOZ, + ETR_TEXTURE_GOURAUD_ADD, + ETR_TEXTURE_GOURAUD_ADD_NO_Z, + + ETR_TEXTURE_GOURAUD_VERTEX_ALPHA, + + ETR_TEXTURE_GOURAUD_LIGHTMAP, + ETR_TEXTURE_GOURAUD_LIGHTMAP_M2, + ETR_TEXTURE_LIGHTMAP_M4, + ETR_TEXTURE_GOURAUD_LIGHTMAP_M4, + + ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD, + + ETR_TEXTURE_GOURAUD_DETAIL_MAP, + + ETR_GOURAUD_ALPHA, + ETR_GOURAUD_ALPHA_NOZ, + + ETR_TEXTURE_GOURAUD_ALPHA, + ETR_TEXTURE_GOURAUD_ALPHA_NOZ, + + ETR_TEXTURE_BLEND, + ETR_INVALID, + + ETR2_COUNT + }; + + class IBurningShader : public virtual IReferenceCounted + { + public: + IBurningShader(IDepthBuffer* zbuffer); + + //! destructor + virtual ~IBurningShader(); + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort); + + //! sets the Texture + virtual void setTexture( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel); + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0; + virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {}; + + virtual void setParam ( u32 index, f32 value) {}; + virtual void setZCompareFunc ( u32 func) {}; + + protected: + + video::IImage* RenderTarget; + + IDepthBuffer* ZBuffer; + + s32 SurfaceWidth; + fp24* lockedZBuffer; + tVideoSample* lockedSurface; + + sInternalTexture IT[2]; + + static const tFixPointu dithermask[ 4 * 4]; + }; + + + IBurningShader* createTriangleRendererTextureGouraud2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureLightMap2_M1(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureLightMap2_M2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureLightMap2_M4(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererGTextureLightMap2_M4(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureLightMap2_Add(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureDetailMap2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureVertexAlpha2(IDepthBuffer* zbuffer); + + + IBurningShader* createTriangleRendererTextureGouraudWire2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererGouraud2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererGouraudAlpha2(IDepthBuffer* zbuffer); + IBurningShader* createTRGouraudAlphaNoZ2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererGouraudWire2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureFlat2(IDepthBuffer* zbuffer); + IBurningShader* createTriangleRendererTextureFlatWire2(IDepthBuffer* zbuffer); + IBurningShader* createTRFlat2(IDepthBuffer* zbuffer); + IBurningShader* createTRFlatWire2(IDepthBuffer* zbuffer); + IBurningShader* createTRTextureGouraudNoZ2(); + IBurningShader* createTRTextureGouraudAdd2(IDepthBuffer* zbuffer); + IBurningShader* createTRTextureGouraudAddNoZ2(IDepthBuffer* zbuffer); + + IBurningShader* createTRTextureGouraudAlpha(IDepthBuffer* zbuffer); + IBurningShader* createTRTextureGouraudAlphaNoZ(IDepthBuffer* zbuffer); + IBurningShader* createTRTextureBlend(IDepthBuffer* zbuffer); + IBurningShader* createTRTextureInverseAlphaBlend(IDepthBuffer* zbuffer); + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/IDepthBuffer.h b/src/dep/src/irrlicht/IDepthBuffer.h new file mode 100644 index 0000000..467b9cb --- /dev/null +++ b/src/dep/src/irrlicht/IDepthBuffer.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Z2_BUFFER_H_INCLUDED__ +#define __I_Z2_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "S4DVertex.h" + +namespace irr +{ +namespace video +{ + class IDepthBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IDepthBuffer() {}; + + //! clears the zbuffer + virtual void clear() = 0; + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size) = 0; + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const = 0; + + //! locks the zbuffer + virtual fp24* lock() = 0; + + //! unlocks the zbuffer + virtual void unlock() = 0; + }; + + + //! creates a ZBuffer + IDepthBuffer* createDepthBuffer(const core::dimension2d& size); + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/IImagePresenter.h b/src/dep/src/irrlicht/IImagePresenter.h new file mode 100644 index 0000000..7b38207 --- /dev/null +++ b/src/dep/src/irrlicht/IImagePresenter.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IMAGE_PRESENTER_H_INCLUDED__ +#define __I_IMAGE_PRESENTER_H_INCLUDED__ + +#include "IImage.h" + +namespace irr +{ +namespace video +{ + +/*! + Interface for a class which is able to present an IImage + an the Screen. Usually only implemented by an IrrDevice for + presenting Software Device Rendered images. + + This class should be used only internally. +*/ + + class IImagePresenter + { + public: + + virtual ~IImagePresenter() {}; + //! presents a surface in the client area + virtual void present(video::IImage* surface, s32 windowId=0, core::rect* src=0 ) = 0; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/ITriangleRenderer.h b/src/dep/src/irrlicht/ITriangleRenderer.h new file mode 100644 index 0000000..731ced5 --- /dev/null +++ b/src/dep/src/irrlicht/ITriangleRenderer.h @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TRIANGLE_RENDERER_H_INCLUDED__ +#define __I_TRIANGLE_RENDERER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "IImage.h" +#include "S2DVertex.h" +#include "rect.h" +#include "IZBuffer.h" + +namespace irr +{ +namespace video +{ + + enum ETriangleRenderer + { + ETR_FLAT = 0, + ETR_FLAT_WIRE, + ETR_GOURAUD, + ETR_GOURAUD_WIRE, + ETR_TEXTURE_FLAT, + ETR_TEXTURE_FLAT_WIRE, + ETR_TEXTURE_GOURAUD, + ETR_TEXTURE_GOURAUD_WIRE, + ETR_TEXTURE_GOURAUD_NOZ, + ETR_TEXTURE_GOURAUD_ADD, + ETR_COUNT + }; + + class ITriangleRenderer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~ITriangleRenderer() {}; + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort) = 0; + + //! en or disables the backface culling + virtual void setBackfaceCulling(bool enabled = true) = 0; + + //! sets the Texture + virtual void setTexture(video::IImage* texture) = 0; + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) = 0; + }; + + + ITriangleRenderer* createTriangleRendererTextureGouraud(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureGouraudWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererGouraud(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererGouraudWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureFlat(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererFlatWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureGouraudNoZ(); + ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer); + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/IZBuffer.h b/src/dep/src/irrlicht/IZBuffer.h new file mode 100644 index 0000000..d345d4a --- /dev/null +++ b/src/dep/src/irrlicht/IZBuffer.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Z_BUFFER_H_INCLUDED__ +#define __I_Z_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "S2DVertex.h" + +namespace irr +{ +namespace video +{ + class IZBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IZBuffer() {}; + + //! clears the zbuffer + virtual void clear() = 0; + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size) = 0; + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const = 0; + + //! locks the zbuffer + virtual TZBufferType* lock() = 0; + + //! unlocks the zbuffer + virtual void unlock() = 0; + }; + + + //! creates a ZBuffer + IZBuffer* createZBuffer(const core::dimension2d& size); + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/Irrlicht.cpp b/src/dep/src/irrlicht/Irrlicht.cpp new file mode 100644 index 0000000..ade41f7 --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht.cpp @@ -0,0 +1,71 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +static const char* const copyright = "Irrlicht Engine (c) 2002-2007 Nikolaus Gebhardt"; + +#ifdef _IRR_WINDOWS_ + #include + #if defined(_DEBUG) && !defined(__GNUWIN32__) + #include + #endif // _DEBUG +#endif + +#ifdef _IRR_XBOX_PLATFORM_ + #include +#endif + +#include "irrlicht.h" + +namespace irr +{ + //! stub for calling createDeviceEx + IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, bool fullscreen, + bool stencilbuffer, bool vsync, IEventReceiver* res, + const char* version) + { + SIrrlichtCreationParameters p; + p.DriverType = driverType; + p.WindowSize = windowSize; + p.Bits = bits; + p.Fullscreen = fullscreen; + p.Stencilbuffer = stencilbuffer; + p.Vsync = vsync; + p.EventReceiver = res; + p.SDK_version_do_not_use = version; + + return createDeviceEx(p); + } + +} // end namespace irr + + +#if defined(_IRR_WINDOWS_API_) + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved ) +{ + // _crtBreakAlloc = 139; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + #if defined(_DEBUG) && !defined(__GNUWIN32__) && !defined(__BORLANDC__) + _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); + #endif + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#endif // defined(_IRR_WINDOWS_) + diff --git a/src/dep/src/irrlicht/Irrlicht.dev b/src/dep/src/irrlicht/Irrlicht.dev new file mode 100644 index 0000000..2fd3271 --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht.dev @@ -0,0 +1,5969 @@ +[Project] +FileName=Irrlicht.dev +Name=Irrlicht +Ver=1 +IsCpp=1 +Type=3 +Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS_@@_ +CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS_@@_ +Includes=..\..\include;zlib +Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lopengl32_@@_ +Libs= +UnitCount=592 +Folders=doc,gui_impl,include,include/core,include/gui,include/io,include/scene,include/video,io_impl,other_impl,other_impl/extern,other_impl/extern/jpeglib,other_impl/extern/libpng,other_impl/extern/zlib,scene_impl,scene_impl/animators,scene_impl/collision,scene_impl/mesh,scene_impl/mesh/loaders,scene_impl/mesh/writers,scene_impl/nodes,scene_impl/nodes/particles,video_impl,"video_impl/Burning Video",video_impl/DirectX8,video_impl/DirectX9,video_impl/Null,video_impl/OpenGL,video_impl/Software +ObjFiles= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Icon= +ExeOutput=..\..\bin\Win32-gcc +ObjectOutput=obj +OverrideOutput=1 +OverrideOutputName=Irrlicht.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000001001000000100 + +[Unit1] +FileName=..\..\include\EDriverTypes.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\ITexture.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\IVideoDriver.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\S3DVertex.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\SColor.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\SLight.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\include\SMaterial.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\aabbox3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\dimension2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\heapsort.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\include\irrArray.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\include\irrList.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\include\irrMath.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\include\irrString.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\include\line2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\include\line3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\include\matrix4.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\include\plane3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\include\position2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\include\rect.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\include\vector2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\include\vector3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\include\IFileList.h +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\include\IFileSystem.h +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\include\IReadFile.H +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\include\IAnimatedMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\include\IAnimatedMeshSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\include\IBillboardSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\include\ICameraSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\include\ILightSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\include\IMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\include\IMeshBuffer.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\include\IQ3LevelMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\include\ISceneManager.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\include\ISceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\include\ISceneNodeAnimator.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\include\SMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\include\SMeshBuffer.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\include\SMeshBufferLightMap.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\include\ICursorControl.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\include\IGUIButton.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\include\IGUICheckbox.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\include\IGUIElement.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\include\IGUIEnvironment.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit45] +FileName=..\..\include\IGUIFileOpenDialog.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\include\IGUIFont.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\include\IGUIImage.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\include\IGUIListBox.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\include\IGUIMeshViewer.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\include\IGUIScrollBar.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\include\IGUISkin.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\include\IGUIWindow.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\include\IEventReceiver.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\include\Irrlicht.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\include\IrrlichtDevice.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\include\irrTypes.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\include\Keycodes.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\include\SIrrCreationParameters.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=BuiltInFont.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=CGUIButton.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=CGUIButton.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=CGUICheckbox.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=CGUICheckbox.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=CGUIComboBox.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=CGUIComboBox.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=CGUIContextMenu.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=CGUIContextMenu.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=CGUIEditBox.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=CGUIEditBox.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=CGUIEnvironment.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=CGUIEnvironment.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=CGUIFileOpenDialog.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=CGUIFileOpenDialog.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=CGUIFont.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=CGUIFont.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=CGUIImage.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=CGUIImage.H +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=CGUIInOutFader.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=CGUIInOutFader.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=CGUIListBox.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=CGUIListBox.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=CGUIMenu.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=CGUIMenu.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=CGUIMeshViewer.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=CGUIMeshViewer.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=CGUIMessageBox.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=CGUIMessageBox.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=CGUIModalScreen.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=CGUIModalScreen.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=CGUIScrollBar.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=CGUIScrollBar.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=CGUISkin.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=CGUISkin.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=CGUIStaticText.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=CGUIStaticText.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=CGUITabControl.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=CGUITabControl.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=CGUIToolBar.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit99] +FileName=CGUIToolBar.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=CGUIWindow.cpp +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=CGUIWindow.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=CSoftwareDriver.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=CSoftwareDriver.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=CSoftwareTexture.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=CSoftwareTexture.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=CTRFlat.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=CTRFlatWire.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=CTRGouraud.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=CTRGouraudWire.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=CTRTextureFlat.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=CTRTextureFlatWire.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=CTRTextureGouraud.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=CTRTextureGouraud.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=CTRTextureGouraudAdd.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=CTRTextureGouraudNoZ.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=CTRTextureGouraudWire.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=CZBuffer.cpp +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=CZBuffer.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=IZBuffer.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=S2DVertex.h +Folder=video_impl/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=COpenGLDriver.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=COpenGLDriver.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=COpenGLMaterialRenderer.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=COpenGLNormalMapRenderer.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=COpenGLNormalMapRenderer.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=COpenGLParallaxMapRenderer.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=COpenGLParallaxMapRenderer.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=COpenGLShaderMaterialRenderer.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit129] +FileName=COpenGLShaderMaterialRenderer.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=COpenGLTexture.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=COpenGLTexture.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=glext.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=CD3D8Driver.cpp +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=CD3D8Driver.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=CD3D8MaterialRenderer.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=CD3D8NormalMapRenderer.cpp +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=CD3D8NormalMapRenderer.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=CD3D8ParallaxMapRenderer.cpp +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=CD3D8ParallaxMapRenderer.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=CD3D8ShaderMaterialRenderer.cpp +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=CD3D8ShaderMaterialRenderer.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=CD3D8Texture.cpp +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=CD3D8Texture.h +Folder=video_impl/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=CColorConverter.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=CColorConverter.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=CFPSCounter.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=CFPSCounter.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=CImage.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=CImage.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=CImageLoaderBMP.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=CImageLoaderBMP.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=CImageLoaderJPG.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=CImageLoaderJPG.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=CImageLoaderPCX.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=CImageLoaderPCX.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=CImageLoaderPNG.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=CImageLoaderPNG.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=CImageLoaderPSD.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=CImageLoaderPSD.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=CImageLoaderTGA.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=CImageLoaderTGA.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=CNullDriver.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=CNullDriver.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=CD3D9Driver.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=CD3D9Driver.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=CD3D9HLSLMaterialRenderer.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=CD3D9HLSLMaterialRenderer.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=CD3D9MaterialRenderer.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=CD3D9NormalMapRenderer.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=CD3D9NormalMapRenderer.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=CD3D9ParallaxMapRenderer.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit172] +FileName=CD3D9ParallaxMapRenderer.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit173] +FileName=CD3D9ShaderMaterialRenderer.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit174] +FileName=CD3D9ShaderMaterialRenderer.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=CD3D9Texture.cpp +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=CD3D9Texture.h +Folder=video_impl/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=CVideoModeList.cpp +Folder=video_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=CVideoModeList.h +Folder=video_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=C3DSMeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=C3DSMeshFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=CAnimatedMeshMD2.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=CAnimatedMeshMD2.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=CAnimatedMeshSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=CAnimatedMeshSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=CBillboardSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=CBillboardSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=CCameraFPSSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=CCameraFPSSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=CCameraMayaSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=CCameraMayaSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=CCameraSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=CCameraSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=CColladaFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=CColladaFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=CCSMLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=CCSMLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit197] +FileName=CDMFLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit198] +FileName=CDMFLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit199] +FileName=CDummyTransformationSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit200] +FileName=CDummyTransformationSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=CEmptySceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=CEmptySceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=CGeometryCreator.cpp +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=CGeometryCreator.h +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=CLightSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=CLightSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=CLMTSMeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit208] +FileName=CLMTSMeshFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit209] +FileName=CMeshManipulator.cpp +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit210] +FileName=CMeshManipulator.h +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit211] +FileName=CMeshSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit212] +FileName=CMeshSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit213] +FileName=CMetaTriangleSelector.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit214] +FileName=CMetaTriangleSelector.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit215] +FileName=CMY3DHelper.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit216] +FileName=CMY3DMeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit217] +FileName=CMY3DMeshFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit218] +FileName=CMY3DStuff.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit219] +FileName=COCTLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit220] +FileName=COCTLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit221] +FileName=COctTreeSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit222] +FileName=COctTreeSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit223] +FileName=COctTreeTriangleSelector.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit224] +FileName=COctTreeTriangleSelector.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit225] +FileName=CParticleBoxEmitter.cpp +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit226] +FileName=CParticleBoxEmitter.h +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit227] +FileName=CParticleFadeOutAffector.cpp +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit228] +FileName=CParticleFadeOutAffector.h +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit229] +FileName=CParticleGravityAffector.cpp +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit230] +FileName=CParticleGravityAffector.h +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit231] +FileName=CParticlePointEmitter.cpp +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit232] +FileName=CParticlePointEmitter.h +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit233] +FileName=CParticleSystemSceneNode.cpp +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit234] +FileName=CParticleSystemSceneNode.h +Folder=scene_impl/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit235] +FileName=CQ3LevelMesh.cpp +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit236] +FileName=CQ3LevelMesh.h +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit237] +FileName=CSceneCollisionManager.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit238] +FileName=CSceneCollisionManager.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit239] +FileName=CSceneManager.cpp +Folder=scene_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit240] +FileName=CSceneManager.h +Folder=scene_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit241] +FileName=CSceneNodeAnimatorCollisionResponse.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit242] +FileName=CSceneNodeAnimatorCollisionResponse.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit243] +FileName=CSceneNodeAnimatorDelete.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit244] +FileName=CSceneNodeAnimatorDelete.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit245] +FileName=CSceneNodeAnimatorFlyCircle.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit246] +FileName=CSceneNodeAnimatorFlyCircle.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit247] +FileName=CSceneNodeAnimatorFlyStraight.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit248] +FileName=CSceneNodeAnimatorFlyStraight.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit249] +FileName=CSceneNodeAnimatorFollowSpline.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit250] +FileName=CSceneNodeAnimatorFollowSpline.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit251] +FileName=CSceneNodeAnimatorRotation.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit252] +FileName=CSceneNodeAnimatorRotation.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit253] +FileName=CSceneNodeAnimatorTexture.cpp +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit254] +FileName=CSceneNodeAnimatorTexture.h +Folder=scene_impl/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit255] +FileName=CShadowVolumeSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit256] +FileName=CShadowVolumeSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit257] +FileName=CSkyBoxSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit258] +FileName=CSkyBoxSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit259] +FileName=COBJMeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit260] +FileName=COBJMeshFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit261] +FileName=CTerrainSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit262] +FileName=CTerrainSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit263] +FileName=CTerrainTriangleSelector.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit264] +FileName=CTerrainTriangleSelector.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit265] +FileName=CTextSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit266] +FileName=CTextSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit267] +FileName=CTriangleBBSelector.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit268] +FileName=CTriangleBBSelector.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit269] +FileName=CTriangleSelector.cpp +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit270] +FileName=CTriangleSelector.h +Folder=scene_impl/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit271] +FileName=CWaterSurfaceSceneNode.cpp +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit272] +FileName=CWaterSurfaceSceneNode.h +Folder=scene_impl/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit273] +FileName=..\..\include\SExposedVideoData.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit274] +FileName=..\..\include\SKeyMap.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit275] +FileName=..\..\include\SMeshBufferTangents.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit276] +FileName=..\..\include\SParticle.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit277] +FileName=CXMeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit278] +FileName=CXMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit279] +FileName=OctTree.h +CompileCpp=1 +Folder=scene_impl/mesh +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit280] +FileName=CFileList.cpp +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit281] +FileName=CFileList.h +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit282] +FileName=CFileSystem.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit283] +FileName=CFileSystem.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit284] +FileName=CLimitReadFile.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit285] +FileName=CLimitReadFile.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit286] +FileName=CMemoryReadFile.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit287] +FileName=CMemoryReadFile.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit288] +FileName=CReadFile.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit289] +FileName=CReadFile.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit290] +FileName=CWriteFile.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit291] +FileName=CWriteFile.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit292] +FileName=CXMLReader.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit293] +FileName=CXMLReader.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit294] +FileName=CXMLWriter.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit295] +FileName=CXMLWriter.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit296] +FileName=CZipReader.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit297] +FileName=CZipReader.h +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit298] +FileName=irrXML.cpp +Folder=io_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit299] +FileName=zlib\adler32.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit300] +FileName=zlib\compress.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit301] +FileName=zlib\crc32.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit302] +FileName=zlib\crc32.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit303] +FileName=zlib\deflate.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit304] +FileName=zlib\deflate.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit305] +FileName=zlib\inffast.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit306] +FileName=zlib\inffast.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit307] +FileName=zlib\inflate.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit308] +FileName=zlib\inftrees.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit309] +FileName=zlib\inftrees.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit310] +FileName=zlib\trees.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit311] +FileName=zlib\trees.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit312] +FileName=zlib\uncompr.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit313] +FileName=zlib\zconf.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit314] +FileName=zlib\zlib.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit315] +FileName=zlib\zutil.c +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit316] +FileName=zlib\zutil.h +Folder=other_impl/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit317] +FileName=jpeglib\cderror.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit318] +FileName=jpeglib\cdjpeg.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit319] +FileName=jpeglib\cdjpeg.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit320] +FileName=jpeglib\jcapimin.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit321] +FileName=jpeglib\jcapistd.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit322] +FileName=jpeglib\jccoefct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit323] +FileName=jpeglib\jccolor.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit324] +FileName=jpeglib\jcdctmgr.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit325] +FileName=jpeglib\jchuff.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit326] +FileName=jpeglib\jchuff.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit327] +FileName=jpeglib\jcinit.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit328] +FileName=jpeglib\jcmainct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit329] +FileName=jpeglib\jcmarker.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit330] +FileName=jpeglib\jcmaster.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit331] +FileName=jpeglib\jcomapi.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit332] +FileName=jpeglib\jconfig.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit333] +FileName=jpeglib\jcparam.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit334] +FileName=jpeglib\jcphuff.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit335] +FileName=jpeglib\jcprepct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit336] +FileName=jpeglib\jcsample.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit337] +FileName=jpeglib\jctrans.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit338] +FileName=jpeglib\jdapimin.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit339] +FileName=jpeglib\jdapistd.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit340] +FileName=jpeglib\jdatadst.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit341] +FileName=jpeglib\jdatasrc.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit342] +FileName=jpeglib\jdcoefct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit343] +FileName=jpeglib\jdcolor.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit344] +FileName=jpeglib\jdct.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit345] +FileName=jpeglib\jddctmgr.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit346] +FileName=jpeglib\jdhuff.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit347] +FileName=jpeglib\jdhuff.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit348] +FileName=jpeglib\jdinput.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit349] +FileName=jpeglib\jdmainct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit350] +FileName=jpeglib\jdmarker.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit351] +FileName=jpeglib\jdmaster.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit352] +FileName=jpeglib\jdmerge.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit353] +FileName=jpeglib\jdphuff.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit354] +FileName=jpeglib\jdpostct.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit355] +FileName=jpeglib\jdsample.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit356] +FileName=jpeglib\jdtrans.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit357] +FileName=jpeglib\jerror.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit358] +FileName=jpeglib\jerror.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit359] +FileName=jpeglib\jfdctflt.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit360] +FileName=jpeglib\jfdctfst.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit361] +FileName=jpeglib\jfdctint.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit362] +FileName=jpeglib\jidctflt.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit363] +FileName=jpeglib\jidctfst.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit364] +FileName=jpeglib\jidctint.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit365] +FileName=jpeglib\jidctred.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit366] +FileName=jpeglib\jinclude.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit367] +FileName=jpeglib\jmemmgr.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit368] +FileName=jpeglib\jmemnobs.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit369] +FileName=jpeglib\jmemsys.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit370] +FileName=jpeglib\jmorecfg.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit371] +FileName=jpeglib\jpegint.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit372] +FileName=jpeglib\jpeglib.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit373] +FileName=jpeglib\jquant1.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit374] +FileName=jpeglib\jquant2.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit375] +FileName=jpeglib\jutils.c +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit376] +FileName=jpeglib\jversion.h +Folder=other_impl/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit377] +FileName=CMD3MeshFileLoader.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit378] +FileName=CMD3MeshFileLoader.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit379] +FileName=CAnimatedMeshMD3.h +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit380] +FileName=CAnimatedMeshMD3.cpp +Folder=scene_impl/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit381] +FileName=CGUISpriteBank.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit382] +FileName=CGUISpriteBank.cpp +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit383] +FileName=..\..\include\IGUIFontBitmap.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit384] +FileName=..\..\include\IGUISpriteBank.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit385] +FileName=COpenGLExtensionHandler.cpp +CompileCpp=1 +Folder=video_impl/OpenGL +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit386] +FileName=CGUISpinBox.h +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit387] +FileName=CGUISpinBox.cpp +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit388] +FileName=..\..\include\IGUISpinBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit389] +FileName=..\..\include\SViewFrustum.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit390] +FileName=..\..\include\triangle3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit391] +FileName=libpng\png.c +CompileCpp=0 +Folder=other_impl/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit392] +FileName=libpng\png.h +CompileCpp=1 +Folder=other_impl/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit393] +FileName=libpng\pngconf.h +CompileCpp=1 +Folder=other_impl/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit394] +FileName=libpng\pngerror.c +CompileCpp=0 +Folder=other_impl/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit395] +FileName=libpng\pngget.c +CompileCpp=0 +Folder=other_impl/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit396] +FileName=libpng\pngmem.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit397] +FileName=libpng\pngpread.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit398] +FileName=libpng\pngread.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit399] +FileName=libpng\pngrio.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit400] +FileName=libpng\pngrtran.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit401] +FileName=libpng\pngrutil.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit402] +FileName=libpng\pngset.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit403] +FileName=libpng\pngtrans.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit404] +FileName=libpng\pngwio.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit405] +FileName=libpng\pngwrite.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit406] +FileName=libpng\pngwtran.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit407] +FileName=libpng\pngwutil.c +Folder=other_impl/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit408] +FileName=CIrrDeviceLinux.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit409] +FileName=CIrrDeviceLinux.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit410] +FileName=CIrrDeviceStub.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit411] +FileName=CIrrDeviceStub.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit412] +FileName=CIrrDeviceWin32.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit413] +FileName=CIrrDeviceWin32.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit414] +FileName=CLogger.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit415] +FileName=CLogger.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit416] +FileName=COSOperator.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit417] +FileName=COSOperator.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit418] +FileName=CTimer.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit419] +FileName=IImagePresenter.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit420] +FileName=Irrlicht.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit421] +FileName=os.cpp +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit422] +FileName=os.h +Folder=other_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit423] +FileName=..\..\include\IrrCompileConfig.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit424] +FileName=CMeshCache.h +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit425] +FileName=CMeshCache.cpp +Folder=scene_impl/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit426] +FileName=COpenGLSLMaterialRenderer.h +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit427] +FileName=COpenGLSLMaterialRenderer.cpp +Folder=video_impl/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit428] +FileName=CSoftwareTexture2.h +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit429] +FileName=S4DVertex.h +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit430] +FileName=SoftwareDriver2_compile_config.h +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit431] +FileName=CSoftwareDriver2.h +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit432] +FileName=CTRTextureGouraudNoZ2.cpp +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit433] +FileName=CTRTextureLightMap2_M2.cpp +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit434] +FileName=CTRTextureLightMap2_M4.cpp +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit435] +FileName=CTRTextureLightMap2_M1.cpp +Folder=video_impl/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion=0.1 +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename=Irrlicht.dll +ProductName=Irrlicht +ProductVersion=0.1 +AutoIncBuildNr=0 + +[Unit436] +FileName=SoftwareDriver2_helper.h +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit437] +FileName=CSoftwareDriver2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit438] +FileName=CSoftwareTexture2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit439] +FileName=CTRTextureGouraud2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit440] +FileName=COgreMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit441] +FileName=COgreMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit442] +FileName=CDefaultSceneNodeFactory.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit443] +FileName=CDefaultSceneNodeAnimatorFactory.cpp +CompileCpp=1 +Folder=scene_impl/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit444] +FileName=CDefaultSceneNodeAnimatorFactory.h +CompileCpp=1 +Folder=scene_impl/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit445] +FileName=CDefaultSceneNodeFactory.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit446] +FileName=CAttributes.h +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit447] +FileName=CAttributeImpl.h +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit448] +FileName=CAttributes.cpp +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit449] +FileName=CCubeSceneNode.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit450] +FileName=CCubeSceneNode.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit451] +FileName=CTRTextureGouraudAddNoZ2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit452] +FileName=CTRTextureGouraudAdd2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit453] +FileName=CTRGouraud2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit454] +FileName=CTRGouraudAlpha2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit455] +FileName=CTRGouraudAlphaNoZ2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit456] +FileName=CTRTextureDetailMap2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit457] +FileName=CTRTextureLightMap2_Add.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit458] +FileName=CTRTextureWire2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit459] +FileName=CTRTextureGouraudVertexAlpha2.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit460] +FileName=..\..\changes.txt +CompileCpp=1 +Folder=doc +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit461] +FileName=..\..\readme.txt +CompileCpp=1 +Folder=doc +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit462] +FileName=CSphereSceneNode.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit463] +FileName=CSphereSceneNode.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit464] +FileName=CPakReader.h +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit465] +FileName=CPakReader.cpp +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit466] +FileName=CSkyDomeSceneNode.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit467] +FileName=CSkyDomeSceneNode.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit468] +FileName=CImageWriterTGA.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit469] +FileName=CImageWriterBMP.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit470] +FileName=CImageWriterBMP.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit471] +FileName=CImageWriterJPG.cpp +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=1 + +[Unit472] +FileName=CImageWriterJPG.h +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=1 + +[Unit473] +FileName=CImageWriterPCX.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit474] +FileName=CImageWriterPCX.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit475] +FileName=CImageWriterPNG.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit476] +FileName=CImageWriterPNG.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit477] +FileName=CImageWriterPPM.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit478] +FileName=CImageWriterPPM.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit479] +FileName=CImageWriterPSD.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit480] +FileName=CImageWriterPSD.h +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit481] +FileName=CImageWriterTGA.cpp +CompileCpp=1 +Folder=video_impl/Null +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit482] +FileName=CTRTextureLightMapGouraud2_M4.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit483] +FileName=CGUIColorSelectDialog.cpp +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit484] +FileName=IBurningShader.h +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit485] +FileName=IBurningShader.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit486] +FileName=IDepthBuffer.h +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit487] +FileName=CDepthBuffer.h +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit488] +FileName=CDepthBuffer.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit489] +FileName=CQuake3ShaderSceneNode.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit490] +FileName=CQuake3ShaderSceneNode.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit491] +FileName=..\..\include\fast_atof.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit492] +FileName=CTRTextureBlend.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit493] +FileName=CTRTextureGouraudAlpha.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit494] +FileName=CTRTextureGouraudAlphaNoZ.cpp +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit495] +FileName=CDefaultGUIElementFactory.cpp +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit496] +FileName=CDefaultGUIElementFactory.h +CompileCpp=1 +Folder=gui_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit497] +FileName=CGUIColorSelectDialog.h +Folder=gui_impl +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit498] +FileName=CSoftware2MaterialRenderer.h +CompileCpp=1 +Folder=video_impl/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit499] +FileName=CXMLReaderImpl.h +CompileCpp=1 +Folder=io_impl +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit500] +FileName=ITriangleRenderer.h +CompileCpp=1 +Folder=video_impl/Software +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit501] +FileName=..\..\include\EGUIElementTypes.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit502] +FileName=..\..\include\ESceneNodeAnimatorTypes.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit503] +FileName=..\..\include\ESceneNodeTypes.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit504] +FileName=..\..\include\ETerrainElements.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit505] +FileName=..\..\include\IAnimatedMeshMD2.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit506] +FileName=..\..\include\IAttributeExchangingObject.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit507] +FileName=..\..\include\IAttributes.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit508] +FileName=..\..\include\IDummyTransformationSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit509] +FileName=..\..\include\IGPUProgrammingServices.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit510] +FileName=..\..\include\IGUIColorSelectDialog.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit511] +FileName=..\..\include\IGUIComboBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit512] +FileName=..\..\include\IGUIContextMenu.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit513] +FileName=..\..\include\IGUIEditBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit514] +FileName=..\..\include\IGUIElementFactory.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit515] +FileName=..\..\include\IGUIInOutFader.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit516] +FileName=..\..\include\IGUIStaticText.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit517] +FileName=..\..\include\IGUITabControl.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit518] +FileName=..\..\include\IGUIToolbar.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit519] +FileName=..\..\include\IImage.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit520] +FileName=..\..\include\IImageLoader.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit521] +FileName=..\..\include\IImageWriter.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit522] +FileName=..\..\include\ILogger.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit523] +FileName=..\..\include\IMaterialRenderer.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit524] +FileName=..\..\include\IMaterialRendererServices.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit525] +FileName=..\..\include\IMeshCache.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit526] +FileName=..\..\include\IMeshLoader.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit527] +FileName=..\..\include\IMeshManipulator.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit528] +FileName=..\..\include\IMeshSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit529] +FileName=..\..\include\IMetaTriangleSelector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit530] +FileName=..\..\include\IOSOperator.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit531] +FileName=..\..\include\IParticleAffector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit532] +FileName=..\..\include\IParticleEmitter.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit533] +FileName=..\..\include\IParticleSystemSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit534] +FileName=..\..\include\IQ3Shader.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit535] +FileName=..\..\include\irrAllocator.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit536] +FileName=..\..\include\irrMap.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit537] +FileName=..\..\include\irrXML.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit538] +FileName=..\..\include\ISceneCollisionManager.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit539] +FileName=..\..\include\ISceneNodeAnimatorCollisionResponse.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit540] +FileName=..\..\include\ISceneNodeAnimatorFactory.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit541] +FileName=..\..\include\ISceneNodeFactory.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit542] +FileName=..\..\include\ISceneUserDataSerializer.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit543] +FileName=..\..\include\IShaderConstantSetCallBack.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit544] +FileName=..\..\include\IShadowVolumeSceneNode.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit545] +FileName=..\..\include\ITerrainSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit546] +FileName=..\..\include\ITextSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit547] +FileName=..\..\include\ITimer.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit548] +FileName=..\..\include\ITriangleSelector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit549] +FileName=..\..\include\IVideoModeList.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit550] +FileName=..\..\include\IWriteFile.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit551] +FileName=..\..\include\IXMLReader.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit552] +FileName=..\..\include\IXMLWriter.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit553] +FileName=..\..\include\quaternion.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit554] +FileName=..\..\include\SAnimatedMesh.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit555] +FileName=..\..\include\SceneParameters.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit556] +FileName=..\..\include\IReferenceCounted.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit557] +FileName=CParticleAnimatedMeshSceneNodeEmitter.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit558] +FileName=CParticleAnimatedMeshSceneNodeEmitter.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit559] +FileName=CParticleSphereEmitter.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit560] +FileName=CParticleAttractionAffector.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit561] +FileName=CParticleAttractionAffector.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit562] +FileName=CParticleCylinderEmitter.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit563] +FileName=CParticleCylinderEmitter.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit564] +FileName=CParticleMeshEmitter.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit565] +FileName=CParticleMeshEmitter.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit566] +FileName=CParticleRingEmitter.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit567] +FileName=CParticleRingEmitter.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit568] +FileName=CParticleRotationAffector.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit569] +FileName=CParticleRotationAffector.h +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit570] +FileName=CParticleSphereEmitter.cpp +CompileCpp=1 +Folder=scene_impl/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit571] +FileName=CIrrMeshWriter.h +CompileCpp=1 +Folder=scene_impl/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit572] +FileName=CIrrMeshWriter.cpp +CompileCpp=1 +Folder=scene_impl/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit573] +FileName=CColladaMeshWriter.h +CompileCpp=1 +Folder=scene_impl/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit574] +FileName=CColladaMeshWriter.cpp +CompileCpp=1 +Folder=scene_impl/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit575] +FileName=CIrrMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit576] +FileName=CIrrMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit577] +FileName=CBSPMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit578] +FileName=CBSPMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit579] +FileName=CMD2MeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit580] +FileName=CMD2MeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit581] +FileName=CMS3DMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit582] +FileName=CMS3DMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit583] +FileName=CB3DMeshFileLoader.h +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit584] +FileName=CB3DMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit585] +FileName=CSkinnedMesh.h +CompileCpp=1 +Folder=scene_impl/mesh +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit586] +FileName=CSkinnedMesh.cpp +CompileCpp=1 +Folder=scene_impl/mesh +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit587] +FileName=CBoneSceneNode.h +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit588] +FileName=CBoneSceneNode.cpp +CompileCpp=1 +Folder=scene_impl/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit589] +FileName=CSTLMeshWriter.cpp +CompileCpp=1 +Folder=scene_impl/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit590] +FileName=CSTLMeshFileLoader.cpp +CompileCpp=1 +Folder=scene_impl/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit591] +FileName=CImageLoaderPPM.cpp +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit592] +FileName=CImageLoaderPPM.h +Folder=video_impl/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/dep/src/irrlicht/Irrlicht.dsp b/src/dep/src/irrlicht/Irrlicht.dsp new file mode 100644 index 0000000..f0db08c --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht.dsp @@ -0,0 +1,2365 @@ +# Microsoft Developer Studio Project File - Name="Irrlicht" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Irrlicht - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "Irrlicht.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "Irrlicht.mak" CFG="Irrlicht - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "Irrlicht - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Irrlicht - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Irrlicht - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "..\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IRRLICHT_EXPORTS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IRRLICHT_EXPORTS" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "NDEBUG" +# ADD RSC /l 0xc07 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "Irrlicht - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "..\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IRRLICHT_EXPORTS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /I "zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IRRLICHT_EXPORTS" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Irrlicht - Win32 Release" +# Name "Irrlicht - Win32 Debug" +# Begin Group "include" + +# PROP Default_Filter "" +# Begin Group "video" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\EDriverTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGPUProgrammingServices.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ITexture.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IVideoDriver.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\S3DVertex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SColor.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SLight.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SMaterial.h +# End Source File +# End Group +# Begin Group "core" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\aabbox3d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\dimension2d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\heapsort.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrAllocator.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrArray.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrList.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrMath.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrString.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\line2d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\line3d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\matrix4.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\plane3d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\position2d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\rect.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\vector2d.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\vector3d.h +# End Source File +# End Group +# Begin Group "io" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\IFileList.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IFileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IReadFile.H +# End Source File +# End Group +# Begin Group "scene" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\IAnimatedMesh.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IAnimatedMeshSceneNode.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IBillboardSceneNode.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ICameraSceneNode.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ILightSceneNode.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IMesh.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IMeshBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IQ3LevelMesh.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ISceneManager.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ISceneNode.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ISceneNodeAnimator.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SMesh.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SMeshBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SMeshBufferLightMap.h +# End Source File +# End Group +# Begin Group "gui" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\ICursorControl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIButton.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUICheckbox.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIElement.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIEnvironment.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIFileOpenDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIFont.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIImage.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIListBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIMeshViewer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIScrollBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUISkin.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IGUIWindow.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\include\IEventReceiver.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IReferenceCounted.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Irrlicht.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\IrrlichtDevice.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\irrTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Keycodes.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SIrrCreationParameters.h +# End Source File +# End Group +# Begin Group "gui_impl" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BuiltInFont.h +# End Source File +# Begin Source File + +SOURCE=.\CDefaultGUIElementFactory.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDefaultGUIElementFactory.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIButton.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIButton.h +# End Source File +# Begin Source File + +SOURCE=.\CGUICheckBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUICheckbox.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIColorSelectDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIColorSelectDialog.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIComboBox.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIContextMenu.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIEditBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIEditBox.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIEnvironment.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIEnvironment.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIFileOpenDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIFileOpenDialog.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIFont.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIFont.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIImage.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIImage.H +# End Source File +# Begin Source File + +SOURCE=.\CGUIInOutFader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIInOutFader.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIListBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIListBox.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIMenu.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIMeshViewer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIMeshViewer.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIMessageBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIMessageBox.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIModalScreen.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIModalScreen.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIScrollBar.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIScrollBar.h +# End Source File +# Begin Source File + +SOURCE=.\CGUISkin.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUISkin.h +# End Source File +# Begin Source File + +SOURCE=.\CGUISpriteBank.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUISpriteBank.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIStaticText.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIStaticText.h +# End Source File +# Begin Source File + +SOURCE=.\CGUITabControl.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUITabControl.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIToolBar.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIToolBar.h +# End Source File +# Begin Source File + +SOURCE=.\CGUIWindow.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUIWindow.h +# End Source File +# Begin Source File + +SOURCE=.\GUIIcons.h +# End Source File +# End Group +# Begin Group "video_impl" + +# PROP Default_Filter "" +# Begin Group "Software" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CSoftwareDriver.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareDriver.h +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareTexture.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareTexture.h +# End Source File +# Begin Source File + +SOURCE=.\CTRFlat.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRFlatWire.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRGouraud.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRGouraudWire.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureFlat.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureFlatWire.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraud.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraud.h +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudAdd.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudNoZ.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudWire.cpp +# End Source File +# Begin Source File + +SOURCE=.\CZBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CZBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\ITriangleRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\IZBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\S2DVertex.h +# End Source File +# End Group +# Begin Group "OpenGL" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\COpenGLDriver.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLDriver.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLExtensionHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLExtensionHandler.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLNormalMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLNormalMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLParallaxMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLParallaxMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLShaderMaterialRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLShaderMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLSLMaterialRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLSLMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\COpenGLTexture.cpp +# End Source File +# Begin Source File + +SOURCE=.\COpenGLTexture.h +# End Source File +# Begin Source File + +SOURCE=.\glext.h +# End Source File +# End Group +# Begin Group "DirectX8" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CD3D8Driver.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D8Driver.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D8MaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D8NormalMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D8NormalMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D8ParallaxMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D8ParallaxMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D8ShaderMaterialRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D8ShaderMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D8Texture.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D8Texture.h +# End Source File +# End Group +# Begin Group "Null" + +# PROP Default_Filter "" +# Begin Group "ImageWriter" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CImageWriterBMP.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterBMP.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterJPG.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterJPG.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPCX.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPCX.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPNG.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPNG.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPPM.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPPM.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPSD.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterPSD.h +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterTGA.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageWriterTGA.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\CColorConverter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CColorConverter.h +# End Source File +# Begin Source File + +SOURCE=.\CFPSCounter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CFPSCounter.h +# End Source File +# Begin Source File + +SOURCE=.\CImage.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImage.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderBMP.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderBMP.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderJPG.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderJPG.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPCX.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPCX.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPNG.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPNG.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPSD.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPSD.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderTGA.cpp +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderTGA.h +# End Source File +# Begin Source File + +SOURCE=.\CNullDriver.cpp +# End Source File +# Begin Source File + +SOURCE=.\CNullDriver.h +# End Source File +# End Group +# Begin Group "DirectX9" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CD3D9Driver.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9Driver.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9HLSLMaterialRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9HLSLMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9MaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9NormalMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9NormalMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9ParallaxMapRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9ParallaxMapRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9ShaderMaterialRenderer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9ShaderMaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CD3D9Texture.cpp +# End Source File +# Begin Source File + +SOURCE=.\CD3D9Texture.h +# End Source File +# End Group +# Begin Group "Software2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CDepthBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDepthBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\CSoftware2MaterialRenderer.h +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareDriver2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareDriver2.h +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareTexture2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSoftwareTexture2.h +# End Source File +# Begin Source File + +SOURCE=.\CTRGouraud2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRGouraudAlpha2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRGouraudAlphaNoZ2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureBlend.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureDetailMap2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraud2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudAdd2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudAddNoZ2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudAlpha.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudAlphaNoZ.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudNoZ2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureGouraudVertexAlpha2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMap2_Add.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMap2_M1.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMap2_M1.h +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMap2_M2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMap2_M4.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureLightMapGouraud2_M4.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTRTextureWire2.cpp +# End Source File +# Begin Source File + +SOURCE=.\IBurningShader.cpp +# End Source File +# Begin Source File + +SOURCE=.\IBurningShader.h +# End Source File +# Begin Source File + +SOURCE=.\IDepthBuffer.h +# End Source File +# Begin Source File + +SOURCE=.\S4DVertex.h +# End Source File +# Begin Source File + +SOURCE=.\SoftwareDriver2_compile_config.h +# End Source File +# Begin Source File + +SOURCE=.\SoftwareDriver2_helper.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\CVideoModeList.cpp +# End Source File +# Begin Source File + +SOURCE=.\CVideoModeList.h +# End Source File +# End Group +# Begin Group "scene_impl" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\C3DSMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\C3DSMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshMD2.cpp +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshMD2.h +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshMD3.cpp +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshMD3.h +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CAnimatedMeshSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CB3DMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CB3DMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CBillboardSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CBillboardSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CBoneSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CBoneSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CBSPMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CBSPMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CCameraFPSSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCameraFPSSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CCameraMayaSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCameraMayaSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CCameraSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCameraSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CColladaFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CColladaFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CColladaMeshWriter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCSMLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCSMLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CCubeSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CCubeSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CDefaultSceneNodeAnimatorFactory.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDefaultSceneNodeAnimatorFactory.h +# End Source File +# Begin Source File + +SOURCE=.\CDefaultSceneNodeFactory.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDefaultSceneNodeFactory.h +# End Source File +# Begin Source File + +SOURCE=.\CDMFLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDMFLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CDummyTransformationSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CDummyTransformationSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CEmptySceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CEmptySceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CGeometryCreator.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGeometryCreator.h +# End Source File +# Begin Source File + +SOURCE=.\CGUISpinBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\CGUISpinBox.h +# End Source File +# Begin Source File + +SOURCE=.\CImageLoaderPPM.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceSDL.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceSDL.h +# End Source File +# Begin Source File + +SOURCE=.\CIrrMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrMeshWriter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CLightSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CLightSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CLMTSMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CLMTSMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CMD2MeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMD2MeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CMD3MeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMD3MeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CMeshCache.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMeshCache.h +# End Source File +# Begin Source File + +SOURCE=.\CMeshManipulator.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMeshManipulator.h +# End Source File +# Begin Source File + +SOURCE=.\CMeshSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMeshSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CMetaTriangleSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMetaTriangleSelector.h +# End Source File +# Begin Source File + +SOURCE=.\CMS3DMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMS3DMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CMY3DHelper.h +# End Source File +# Begin Source File + +SOURCE=.\CMY3DMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMY3DMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CMY3DStuff.h +# End Source File +# Begin Source File + +SOURCE=.\COBJMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\COBJMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\COCTLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\COCTLoader.h +# End Source File +# Begin Source File + +SOURCE=.\COctTreeSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\COctTreeSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\COctTreeTriangleSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\COctTreeTriangleSelector.h +# End Source File +# Begin Source File + +SOURCE=.\COgreMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\COgreMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleAnimatedMeshSceneNodeEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleAnimatedMeshSceneNodeEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleAttractionAffector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleAttractionAffector.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleBoxEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleBoxEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleCylinderEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleCylinderEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleFadeOutAffector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleFadeOutAffector.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleGravityAffector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleGravityAffector.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleMeshEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleMeshEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticlePointEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticlePointEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleRingEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleRingEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleRotationAffector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleRotationAffector.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleSphereEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleSphereEmitter.h +# End Source File +# Begin Source File + +SOURCE=.\CParticleSystemSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CParticleSystemSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CQ3LevelMesh.cpp +# End Source File +# Begin Source File + +SOURCE=.\CQ3LevelMesh.h +# End Source File +# Begin Source File + +SOURCE=.\CQuake3ShaderSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CQuake3ShaderSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneCollisionManager.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneCollisionManager.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneManager.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneManager.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorCollisionResponse.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorCollisionResponse.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorDelete.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorDelete.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFlyCircle.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFlyCircle.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFlyStraight.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFlyStraight.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFollowSpline.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorFollowSpline.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorRotation.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorRotation.h +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorTexture.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSceneNodeAnimatorTexture.h +# End Source File +# Begin Source File + +SOURCE=.\CShadowVolumeSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CShadowVolumeSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CSkinnedMesh.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSkinnedMesh.h +# End Source File +# Begin Source File + +SOURCE=.\CSkyBoxSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSkyBoxSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CSkyDomeSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSkyDomeSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CSphereSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSphereSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CSTLMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CSTLMeshWriter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTerrainSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTerrainSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CTerrainTriangleSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTerrainTriangleSelector.h +# End Source File +# Begin Source File + +SOURCE=.\CTextSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTextSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CTriangleBBSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTriangleBBSelector.h +# End Source File +# Begin Source File + +SOURCE=.\CTriangleSelector.cpp +# End Source File +# Begin Source File + +SOURCE=.\CTriangleSelector.h +# End Source File +# Begin Source File + +SOURCE=.\CWaterSurfaceSceneNode.cpp +# End Source File +# Begin Source File + +SOURCE=.\CWaterSurfaceSceneNode.h +# End Source File +# Begin Source File + +SOURCE=.\CXMeshFileLoader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CXMeshFileLoader.h +# End Source File +# Begin Source File + +SOURCE=.\dmfsupport.h +# End Source File +# Begin Source File + +SOURCE=.\OctTree.h +# End Source File +# End Group +# Begin Group "io_impl" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CAttributeImpl.h +# End Source File +# Begin Source File + +SOURCE=.\CAttributes.cpp +# End Source File +# Begin Source File + +SOURCE=.\CAttributes.h +# End Source File +# Begin Source File + +SOURCE=.\CFileList.cpp +# End Source File +# Begin Source File + +SOURCE=.\CFileList.h +# End Source File +# Begin Source File + +SOURCE=.\CFileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=.\CFileSystem.h +# End Source File +# Begin Source File + +SOURCE=.\CLimitReadFile.cpp +# End Source File +# Begin Source File + +SOURCE=.\CLimitReadFile.h +# End Source File +# Begin Source File + +SOURCE=.\CMemoryReadFile.cpp +# End Source File +# Begin Source File + +SOURCE=.\CMemoryReadFile.h +# End Source File +# Begin Source File + +SOURCE=.\CPakReader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CPakReader.h +# End Source File +# Begin Source File + +SOURCE=.\CReadFile.cpp +# End Source File +# Begin Source File + +SOURCE=.\CReadFile.h +# End Source File +# Begin Source File + +SOURCE=.\CWriteFile.cpp +# End Source File +# Begin Source File + +SOURCE=.\CWriteFile.h +# End Source File +# Begin Source File + +SOURCE=.\CXMLReader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CXMLReader.h +# End Source File +# Begin Source File + +SOURCE=.\CXMLReaderImpl.h +# End Source File +# Begin Source File + +SOURCE=.\CXMLWriter.cpp +# End Source File +# Begin Source File + +SOURCE=.\CXMLWriter.h +# End Source File +# Begin Source File + +SOURCE=.\CZipReader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CZipReader.h +# End Source File +# Begin Source File + +SOURCE=.\irrXML.cpp +# End Source File +# End Group +# Begin Group "other_impl" + +# PROP Default_Filter "" +# Begin Group "extern" + +# PROP Default_Filter "" +# Begin Group "zlib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\zlib\adler32.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\compress.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\crc32.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\crc32.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\deflate.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\inffast.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\inflate.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\inftrees.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\trees.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\trees.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\uncompr.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zlib\zutil.c +# End Source File +# Begin Source File + +SOURCE=.\zlib\zutil.h +# End Source File +# End Group +# Begin Group "jpeglib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\jpeglib\cderror.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\cdjpeg.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\cdjpeg.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcapimin.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcapistd.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jccoefct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jccolor.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcdctmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jchuff.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jchuff.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcinit.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcmainct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcmarker.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcmaster.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcomapi.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jconfig.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcparam.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcphuff.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcprepct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jcsample.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jctrans.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdapimin.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdapistd.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdatadst.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdatasrc.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdcoefct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdcolor.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdct.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jddctmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdhuff.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdhuff.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdinput.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdmainct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdmarker.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdmaster.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdmerge.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdphuff.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdpostct.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdsample.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jdtrans.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jerror.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jerror.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jfdctflt.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jfdctfst.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jfdctint.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jidctflt.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jidctfst.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jidctint.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jidctred.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jinclude.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jmemmgr.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jmemnobs.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jmemsys.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jmorecfg.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jpegint.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jpeglib.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jquant1.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jquant2.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jutils.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\jversion.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdbmp.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdcolmap.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdgif.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdppm.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdrle.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdswitch.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\rdtarga.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\transupp.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\transupp.h +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\wrbmp.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\wrgif.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\wrppm.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\wrrle.c +# End Source File +# Begin Source File + +SOURCE=.\jpeglib\wrtarga.c +# End Source File +# End Group +# Begin Group "libpng" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\libpng\png.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\png.h +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngconf.h +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngerror.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngget.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngmem.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngpread.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngread.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngrio.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngrtran.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngrutil.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngset.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngtrans.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngwio.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngwrite.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngwtran.c +# End Source File +# Begin Source File + +SOURCE=.\libpng\pngwutil.c +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\CIrrDeviceLinux.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceLinux.h +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceStub.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceStub.h +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceWin32.cpp +# End Source File +# Begin Source File + +SOURCE=.\CIrrDeviceWin32.h +# End Source File +# Begin Source File + +SOURCE=.\CLogger.cpp +# End Source File +# Begin Source File + +SOURCE=.\CLogger.h +# End Source File +# Begin Source File + +SOURCE=.\COSOperator.cpp +# End Source File +# Begin Source File + +SOURCE=.\COSOperator.h +# End Source File +# Begin Source File + +SOURCE=.\CTimer.h +# End Source File +# Begin Source File + +SOURCE=.\fast_atof.h +# End Source File +# Begin Source File + +SOURCE=.\IImagePresenter.h +# End Source File +# Begin Source File + +SOURCE=.\Irrlicht.cpp +# End Source File +# Begin Source File + +SOURCE=.\os.cpp +# End Source File +# Begin Source File + +SOURCE=.\os.h +# End Source File +# End Group +# Begin Group "doc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\changes.txt +# End Source File +# End Group +# Begin Source File + +SOURCE=.\glxext.h +# End Source File +# End Target +# End Project diff --git a/src/dep/src/irrlicht/Irrlicht.dsw b/src/dep/src/irrlicht/Irrlicht.dsw new file mode 100644 index 0000000..99cd376 --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! + +############################################################################### + +Project: "Irrlicht"=.\Irrlicht.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/dep/src/irrlicht/Irrlicht.opt b/src/dep/src/irrlicht/Irrlicht.opt new file mode 100644 index 0000000000000000000000000000000000000000..7074c532dc7ad5851fc6bb41e10ff9bf8cab925d GIT binary patch literal 53760 zcmeHQ%X{0#5r-_x7G=wkWW{#uv_YK4ksp%v$jeUbR3;@?j%2B(QYWoi2LzYY+91FH zpk&3L|BoKpL(lD{|3Xi_wYm3@9-Cf!>%;xc;z3fTmXs)ewcUZf5lLWnX7)F`i^Tvt z`17BJzx~bcPyf}}wp}-RjsHB!7>646_uxB`+J+1qfAWOBC!h2kyLfwn5coH2HQ~2j z&_Pfih_OSpM!|+9zMSWS)c;Q1{Fa9R05Sj#P_VXJBEk9 z&@fSR7oWbd1hyFhH#~!Lz!g?3ledB=<7*$|lqyDCmhaDD( zuxPiL#sSqvsqK;-?fB`qvXdGswj0py8Jo~A@NM_oka3`=7sYx&o$5bIYGVC!@VZ1@ z35C6E$Dp73E9s`K6B#FnDc0Wu|B>ze()S%{uZOeQt7|#2Asnw-5pKAa>>r<+csKpA z7I-z^7HbP}q4di{F{qL_-WUN!fDvE>7y(9r5nu!u0Y-okU<4QeM&LO_z!zc7cg;KM zBQPz~kwIw6Q218p`DWFVZYbTd8G2^8F3f@`OV{*D>Ibn-3=U+no*RSQIb=6#je;UeDhifQ>;&Bg5I^BjRi?Psqsvcvi z!=(nFgZY;ttjyJOiCJkk=&j$;;key%I4-kEi~u9R2rvSS03*N%FanGKBftnS0*t_Z zBCw0N8pr=S43s7T$mReR$NzMJsBRxXYz|;?{Ey>*;dAr+U#s=kcd;Vb z#kyo#7u{|LS&#P!dj&K6dm2gn*Au?Bt9Fp)c8SNQL`{tFHId$Inz zKUv0o_)|Q>8wj`W$^wEG~Xny0%j*ih;luuDB;FRVT7(4?CiQ&4%sX+gySXU<4QeMt~7u z1Q-EEfDvE>7y(9r5qPl?;P@}cf7MF=^!du27Rt9=RDF{c>+|~W7jOOdm)}LXD^Dar zIdj~+E8UrCGbakQ^3h~>l-RM~$f|gq9qzz?D&bGX+`-CrD^RICcPK;YIKS(o)#vo> zpXwV8ric1R^Z6Thut5EYkzKWXv`nnRuk0YDp+pil>_O&QW$#Vjt5suheH*eUyw->M zM{~FC9<)7QXpSF{y3&0rR;el8TdqmX;XY+UKbTa!Q^Pr+DzYh7m&mWsk|C;YTc+Eehmk9W}B!0nZnOYj5H1WN1lO_;Cjrk-l$xm8x`v?YSjco>=cey61)x^Ei|+ zBM(Usz{dseVac(|fsQ#N9j{y#zK-W;=u68jJ7T7&V>>3%LttgWgJK=yATb72>9*k; zCB8TbN6E60^Jc59*wFKwf~Bp_ptM5Ns89=q7Mi2-Va4%|1LeucH;(5A0MrhP(t_W0l9drbXob=a(V29t zuh#(;5AAg{6=Wsy3iqK$S8PPo-5YLI_0FJN$Z&^F-f&b$m&`>bo|=w#NL0vaK%s39 z85TufZV105ETm&6A;o6N zuLWVPqGLP`??tV`r-9hlyXVYP+(=@yA#HsVd0htUGytG;qj$MsAVS-6FlO0WuVo6D zu!Vtk06tPe8mN1?Vkqe4c8pd{JkJ>JV_=@%fK3oT-Z3Tv8!E@{UI_JDrXNy{i=eHF< ztZJuHmkEq8TC~-x}K0>znH1Ujb*=fzp1P{bk zn{j$b>Fvm~Z_AV|LDlw9y8ulCXWc3qh}QNqPnYjt&WLs!)i_nI^ZYv!9>jzQSI-T@ zLt0c+WC(FO2`5qs)Q&qSa5^nO(?-l5Eev!t71n7vl@pg&>u&Fq&e$QJznov9dxKygZkM8)0;9fVroZ`lNce; zg5nFzPEH;;?a`?&9UO2<$CO*!AEH@D`x(#aNOTSJIGR)90~ZMLYrXJMI|v=BG|iOT z&uoTlnlPs)F&*-w32SGPM{UByDq5XMA4=?Qk4r|nxJ(MQ}?O7bBdqSeel`eg`z zYkf6rtLbS3WVNcDuQvu+qVHWK3@r#uMTGgk&lnmRvb&U_`A-*-@b@-m;1|@R@#Zy^ zu(ZCLGWlj`dN_W4E;_k`B|gpLSpDdVFE(&Uh7;MEkISHN{5tK5d1T2P+kS}hmS!^B z_l{q`jd7dofYK%n@&0-NWn2Acq_AExleu^?k6zf)1oPT8Gs;!0tWaMYiZ&)Mp7YV8 z8*|K}gvwvsCZnv%&KqMEwGPbo9fwlD;wl;!p=sLKZ8z*_Zt+y6W|vTjfv18C36qjF zmi(j?v1vls%a_fdhA15#(oe!G$Z0DBNn^lG$_wC7q_~mMy=4vGx-fMj8^8 zW>oLwCmM*lZwI$EA4nb8(1e=(_lU%15+^n`32HQ|oxr1+jBo-$pAml}AGOuA=`|i` z6hK8~X`2=59$H-}{RBXbBI16Kp_JG<8%R~!h<6e|B5=Ko8FzyYRl|A-a**0JKHks) z;#T$)wo#^T#DF$1R9{sts`vj3Q7<8BjXSB9w6BJnOR0*-*h7DhO|&7k*oICiRm&D= zYd(N~{M3G&)2PH-;Fcx&Mz?;{=8wtaJ;uoNuX>GB{l7c-;jceC7`J$(rG+Ev-T4uL z#LXcYiC>21FoC%6H-_=eKhPeG;ix^J@u=6_wS1kOy5+f+opqyl%o1i!d7A&xxsHUL z9XQ+hyYXUSH)e7qhwhmyM$xUk3X+K2d6r-7-XugHx)+jP*`Io4(cyh-ekI?vNs*)_ zYs=avQQeD)Cdu79Kbv3buJvSVg;qW{cHf|LqGZ*aFvVs*zFW4(W}RD_@2+M!3h%8p zh4)h1_S$LZD%EhSYbiH{hYL=BD~lU@6h+x1LN`BK$m0g)4czG5ql5+D$16Q?w;-Qe z+^dX5SzfO@ea}*sR`dHaY%Jxb_e;>sJ_*7wpH*ScJ-Ug^SVFWfxoOaan6BII5+Wt5 zaik=VsiO)5?$x0Dew_oCzSu8G%QtTAkJp#8tKE%X%XYYmuxZyGi{)0WG=*dK&e z;y8B8Y1LdDmEB|0N@b_P$k`-j-K9hfxBFyUHV#1Vlel@r=9g>XKGidM{;&1ht2
  • TBre24B1)?ge}PuLt@6XzA^fCu*5()(PgFV&3rzX;Q%Fd)#8{7y(9r5nu!u0Y-ok zU<4QeMt~7u1Q-EEpmPK`{)Yf4um5eksGQgTzFg~nb9m=S!KfK!{0Y2)Ww+bN9^QYl zN=oAQpXBhC85{a5(C*^BFTpMi7{&W%`cbA2)amaSXW46Rd8+y6bo0-d=AZ8-woy!(H%5RFU<4QeMt~7u1Q-EE zfDvE>7y(9r5qQ23;P@}ce>wl7dLcr?!<;XF{>MXj`V+CbJ_BLDUp5U%*~{6B>P^{A zd!OBp3lKdEI@$1gTEyv-WUN!fDvE> j7y(9r5nu!u0Y-okU<4R}7Zw4I|8e|} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dep/src/irrlicht/Irrlicht8.0.sln b/src/dep/src/irrlicht/Irrlicht8.0.sln new file mode 100644 index 0000000..e7ed80f --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht8.0.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht8", "Irrlicht8.0.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/dep/src/irrlicht/Irrlicht8.0.vcproj b/src/dep/src/irrlicht/Irrlicht8.0.vcproj new file mode 100644 index 0000000..6ec210a --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht8.0.vcproj @@ -0,0 +1,2815 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dep/src/irrlicht/Irrlicht_Win32-gcc.cbp b/src/dep/src/irrlicht/Irrlicht_Win32-gcc.cbp new file mode 100644 index 0000000..ae47fef --- /dev/null +++ b/src/dep/src/irrlicht/Irrlicht_Win32-gcc.cbp @@ -0,0 +1,854 @@ + + + + + + diff --git a/src/dep/src/irrlicht/MacOSX/._MainMenu.nib b/src/dep/src/irrlicht/MacOSX/._MainMenu.nib new file mode 100644 index 0000000000000000000000000000000000000000..ed1f83f526c3bfce391640bdb42087b9c7a3cf0f GIT binary patch literal 82 jcmZQz6=P>$V!#9-F-{;h0%8Rq2JwS{7y$$jOk@@SDyIPE literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/MacOSX/AppDelegate.h b/src/dep/src/irrlicht/MacOSX/AppDelegate.h new file mode 100644 index 0000000..5599032 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/AppDelegate.h @@ -0,0 +1,16 @@ +// Copyright (C) 2005 Etienne Petitjean +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#import +#import "CIrrDeviceMacOSX.h" + +@interface AppDelegate : NSObject +{ + BOOL _quit; + irr::CIrrDeviceMacOSX *_device; +} + +- (id)initWithDevice:(irr::CIrrDeviceMacOSX *)device; + +@end diff --git a/src/dep/src/irrlicht/MacOSX/AppDelegate.mm b/src/dep/src/irrlicht/MacOSX/AppDelegate.mm new file mode 100644 index 0000000..18711f6 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/AppDelegate.mm @@ -0,0 +1,61 @@ +// Copyright (C) 2005 Etienne Petitjean +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (id)initWithDevice:(irr::CIrrDeviceMacOSX *)device +{ + self = [super init]; + if (self) _device = device; + return (self); +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + _quit = FALSE; +} + +- (void)orderFrontStandardAboutPanel:(id)sender +{ + [NSApp orderFrontStandardAboutPanel:sender]; +} + +- (void)unhideAllApplications:(id)sender +{ + [NSApp unhideAllApplications:sender]; +} + +- (void)hide:(id)sender +{ + [NSApp hide:sender]; +} + +- (void)hideOtherApplications:(id)sender +{ + [NSApp hideOtherApplications:sender]; +} + +- (void)terminate:(id)sender +{ + _quit = TRUE; +} + +- (void)windowDidResize:(NSNotification *)aNotification +{ + NSWindow *window; + NSRect frame; + + window = [aNotification object]; + frame = [window frame]; + _device->setResize((int)frame.size.width,(int)frame.size.height); +} + +- (BOOL)isQuit +{ + return (_quit); +} + +@end diff --git a/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.h b/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.h new file mode 100644 index 0000000..9808f88 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.h @@ -0,0 +1,214 @@ +// Copyright (C) 2005 Etienne Petitjean +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__ +#define __C_IRR_DEVICE_MACOSX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef MACOSX + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "IGUIEnvironment.h" +#include "ICursorControl.h" + +#include +#include + +namespace irr +{ + class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, bool fullscreen, + bool sbuffer, bool vsync, + bool antiAlias, IEventReceiver* receiver, + const char* version); + + //! destructor + virtual ~CIrrDeviceMacOSX(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! presents a surface in the client area + virtual void present(video::IImage* surface, s32 windowId = 0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! Sets if the window should be resizeable in windowed mode. + virtual void setResizeAble(bool resize); + + void flush(); + void setMouseLocation(int x,int y); + void setResize(int width,int height); + void setCursorVisible(bool visible); + + private: + + //! create the driver + void createDriver(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, u32 bits, bool fullscreen, + bool stencilbuffer, bool vsync, bool antiAlias); + + //! Implementation of the macos x cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(const core::dimension2d& wsize, CIrrDeviceMacOSX *device) : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), _device(device), UseReferenceRect(false) + { + CursorPos.X = CursorPos.Y = 0; + if (WindowSize.Width!=0) InvWindowSize.Width = 1.0f / WindowSize.Width; + if (WindowSize.Height!=0) InvWindowSize.Height = 1.0f / WindowSize.Height; + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + _device->setCursorVisible(visible); + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + if (CursorPos.X != pos.X || CursorPos.Y != pos.Y) + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + if (UseReferenceRect) + { + _device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y); + } + else + { + _device->setMouseLocation(x,y); + } + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getPosition() + { + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + //! Updates the internal cursor position + void updateInternalCursorPosition(int x,int y) + { + CursorPos.X = x; + CursorPos.Y = y; + } + + private: + + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + CIrrDeviceMacOSX *_device; + bool IsVisible; + bool UseReferenceRect; + core::rect ReferenceRect; + }; + + bool createWindow(const irr::core::dimension2d& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer); + void initKeycodes(); + void storeMouseLocation(); + void postMouseEvent(void *event,irr::SEvent &ievent); + void postKeyEvent(void *event,irr::SEvent &ievent,bool pressed); + + video::E_DRIVER_TYPE DriverType; + bool stencilbuffer; + + void *_window; + CGLContextObj _cglcontext; + void *_oglcontext; + int _width; + int _height; + std::map _keycodes; + int _screenWidth; + int _screenHeight; + bool _active; + }; + + +} // end namespace irr + +#endif // MACOSX +#endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__ + diff --git a/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.mm b/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.mm new file mode 100644 index 0000000..6e78cd2 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/CIrrDeviceMacOSX.mm @@ -0,0 +1,629 @@ +// Copyright (C) 2005 Etienne Petitjean +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifdef MACOSX + +#import +#import + +#include "CIrrDeviceMacOSX.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include +#include +#include "COSOperator.h" +#include "irrlicht.h" +#import +#import +#import "AppDelegate.h" + +namespace irr +{ + namespace video + { + IVideoDriver* createOpenGLDriver(const core::dimension2d& screenSize, CIrrDeviceMacOSX *device, bool fullscreen, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias); + } +} // end namespace irr + +static bool firstLaunch = true; + +namespace irr +{ +//! constructor +CIrrDeviceMacOSX::CIrrDeviceMacOSX(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, bool fullscreen, + bool sbuffer, bool vsync, + bool antiAlias, IEventReceiver* receiver, + const char* version) + : CIrrDeviceStub(version, receiver), DriverType(driverType), stencilbuffer(sbuffer), _window(NULL), _active(true), _oglcontext(NULL), _cglcontext(NULL) +{ + struct utsname name; + NSString *path; + + #ifdef _DEBUG + setDebugName("CIrrDeviceMacOSX"); + #endif + + if (firstLaunch) + { + firstLaunch = false; + + [[NSAutoreleasePool alloc] init]; + [NSApplication sharedApplication]; + [NSApp setDelegate:[[[AppDelegate alloc] initWithDevice:this] autorelease]]; + [NSBundle loadNibNamed:@"MainMenu" owner:[NSApp delegate]]; + [NSApp finishLaunching]; + + path = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent]; + chdir([path cString]); + } + + uname(&name); + Operator = new COSOperator(name.version); + os::Printer::log(name.version,ELL_INFORMATION); + + initKeycodes(); + if (driverType != video::EDT_NULL) createWindow(windowSize,bits,fullscreen,vsync,stencilbuffer); + CursorControl = new CCursorControl(windowSize, this); + createDriver(driverType,windowSize,bits,fullscreen,stencilbuffer,vsync,antiAlias); + createGUIAndScene(); +} + +CIrrDeviceMacOSX::~CIrrDeviceMacOSX() +{ + closeDevice(); +} + +void CIrrDeviceMacOSX::closeDevice() +{ + if (_window != NULL) + { + [_window setIsVisible:FALSE]; + + if (_oglcontext != NULL) + { + [_oglcontext clearDrawable]; + [_oglcontext release]; + _oglcontext = NULL; + } + + [_window setReleasedWhenClosed:TRUE]; + [_window release]; + _window = NULL; + } + else + { + if (_cglcontext != NULL) + { + CGLSetCurrentContext(NULL); + CGLClearDrawable(_cglcontext); + CGLDestroyContext(_cglcontext); + } + } + + _active = FALSE; + _cglcontext = NULL; +} + +bool CIrrDeviceMacOSX::createWindow(const irr::core::dimension2d& windowSize, irr::u32 bits, bool fullscreen, bool vsync, bool stencilBuffer) +{ + int index; + CGDisplayErr error; + bool result; + NSOpenGLPixelFormat *format; + CGDirectDisplayID display; + CGLPixelFormatObj pixelFormat; + CGRect displayRect; + CGLPixelFormatAttribute fullattribs[32]; + NSOpenGLPixelFormatAttribute windowattribs[32]; + CFDictionaryRef displaymode,olddisplaymode; + long numPixelFormats,newSwapInterval; + + result = false; + display = CGMainDisplayID(); + _screenWidth = (int) CGDisplayPixelsWide(display); + _screenHeight = (int) CGDisplayPixelsHigh(display); + + if (!fullscreen) + { + _window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,windowSize.Width,windowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:NSBackingStoreBuffered defer:FALSE]; + if (_window != NULL) + { + index = 0; + windowattribs[index++] = NSOpenGLPFANoRecovery; + windowattribs[index++] = NSOpenGLPFADoubleBuffer; + windowattribs[index++] = NSOpenGLPFAAccelerated; + windowattribs[index++] = NSOpenGLPFADepthSize; + windowattribs[index++] = (NSOpenGLPixelFormatAttribute)16; + windowattribs[index++] = NSOpenGLPFAColorSize; + windowattribs[index++] = (NSOpenGLPixelFormatAttribute)bits; + + if (stencilBuffer) + { + windowattribs[index++] = NSOpenGLPFAStencilSize; + windowattribs[index++] = (NSOpenGLPixelFormatAttribute)1; + } + + windowattribs[index++] = (NSOpenGLPixelFormatAttribute)NULL; + + format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs]; + if (format != NULL) + { + _oglcontext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:NULL]; + [format release]; + } + + if (_oglcontext != NULL) + { + [_window center]; + [_window setDelegate:[NSApp delegate]]; + [_oglcontext setView:[_window contentView]]; + [_window setAcceptsMouseMovedEvents:TRUE]; + [_window setIsVisible:TRUE]; + [_window makeKeyAndOrderFront:nil]; + + _cglcontext = (CGLContextObj) [_oglcontext CGLContextObj]; + _width = windowSize.Width; + _height = windowSize.Height; + result = true; + } + } + } + else + { + displaymode = CGDisplayBestModeForParameters(display,bits,windowSize.Width,windowSize.Height,NULL); + if (displaymode != NULL) + { + olddisplaymode = CGDisplayCurrentMode(display); + error = CGCaptureAllDisplays(); + if (error == CGDisplayNoErr) + { + error = CGDisplaySwitchToMode(display,displaymode); + if (error == CGDisplayNoErr) + { + pixelFormat = NULL; + numPixelFormats = 0; + + index = 0; + fullattribs[index++] = kCGLPFAFullScreen; + fullattribs[index++] = kCGLPFADisplayMask; + fullattribs[index++] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display); + fullattribs[index++] = kCGLPFADoubleBuffer; + fullattribs[index++] = kCGLPFAAccelerated; + fullattribs[index++] = kCGLPFADepthSize; + fullattribs[index++] = (CGLPixelFormatAttribute)16; + fullattribs[index++] = kCGLPFAColorSize; + fullattribs[index++] = (CGLPixelFormatAttribute)bits; + + if (stencilBuffer) + { + fullattribs[index++] = kCGLPFAStencilSize; + fullattribs[index++] = (CGLPixelFormatAttribute)1; + } + + fullattribs[index++] = (CGLPixelFormatAttribute)NULL; + CGLChoosePixelFormat(fullattribs,&pixelFormat,&numPixelFormats); + + if (pixelFormat != NULL) + { + CGLCreateContext(pixelFormat,NULL,&_cglcontext); + CGLDestroyPixelFormat(pixelFormat); + } + + if (_cglcontext != NULL) + { + CGLSetFullScreen(_cglcontext); + displayRect = CGDisplayBounds(display); + _width = (int)displayRect.size.width; + _height = (int)displayRect.size.height; + result = true; + } + } + } + } + } + + if (result) + { + CGLSetCurrentContext(_cglcontext); + newSwapInterval = (vsync) ? 1 : 0; + CGLSetParameter(_cglcontext,kCGLCPSwapInterval,&newSwapInterval); + glViewport(0,0,_width,_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + + return (result); +} + +void CIrrDeviceMacOSX::setResize(int width,int height) +{ + _width = width; + _height = height; + [_oglcontext update]; + getVideoDriver()->OnResize(core::dimension2d(width, height)); +} + +void CIrrDeviceMacOSX::createDriver(video::E_DRIVER_TYPE driverType,const core::dimension2d& windowSize,u32 bits,bool fullscreen,bool stencilbuffer, bool vsync, bool antiAlias) +{ + switch (driverType) + { + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(windowSize, fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createSoftwareDriver2(windowSize, fullscreen, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + VideoDriver = video::createOpenGLDriver(windowSize, this, fullscreen, stencilbuffer, FileSystem, vsync, antiAlias); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in OSX. Try OpenGL or Software renderer.", ELL_ERROR); + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, windowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + +void CIrrDeviceMacOSX::flush() +{ + if (_cglcontext != NULL) + { + glFinish(); + CGLFlushDrawable(_cglcontext); + } +} + +bool CIrrDeviceMacOSX::run() +{ + NSEvent *event; + irr::SEvent ievent; + + os::Timer::tick(); + storeMouseLocation(); + + event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]; + if (event != nil) + { + bzero(&ievent,sizeof(ievent)); + + switch([event type]) + { + case NSKeyDown: + postKeyEvent(event,ievent,true); + break; + + case NSKeyUp: + postKeyEvent(event,ievent,false); + break; + + case NSLeftMouseDown: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + postMouseEvent(event,ievent); + break; + + case NSLeftMouseUp: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + postMouseEvent(event,ievent); + break; + + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + postMouseEvent(event,ievent); + break; + + case NSRightMouseDown: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + postMouseEvent(event,ievent); + break; + + case NSRightMouseUp: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + postMouseEvent(event,ievent); + break; + + case NSScrollWheel: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + ievent.MouseInput.Wheel = [event deltaY]; + if (ievent.MouseInput.Wheel < 1.0f) ievent.MouseInput.Wheel *= 10.0f; + else ievent.MouseInput.Wheel *= 5.0f; + postMouseEvent(event,ievent); + break; + + default: + [NSApp sendEvent:event]; + break; + } + } + + return (![[NSApp delegate] isQuit] && _active); +} + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceMacOSX::yield() +{ + // TODO: Does this work or maybe is there a better way? + struct timespec ts = {0,0}; + nanosleep(&ts, NULL); +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceMacOSX::sleep(u32 timeMs, bool pauseTimer=false) +{ + // TODO: Does this work or maybe is there a better way? + + bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + +void CIrrDeviceMacOSX::present(video::IImage* image, s32 windowId, core::rect* src ) +{ +} + +void CIrrDeviceMacOSX::setWindowCaption(const wchar_t* text) +{ + size_t size; + char title[1024]; + + if (_window != NULL) + { + size = wcstombs(title,text,1024); + if (size == 1024) title[1023] = 0; + [_window setTitle:[NSString stringWithCString:title length:size]]; + } +} + +bool CIrrDeviceMacOSX::isWindowActive() const +{ + return (_active); +} + +void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed) +{ + NSString *str; + std::map::const_iterator iter; + unsigned int result,c,mkey,mchar; + const unsigned char *cStr; + BOOL skipCommand; + + str = [event characters]; + if (str != nil && [str length] > 0) + { + mkey = mchar = 0; + skipCommand = false; + c = [str characterAtIndex:0]; + + iter = _keycodes.find(c); + if (iter != _keycodes.end()) mkey = (*iter).second; + else + { + cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding]; + if (cStr != NULL && strlen((char*)cStr) > 0) + { + mchar = cStr[0]; + mkey = toupper(mchar); + if ([event modifierFlags] & NSCommandKeyMask) + { + if (mkey == 'C' || mkey == 'V' || mkey == 'X') + { + mchar = 0; + skipCommand = true; + } + } + } + } + + ievent.EventType = irr::EET_KEY_INPUT_EVENT; + ievent.KeyInput.Key = (irr::EKEY_CODE)mkey; + ievent.KeyInput.PressedDown = pressed; + ievent.KeyInput.Shift = ([event modifierFlags] & NSShiftKeyMask) != 0; + ievent.KeyInput.Control = ([event modifierFlags] & NSControlKeyMask) != 0; + ievent.KeyInput.Char = (irr::EKEY_CODE)mchar; + + if (skipCommand) + ievent.KeyInput.Control = true; + else if ([event modifierFlags] & NSCommandKeyMask) + [NSApp sendEvent:(NSEvent *)event]; + + postEventFromUser(ievent); + } +} + +void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent) +{ + BOOL post = true; + + if (_window != NULL) + { + ievent.MouseInput.X = (int)[event locationInWindow].x; + ievent.MouseInput.Y = _height - (int)[event locationInWindow].y; + if (ievent.MouseInput.Y < 0) post = false; + } + else + { + ievent.MouseInput.X = (int)[NSEvent mouseLocation].x; + ievent.MouseInput.Y = _height - (int)[NSEvent mouseLocation].y; + } + + if (post) postEventFromUser(ievent); + [NSApp sendEvent:(NSEvent *)event]; +} + +void CIrrDeviceMacOSX::storeMouseLocation() +{ + NSPoint p; + int x,y; + + p = [NSEvent mouseLocation]; + + if (_window != NULL) + { + p = [_window convertScreenToBase:p]; + x = (int)p.x; + y = _height - (int)p.y; + } + else + { + x = (int)p.x; + y = _screenHeight - (int)p.y; + } + + ((CCursorControl *)CursorControl)->updateInternalCursorPosition(x,y); +} + +void CIrrDeviceMacOSX::setMouseLocation(int x,int y) +{ + NSPoint p; + CGPoint c; + + if (_window != NULL) + { + p.x = (float) x; + p.y = (float) (_height - y); + p = [_window convertBaseToScreen:p]; + p.y = _screenHeight - p.y; + } + else + { + p.x = (float) x; + p.y = (float) (_height - y); + } + + c.x = p.x; + c.y = p.y; + CGSetLocalEventsSuppressionInterval(0); + CGWarpMouseCursorPosition(c); +} + +void CIrrDeviceMacOSX::setCursorVisible(bool visible) +{ + CGDirectDisplayID display; + + display = CGMainDisplayID(); + if (visible) CGDisplayShowCursor(display); + else CGDisplayHideCursor(display); +} + +void CIrrDeviceMacOSX::initKeycodes() +{ + _keycodes[NSUpArrowFunctionKey] = irr::KEY_UP; + _keycodes[NSDownArrowFunctionKey] = irr::KEY_DOWN; + _keycodes[NSLeftArrowFunctionKey] = irr::KEY_LEFT; + _keycodes[NSRightArrowFunctionKey] = irr::KEY_RIGHT; + _keycodes[NSF1FunctionKey] = irr::KEY_F1; + _keycodes[NSF2FunctionKey] = irr::KEY_F2; + _keycodes[NSF3FunctionKey] = irr::KEY_F3; + _keycodes[NSF4FunctionKey] = irr::KEY_F4; + _keycodes[NSF5FunctionKey] = irr::KEY_F5; + _keycodes[NSF6FunctionKey] = irr::KEY_F6; + _keycodes[NSF7FunctionKey] = irr::KEY_F7; + _keycodes[NSF8FunctionKey] = irr::KEY_F8; + _keycodes[NSF9FunctionKey] = irr::KEY_F9; + _keycodes[NSF10FunctionKey] = irr::KEY_F10; + _keycodes[NSF11FunctionKey] = irr::KEY_F11; + _keycodes[NSF12FunctionKey] = irr::KEY_F12; + _keycodes[NSF13FunctionKey] = irr::KEY_F13; + _keycodes[NSF14FunctionKey] = irr::KEY_F14; + _keycodes[NSF15FunctionKey] = irr::KEY_F15; + _keycodes[NSF16FunctionKey] = irr::KEY_F16; + _keycodes[NSHomeFunctionKey] = irr::KEY_HOME; + _keycodes[NSEndFunctionKey] = irr::KEY_END; + _keycodes[NSInsertFunctionKey] = irr::KEY_INSERT; + _keycodes[NSDeleteFunctionKey] = irr::KEY_DELETE; + _keycodes[NSHelpFunctionKey] = irr::KEY_HELP; + _keycodes[NSSelectFunctionKey] = irr::KEY_SELECT; + _keycodes[NSPrintFunctionKey] = irr::KEY_PRINT; + _keycodes[NSExecuteFunctionKey] = irr::KEY_EXECUT; + _keycodes[NSPrintScreenFunctionKey] = irr::KEY_SNAPSHOT; + _keycodes[NSPauseFunctionKey] = irr::KEY_PAUSE; + _keycodes[NSScrollLockFunctionKey] = irr::KEY_SCROLL; + _keycodes[0x7F] = irr::KEY_BACK; + _keycodes[0x09] = irr::KEY_TAB; + _keycodes[0x0D] = irr::KEY_RETURN; + _keycodes[0x03] = irr::KEY_RETURN; + _keycodes[0x1B] = irr::KEY_ESCAPE; +} + +//! Sets if the window should be resizeable in windowed mode. + +void CIrrDeviceMacOSX::setResizeAble(bool resize) +{ + // todo: implement resize +} + + +IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& param) +{ + CIrrDeviceMacOSX* dev = new CIrrDeviceMacOSX( + param.DriverType, + param.WindowSize, + param.Bits, + param.Fullscreen, + param.Stencilbuffer, + param.Vsync, + param.AntiAlias, + param.EventReceiver, + param.SDK_version_do_not_use); + + if (dev && !dev->getVideoDriver() && param.DriverType != video::EDT_NULL) + { + dev->drop(); + dev = 0; + } + + return dev; +} + +} + +#endif + diff --git a/src/dep/src/irrlicht/MacOSX/DemoApp-Info.plist b/src/dep/src/irrlicht/MacOSX/DemoApp-Info.plist new file mode 100644 index 0000000..a754c7f --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/DemoApp-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.irrlicht.${EXECUTABLE_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + IRRL + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.mode1 b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.mode1 new file mode 100644 index 0000000..c7ff145 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.mode1 @@ -0,0 +1,1366 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + B8D4602E094C67E300898A14 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 252 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 0867D691FE84028FC02AAC07 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {252, 796}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {269, 814}} + GroupTreeTableConfiguration + + MainColumn + 252 + + RubberWindowFrame + 215 163 1240 855 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 269pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {966, 566}} + RubberWindowFrame + 215 163 1240 855 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 566pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 571}, {966, 243}} + RubberWindowFrame + 215 163 1240 855 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 243pt + + + Proportion + 966pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + B8E1AEE90A20BA7A0084E880 + 1CE0B1FE06471DED0097A5F4 + B8E1AEEA0A20BA7A0084E880 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 1C0AD2B3069F1EA900FABCE6 + B8E1AEEF0A20BFA00084E880 + B8D460FD094C68D500898A14 + /Users/epetitje/Desktop/irrlicht-1.0/source/Irrlicht/MacOSX/MacOSX.xcodeproj + + WindowString + 215 163 1240 855 0 0 1680 1028 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + <No Editor> + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1014, 355}} + RubberWindowFrame + 752 216 1014 685 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 355pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 360}, {1014, 284}} + RubberWindowFrame + 752 216 1014 685 0 0 1680 1028 + + Module + PBXBuildResultsModule + Proportion + 284pt + + + Proportion + 644pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + B8D460FD094C68D500898A14 + B8E1AEC30A20BA6F0084E880 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 752 216 1014 685 0 0 1680 1028 + WindowToolGUID + B8D460FD094C68D500898A14 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 203}} + {{405, 0}, {683, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1088, 203}} + {{0, 203}, {1088, 543}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {1088, 746}} + RubberWindowFrame + 894 152 1088 787 0 0 1680 1028 + + Module + PBXDebugSessionModule + Proportion + 746pt + + + Proportion + 746pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + B89968FA0A0F51B900B60327 + 1C162984064C10D400B95A72 + B89968FB0A0F51B900B60327 + B89968FC0A0F51B900B60327 + B89968FD0A0F51B900B60327 + B89968FE0A0F51B900B60327 + B89968FF0A0F51B900B60327 + B89969000A0F51B900B60327 + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 894 152 1088 787 0 0 1680 1028 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + Irrlicht.cpp + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {851, 379}} + RubberWindowFrame + 822 82 851 776 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 851pt + + + Proportion + 379pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 384}, {851, 351}} + RubberWindowFrame + 822 82 851 776 0 0 1680 1028 + + Module + PBXProjectFindModule + Proportion + 351pt + + + Proportion + 735pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + B8996B6A0A0F88DF00B60327 + B8996B6B0A0F88DF00B60327 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 822 82 851 776 0 0 1680 1028 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {440, 358}} + RubberWindowFrame + 38 529 440 400 0 0 1680 1028 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 359pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + B8E30DA1094EDBF1002CB3A0 + B89969010A0F51B900B60327 + 1C78EAAC065D492600B07095 + + WindowString + 38 529 440 400 0 0 1680 1028 + WindowToolGUID + B8E30DA1094EDBF1002CB3A0 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.run + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {367, 168}} + {{0, 173}, {367, 270}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {406, 443}} + {{411, 0}, {517, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {756, 467}} + RubberWindowFrame + 14 307 756 508 0 0 1680 1028 + + Module + PBXRunSessionModule + Proportion + 467pt + + + Proportion + 467pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + B8E1AF160A20C2E60084E880 + 1CD0528B0623707200166675 + B8E1AF170A20C2E60084E880 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 14 307 756 508 0 0 1680 1028 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 470 310 744 409 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 470 310 744 409 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + B8E1AEEF0A20BFA00084E880 + B8E1AEF00A20BFA00084E880 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 470 310 744 409 0 0 1680 1028 + WindowToolGUID + B8E1AEEF0A20BFA00084E880 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugAnimator + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + B8EB98380950C81600086DD5 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {700, 459}} + RubberWindowFrame + 240 442 700 500 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 459pt + + + Proportion + 459pt + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + + TableOfContents + + B88EED7409811B55002A2F8A + B88EED7509811B55002A2F8A + B8EB98380950C81600086DD5 + + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 240 442 700 500 0 0 1280 1002 + WindowToolGUID + B88EED7409811B55002A2F8A + WindowToolIsVisible + + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + + diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.pbxuser b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.pbxuser new file mode 100644 index 0000000..292a588 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/epetitje.pbxuser @@ -0,0 +1,1222 @@ +// !$*UTF8*$! +{ + 0867D690FE84028FC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Release; + activeBuildStyle = 014CEA440018CDF011CA2923 /* Debug */; + activeExecutable = B81CFEB3097FDE900057C06F /* PerPixelLightning */; + activeTarget = B81CFFC6097FE9980057C06F /* ALL */; + addToTargets = ( + ); + breakpoints = ( + ); + breakpointsGroup = B8D46100094C690000898A14 /* XCBreakpointsBucket */; + codeSenseManager = B8D46030094C67E300898A14 /* Code sense */; + executables = ( + B8DEF35E0950229200FDEA7E /* Demo */, + B81CFE10097FD9F50057C06F /* 2DGraphics */, + B81CFE91097FDDE20057C06F /* Collision */, + B81CFEB3097FDE900057C06F /* PerPixelLightning */, + B81CFED1097FDF020057C06F /* TerrainRendering */, + B81CFEF7097FE05F0057C06F /* SpecialFx */, + B81CFF16097FE13E0057C06F /* UserInterface */, + B81CFF2D097FE1E00057C06F /* CustomSceneNode */, + B81CFF42097FE25F0057C06F /* Quake3Map */, + B81CFF59097FE3050057C06F /* Shaders */, + B81CFF87097FE3DC0057C06F /* Movement */, + B81CFFA0097FE45E0057C06F /* MeshViewer */, + B81CFFBE097FE5F80057C06F /* RenderToTexture */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_ContinueID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 210, + 20, + 110, + 109, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 200, + 200, + 300, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBookmarksDataSource_LocationID, + PBXBookmarksDataSource_NameID, + PBXBookmarksDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 400, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = 1; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 727, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 200, + 120, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFindDataSource_MessageID, + PBXFindDataSource_LocationID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 518, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 169916923; + PBXWorkspaceStateSaveDate = 169916923; + }; + sourceControlManager = B8D4602F094C67E300898A14 /* Source Control */; + userBuildSettings = { + }; + }; + 32DBCF5E0370ADEE00C91783 /* MacOSX_Prefix.pch */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {938, 520}}"; + sepNavSelRange = "{130, 0}"; + sepNavVisRect = "{{0, 0}, {938, 520}}"; + }; + }; + B81CFDFE097FD9F50057C06F /* 2DGraphics */ = { + activeExec = 0; + executables = ( + B81CFE10097FD9F50057C06F /* 2DGraphics */, + ); + }; + B81CFE10097FD9F50057C06F /* 2DGraphics */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = 2DGraphics; + sourceDirectories = ( + ); + }; + B81CFE12097FDA590057C06F /* CDemo.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 560}}"; + sepNavSelRange = "{505, 0}"; + sepNavVisRect = "{{0, 0}, {925, 534}}"; + }; + }; + B81CFE13097FDA590057C06F /* CMainMenu.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 560}}"; + sepNavSelRange = "{743, 0}"; + sepNavVisRect = "{{0, 0}, {925, 534}}"; + }; + }; + B81CFE14097FDA590057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 560}}"; + sepNavSelRange = "{292, 0}"; + sepNavVisRect = "{{0, 0}, {925, 534}}"; + }; + }; + B81CFE21097FDAE40057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1008}}"; + sepNavSelRange = "{1466, 0}"; + sepNavVisRect = "{{0, 237}, {925, 534}}"; + }; + }; + B81CFE82097FDDE20057C06F /* Collision */ = { + activeExec = 0; + executables = ( + B81CFE91097FDDE20057C06F /* Collision */, + ); + }; + B81CFE91097FDDE20057C06F /* Collision */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Collision; + sourceDirectories = ( + ); + }; + B81CFE93097FDE0A0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 980}}"; + sepNavSelRange = "{1573, 0}"; + sepNavVisRect = "{{0, 250}, {925, 534}}"; + }; + }; + B81CFEA4097FDE900057C06F /* PerPixelLightning */ = { + activeExec = 0; + executables = ( + B81CFEB3097FDE900057C06F /* PerPixelLightning */, + ); + }; + B81CFEB3097FDE900057C06F /* PerPixelLightning */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = PerPixelLightning; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + B81CFEB6097FDEC10057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 6468}}"; + sepNavSelRange = "{2388, 0}"; + sepNavVisRect = "{{0, 910}, {925, 534}}"; + }; + }; + B81CFEC2097FDF020057C06F /* TerrainRendering */ = { + activeExec = 0; + executables = ( + B81CFED1097FDF020057C06F /* TerrainRendering */, + ); + }; + B81CFED1097FDF020057C06F /* TerrainRendering */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = TerrainRendering; + sourceDirectories = ( + ); + }; + B81CFED4097FDF2E0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1358}}"; + sepNavSelRange = "{1735, 0}"; + sepNavVisRect = "{{0, 798}, {925, 534}}"; + }; + }; + B81CFEE8097FE05F0057C06F /* SpecialFx */ = { + activeExec = 0; + executables = ( + B81CFEF7097FE05F0057C06F /* SpecialFx */, + ); + }; + B81CFEF7097FE05F0057C06F /* SpecialFx */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = SpecialFx; + sourceDirectories = ( + ); + }; + B81CFEFA097FE0900057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 882}}"; + sepNavSelRange = "{1278, 0}"; + sepNavVisRect = "{{0, 208}, {925, 534}}"; + }; + }; + B81CFF07097FE13E0057C06F /* UserInterface */ = { + activeExec = 0; + executables = ( + B81CFF16097FE13E0057C06F /* UserInterface */, + ); + }; + B81CFF16097FE13E0057C06F /* UserInterface */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = UserInterface; + sourceDirectories = ( + ); + }; + B81CFF19097FE17F0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 2590}}"; + sepNavSelRange = "{4482, 0}"; + sepNavVisRect = "{{0, 1846}, {925, 534}}"; + }; + }; + B81CFF1E097FE1E00057C06F /* CustomSceneNode */ = { + activeExec = 0; + executables = ( + B81CFF2D097FE1E00057C06F /* CustomSceneNode */, + ); + }; + B81CFF2D097FE1E00057C06F /* CustomSceneNode */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = CustomSceneNode; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + B81CFF30097FE2230057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 2562}}"; + sepNavSelRange = "{5552, 0}"; + sepNavVisRect = "{{0, 2002}, {925, 534}}"; + }; + }; + B81CFF33097FE25F0057C06F /* Quake3Map */ = { + activeExec = 0; + executables = ( + B81CFF42097FE25F0057C06F /* Quake3Map */, + ); + }; + B81CFF42097FE25F0057C06F /* Quake3Map */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Quake3Map; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + B81CFF45097FE2920057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1106}}"; + sepNavSelRange = "{1745, 0}"; + sepNavVisRect = "{{0, 546}, {925, 534}}"; + }; + }; + B81CFF4A097FE3050057C06F /* Shaders */ = { + activeExec = 0; + executables = ( + B81CFF59097FE3050057C06F /* Shaders */, + ); + }; + B81CFF59097FE3050057C06F /* Shaders */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Shaders; + sourceDirectories = ( + ); + }; + B81CFF5C097FE33B0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1806}}"; + sepNavSelRange = "{923, 0}"; + sepNavVisRect = "{{0, 1246}, {925, 534}}"; + }; + }; + B81CFF78097FE3DC0057C06F /* Movement */ = { + activeExec = 0; + executables = ( + B81CFF87097FE3DC0057C06F /* Movement */, + ); + }; + B81CFF87097FE3DC0057C06F /* Movement */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Movement; + sourceDirectories = ( + ); + }; + B81CFF8A097FE4120057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1582}}"; + sepNavSelRange = "{284, 0}"; + sepNavVisRect = "{{0, 1022}, {925, 534}}"; + }; + }; + B81CFF91097FE45E0057C06F /* MeshViewer */ = { + activeExec = 0; + executables = ( + B81CFFA0097FE45E0057C06F /* MeshViewer */, + ); + }; + B81CFFA0097FE45E0057C06F /* MeshViewer */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = MeshViewer; + sourceDirectories = ( + ); + }; + B81CFFA3097FE4A40057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 4284}}"; + sepNavSelRange = "{8789, 0}"; + sepNavVisRect = "{{0, 3484}, {925, 534}}"; + }; + }; + B81CFFAF097FE5F80057C06F /* RenderToTexture */ = { + activeExec = 0; + executables = ( + B81CFFBE097FE5F80057C06F /* RenderToTexture */, + ); + }; + B81CFFBE097FE5F80057C06F /* RenderToTexture */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = RenderToTexture; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + B81CFFC1097FE6420057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 2002}}"; + sepNavSelRange = "{4206, 0}"; + sepNavVisRect = "{{0, 12}, {925, 534}}"; + }; + }; + B81CFFC6097FE9980057C06F /* ALL */ = { + activeExec = 0; + }; + B82567DE0A0BB505009744E8 /* OSXClipboard.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 777}}"; + sepNavSelRange = "{237, 0}"; + sepNavVisRect = "{{0, 0}, {925, 777}}"; + }; + }; + B82567EA0A0BB58D009744E8 /* OSXClipboard.mm */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 777}}"; + sepNavSelRange = "{918, 0}"; + sepNavVisRect = "{{0, 0}, {925, 777}}"; + }; + }; + B8996BE60A0F908900B60327 /* CIrrDeviceMacOSX.mm:370 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + continueAfterActions = 0; + delayBeforeContinue = 0; + fileReference = B8E30CD3094ED594002CB3A0 /* CIrrDeviceMacOSX.mm */; + functionName = "CIrrDeviceMacOSX::present()"; + hitCount = 3; + lineNumber = 370; + modificationTime = 169918359.191792; + state = 2; + }; + B8D4602F094C67E300898A14 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + B8D46030094C67E300898A14 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + B8D46100094C690000898A14 /* XCBreakpointsBucket */ = { + isa = XCBreakpointsBucket; + name = "Project Breakpoints"; + objects = ( + B8996BE60A0F908900B60327 /* CIrrDeviceMacOSX.mm:370 */, + ); + }; + B8D46155094C692400898A14 /* jmemmgr.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 15666}}"; + sepNavSelRange = "{922, 0}"; + sepNavVisRect = "{{0, 14898}, {877, 768}}"; + sepNavWindowFrame = "{{138, 96}, {916, 897}}"; + }; + }; + B8D46157094C692400898A14 /* jmemnobs.c */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {810, 1540}}"; + sepNavSelRange = "{2330, 23}"; + sepNavVisRect = "{{0, 993}, {810, 436}}"; + }; + }; + B8D46262094C6E5300898A14 /* COctTreeSceneNode.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 4382}}"; + sepNavSelRange = "{4709, 0}"; + sepNavVisRect = "{{0, 2202}, {1047, 511}}"; + }; + }; + B8D46264094C6E5300898A14 /* CNullDriver.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 19558}}"; + sepNavSelRange = "{7839, 0}"; + sepNavVisRect = "{{0, 4937}, {1047, 501}}"; + sepNavWindowFrame = "{{155, 103}, {1071, 877}}"; + }; + }; + B8D4626C094C6E5300898A14 /* COSOperator.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1414}}"; + sepNavSelRange = "{1371, 20}"; + sepNavVisRect = "{{0, 522}, {925, 777}}"; + }; + }; + B8D4626D094C6E5300898A14 /* COpenGLTexture.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 2786}}"; + sepNavSelRange = "{4046, 7}"; + sepNavVisRect = "{{0, 2212}, {925, 534}}"; + }; + }; + B8D4626F094C6E5300898A14 /* COpenGLShaderMaterialRenderer.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1032, 3080}}"; + sepNavSelRange = "{546, 0}"; + sepNavVisRect = "{{0, 0}, {1032, 699}}"; + sepNavWindowFrame = "{{331, 103}, {1071, 828}}"; + }; + }; + B8D46272094C6E5300898A14 /* COpenGLDriver.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1100, 35028}}"; + sepNavSelRange = "{20988, 23}"; + sepNavVisRect = "{{0, 7600}, {925, 534}}"; + sepNavWindowFrame = "{{38, 91}, {1023, 911}}"; + }; + }; + B8D46274094C6E5300898A14 /* CGUITabControl.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 5348}}"; + sepNavSelRange = "{3863, 0}"; + sepNavVisRect = "{{0, 2379}, {1047, 465}}"; + }; + }; + B8D46275094C6E5300898A14 /* CGUIStaticText.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 3934}}"; + sepNavSelRange = "{754, 0}"; + sepNavVisRect = "{{0, 3254}, {874, 661}}"; + }; + }; + B8D46276094C6E5300898A14 /* CGUISkin.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 8176}}"; + sepNavSelRange = "{2150, 0}"; + sepNavVisRect = "{{0, 758}, {1047, 431}}"; + }; + }; + B8D46277094C6E5300898A14 /* CGUIScrollBar.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 3710}}"; + sepNavSelRange = "{6269, 0}"; + sepNavVisRect = "{{0, 2740}, {1047, 471}}"; + }; + }; + B8D46278094C6E5300898A14 /* CGUIModalScreen.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1540}}"; + sepNavSelRange = "{1866, 0}"; + sepNavVisRect = "{{0, 867}, {874, 661}}"; + }; + }; + B8D46279094C6E5300898A14 /* CGUIMessageBox.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 3024}}"; + sepNavSelRange = "{666, 0}"; + sepNavVisRect = "{{0, 2351}, {874, 661}}"; + }; + }; + B8D4627A094C6E5300898A14 /* CGUIMeshViewer.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {968, 2464}}"; + sepNavSelRange = "{572, 0}"; + sepNavVisRect = "{{0, 1784}, {874, 661}}"; + }; + }; + B8D4627B094C6E5300898A14 /* CGUIMenu.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 3402}}"; + sepNavSelRange = "{538, 0}"; + sepNavVisRect = "{{0, 2729}, {874, 661}}"; + }; + }; + B8D4627C094C6E5300898A14 /* CGUIListBox.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 5208}}"; + sepNavSelRange = "{3733, 0}"; + sepNavVisRect = "{{0, 2306}, {1047, 471}}"; + }; + }; + B8D4627D094C6E5300898A14 /* CGUIInOutFader.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1904}}"; + sepNavSelRange = "{1324, 0}"; + sepNavVisRect = "{{0, 1231}, {874, 661}}"; + }; + }; + B8D4627E094C6E5300898A14 /* CGUIWindow.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {938, 2464}}"; + sepNavSelRange = "{3236, 0}"; + sepNavVisRect = "{{0, 1596}, {938, 515}}"; + }; + }; + B8D4627F094C6E5300898A14 /* CGUIImage.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1176}}"; + sepNavSelRange = "{928, 0}"; + sepNavVisRect = "{{0, 587}, {1047, 436}}"; + }; + }; + B8D46280094C6E5300898A14 /* CGUIFont.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {926, 4858}}"; + sepNavSelRange = "{7004, 0}"; + sepNavVisRect = "{{0, 3973}, {925, 777}}"; + }; + }; + B8D46281094C6E5300898A14 /* CGUIFileOpenDialog.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {884, 3808}}"; + sepNavSelRange = "{3571, 0}"; + sepNavVisRect = "{{0, 2243}, {874, 767}}"; + }; + }; + B8D46282094C6E5300898A14 /* CGUIEnvironment.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 9576}}"; + sepNavSelRange = "{5263, 0}"; + sepNavVisRect = "{{0, 3541}, {1047, 492}}"; + }; + }; + B8D46283094C6E5300898A14 /* Irrlicht.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {810, 1106}}"; + sepNavSelRange = "{504, 8}"; + sepNavVisRect = "{{0, 226}, {810, 347}}"; + }; + }; + B8D46287094C6E5300898A14 /* CImage.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 16478}}"; + sepNavSelRange = "{20290, 23}"; + sepNavVisRect = "{{0, 14524}, {925, 534}}"; + }; + }; + B8D46288094C6E5300898A14 /* CGUIToolBar.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1946}}"; + sepNavSelRange = "{705, 0}"; + sepNavVisRect = "{{0, 1273}, {874, 661}}"; + }; + }; + B8D46295094C6E5300898A14 /* CSceneManager.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 15582}}"; + sepNavSelRange = "{19667, 0}"; + sepNavVisRect = "{{0, 10266}, {1047, 511}}"; + }; + }; + B8D46297094C6E5300898A14 /* CReadFile.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1792}}"; + sepNavSelRange = "{1751, 0}"; + sepNavVisRect = "{{0, 1381}, {1047, 411}}"; + }; + }; + B8D46298094C6E5300898A14 /* CQ3LevelMesh.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {908, 10290}}"; + sepNavSelRange = "{8416, 0}"; + sepNavVisRect = "{{0, 4033}, {810, 292}}"; + }; + }; + B8D46299094C6E5300898A14 /* CParticleSystemSceneNode.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {938, 5516}}"; + sepNavSelRange = "{5610, 0}"; + sepNavVisRect = "{{0, 4993}, {938, 515}}"; + }; + }; + B8D4629B094C6E5300898A14 /* CIrrDeviceWin32.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 8722}}"; + sepNavSelRange = "{14288, 0}"; + sepNavVisRect = "{{0, 8090}, {925, 534}}"; + sepNavWindowFrame = "{{834, -21}, {1023, 911}}"; + }; + }; + B8D4629C094C6E5300898A14 /* CImageLoaderTGA.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 2968}}"; + sepNavSelRange = "{4403, 0}"; + sepNavVisRect = "{{0, 232}, {896, 510}}"; + }; + }; + B8D4629F094C6E5300898A14 /* CImageLoaderPCX.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 784}}"; + sepNavSelRange = "{340, 0}"; + sepNavVisRect = "{{0, 0}, {874, 767}}"; + }; + }; + B8D462A0094C6E5300898A14 /* CImageLoaderJPG.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 3150}}"; + sepNavSelRange = "{1994, 17}"; + sepNavVisRect = "{{0, 941}, {874, 767}}"; + sepNavWindowFrame = "{{38, 69}, {919, 907}}"; + }; + }; + B8D462A1094C6E5300898A14 /* CImageLoaderBmp.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {818, 5348}}"; + sepNavSelRange = "{5729, 0}"; + sepNavVisRect = "{{0, 3823}, {810, 292}}"; + }; + }; + B8D462A3094C6E5300898A14 /* CWriteFile.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1680}}"; + sepNavSelRange = "{540, 0}"; + sepNavVisRect = "{{0, 1007}, {874, 661}}"; + }; + }; + B8D462A4094C6E5300898A14 /* CColorConverter.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 4858}}"; + sepNavSelRange = "{7023, 0}"; + sepNavVisRect = "{{0, 4015}, {896, 510}}"; + }; + }; + B8D462A9094C6E5300898A14 /* CSoftwareTexture2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 2226}}"; + sepNavSelRange = "{464, 0}"; + sepNavVisRect = "{{0, 1679}, {925, 534}}"; + }; + }; + B8D462AB094C6E5300898A14 /* os.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {938, 1526}}"; + sepNavSelRange = "{951, 0}"; + sepNavVisRect = "{{0, 742}, {938, 515}}"; + }; + }; + B8D462AC094C6E5300898A14 /* CLimitReadFile.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1652}}"; + sepNavSelRange = "{1626, 0}"; + sepNavVisRect = "{{0, 979}, {874, 661}}"; + }; + }; + B8D462AF094C6E5300898A14 /* CAnimatedMeshMD2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {908, 11816}}"; + sepNavSelRange = "{16369, 0}"; + sepNavVisRect = "{{0, 8149}, {810, 292}}"; + sepNavWindowFrame = "{{15, 126}, {916, 897}}"; + }; + }; + B8D462B2094C6E5300898A14 /* CFileSystem.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 2884}}"; + sepNavSelRange = "{1422, 0}"; + sepNavVisRect = "{{0, 938}, {896, 510}}"; + }; + }; + B8D462B9094C6E5300898A14 /* CGUICheckBox.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 1974}}"; + sepNavSelRange = "{364, 0}"; + sepNavVisRect = "{{0, 1301}, {874, 661}}"; + }; + }; + B8D462C0094C6E5300898A14 /* CTRFlatWire.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {938, 1946}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {938, 515}}"; + }; + }; + B8D462C5094C6E5300898A14 /* CGUIComboBox.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 3948}}"; + sepNavSelRange = "{5080, 0}"; + sepNavVisRect = "{{0, 3275}, {874, 661}}"; + }; + }; + B8D462C6094C6E5300898A14 /* CGUIButton.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 4466}}"; + sepNavSelRange = "{3029, 0}"; + sepNavVisRect = "{{0, 232}, {896, 510}}"; + }; + }; + B8D462C7094C6E5300898A14 /* C3DSMeshFileLoader.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {810, 9786}}"; + sepNavSelRange = "{15181, 0}"; + sepNavVisRect = "{{0, 9073}, {810, 292}}"; + }; + }; + B8D462C8094C6E5300898A14 /* CGUIContextMenu.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 7098}}"; + sepNavSelRange = "{10426, 0}"; + sepNavVisRect = "{{0, 6425}, {874, 661}}"; + }; + }; + B8D462C9094C6E5300898A14 /* CGUIEditBox.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 3262}}"; + sepNavSelRange = "{2181, 0}"; + sepNavVisRect = "{{0, 1061}, {925, 777}}"; + }; + }; + B8D462CC094C6E5300898A14 /* CIrrDeviceStub.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 3010}}"; + sepNavSelRange = "{3415, 0}"; + sepNavVisRect = "{{0, 2029}, {1047, 492}}"; + }; + }; + B8D462CF094C6E5300898A14 /* CLogger.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1274}}"; + sepNavSelRange = "{325, 0}"; + sepNavVisRect = "{{0, 0}, {1047, 436}}"; + }; + }; + B8D462D1094C6E5300898A14 /* CFileList.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {973, 2422}}"; + sepNavSelRange = "{1293, 0}"; + sepNavVisRect = "{{0, 802}, {973, 371}}"; + }; + }; + B8D462D7094C6E5300898A14 /* CMemoryReadFile.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1582}}"; + sepNavSelRange = "{1568, 0}"; + sepNavVisRect = "{{0, 1160}, {1047, 410}}"; + }; + }; + B8D462D8094C6E5300898A14 /* CIrrDeviceLinux.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 7672}}"; + sepNavSelRange = "{12343, 0}"; + sepNavVisRect = "{{0, 6832}, {896, 742}}"; + }; + }; + B8D462D9094C6E5300898A14 /* CZipReader.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {866, 4872}}"; + sepNavSelRange = "{3802, 0}"; + sepNavVisRect = "{{0, 1849}, {810, 292}}"; + sepNavWindowFrame = "{{15, 90}, {919, 907}}"; + }; + }; + B8D462DF094C6E5300898A14 /* CVideoModeList.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1386}}"; + sepNavSelRange = "{367, 0}"; + sepNavVisRect = "{{0, 0}, {1047, 436}}"; + }; + }; + B8D462EA094C6E5300898A14 /* CImageLoaderPSD.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {874, 784}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {874, 767}}"; + }; + }; + B8D462EC094C6E5300898A14 /* CCameraFPSSceneNode.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 3542}}"; + sepNavSelRange = "{4087, 0}"; + sepNavVisRect = "{{0, 2117}, {1047, 456}}"; + }; + }; + B8D462EE094C6E5300898A14 /* CSoftwareDriver2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 16268}}"; + sepNavSelRange = "{22483, 41}"; + sepNavVisRect = "{{0, 14308}, {925, 534}}"; + }; + }; + B8D4637E094C7B2900898A14 /* COpenGLSLMaterialRenderer.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 4620}}"; + sepNavSelRange = "{6039, 0}"; + sepNavVisRect = "{{0, 3113}, {896, 510}}"; + }; + }; + B8D46380094C7B2900898A14 /* CTRTextureGouraud2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {877, 9044}}"; + sepNavSelRange = "{325, 0}"; + sepNavVisRect = "{{0, 8276}, {877, 768}}"; + sepNavWindowFrame = "{{258, 103}, {916, 897}}"; + }; + }; + B8D46385094C7B2900898A14 /* CTRTextureLightMap2_M4.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 9380}}"; + sepNavSelRange = "{8948, 17}"; + sepNavVisRect = "{{0, 5786}, {1047, 511}}"; + }; + }; + B8D46386094C7B2900898A14 /* CZBuffer2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 1414}}"; + sepNavSelRange = "{1426, 0}"; + sepNavVisRect = "{{0, 0}, {1047, 501}}"; + }; + }; + B8DEF35C0950229200FDEA7E /* Demo */ = { + activeExec = 0; + executables = ( + B8DEF35E0950229200FDEA7E /* Demo */, + ); + }; + B8DEF35E0950229200FDEA7E /* Demo */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 3; + libgmallocEnabled = 0; + name = Demo; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + B8DEF35F0950229300FDEA7E /* DemoApp-Info.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {896, 510}}"; + sepNavSelRange = "{541, 0}"; + sepNavVisRect = "{{0, 0}, {896, 510}}"; + }; + }; + B8E30CD3094ED594002CB3A0 /* CIrrDeviceMacOSX.mm */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1358, 8204}}"; + sepNavSelRange = "{10690, 0}"; + sepNavVisRect = "{{0, 5544}, {925, 534}}"; + sepNavWindowFrame = "{{328, 117}, {1023, 911}}"; + }; + }; + B8EE6F900A0B9ABD0053168D /* CTRTextureGouraudAdd2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 798}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {925, 777}}"; + }; + }; + B8EE6F930A0B9ADF0053168D /* CTRTextureGouraudAddNoZ2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 798}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {925, 777}}"; + }; + }; + B8EE6F990A0B9B2C0053168D /* CTRTextureGouraudVertexAlpha2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {810, 9366}}"; + sepNavSelRange = "{4060, 12}"; + sepNavVisRect = "{{0, 2876}, {810, 347}}"; + }; + }; + B8EE6F9C0A0B9B510053168D /* CTRTextureLightMap2_Add.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1498}}"; + sepNavSelRange = "{1449, 17}"; + sepNavVisRect = "{{0, 944}, {925, 534}}"; + }; + }; + B8EE6FA20A0B9B8E0053168D /* CTRTextureDetailMap2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 1386}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 12}, {925, 534}}"; + }; + }; + B8EE6FA90A0B9BA80053168D /* CTRGouraud2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1047, 7420}}"; + sepNavSelRange = "{8022, 0}"; + sepNavVisRect = "{{0, 5497}, {1047, 501}}"; + }; + }; + B8F68273097AA76A00537976 /* AppDelegate.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 777}}"; + sepNavSelRange = "{0, 166}"; + sepNavVisRect = "{{0, 0}, {925, 777}}"; + }; + }; + B8F68274097AA76A00537976 /* AppDelegate.mm */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {925, 560}}"; + sepNavSelRange = "{165, 0}"; + sepNavVisRect = "{{0, 0}, {925, 534}}"; + }; + }; + D2AAC07D0554694100DB518D /* MacOSX */ = { + activeExec = 0; + }; +} diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj new file mode 100644 index 0000000..34d872d --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj @@ -0,0 +1,4105 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + B81CFFC6097FE9980057C06F /* All */ = { + isa = PBXAggregateTarget; + buildConfigurationList = B81CFFE8097FE9C30057C06F /* Build configuration list for PBXAggregateTarget "All" */; + buildPhases = ( + ); + dependencies = ( + 4CA5CB9A0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB980A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB960A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB940A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB920A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB900A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8E0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8C0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8A0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB880A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB860A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB840A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB820A4868B500ADB3D7 /* PBXTargetDependency */, + ); + name = All; + productName = ALL; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 4C364EA40A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */; }; + 4C43EEBC0A74A5A300F942FC /* CAnimatedMeshB3d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C43EEBB0A74A5A300F942FC /* CAnimatedMeshB3d.cpp */; }; + 4C43EEC00A74A5C800F942FC /* CPakReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */; }; + 4C53E2500A48504D0014E966 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054770A48470500C844C2 /* main.cpp */; }; + 4C53E2510A4850550014E966 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4C53E26F0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2700A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2710A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2720A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2730A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2740A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2750A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2760A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2770A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2780A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2790A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27A0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27B0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27C0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27D0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27E0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27F0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2800A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2810A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2820A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2830A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2840A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2850A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2860A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2870A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2880A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E3890A48559C0014E966 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4C53E38F0A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3900A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3910A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3920A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3930A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3940A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3950A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3960A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3970A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3980A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3990A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E39A0A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E39B0A4855BA0014E966 /* DemoApp-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */; }; + 4C53E3B30A4856B30014E966 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1170A484C2A0014E966 /* pngrutil.c */; }; + 4C53E3BB0A4856B30014E966 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E10D0A484C2A0014E966 /* pngget.c */; }; + 4C53E3C40A4856B30014E966 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1160A484C2A0014E966 /* pngrtran.c */; }; + 4C53E3C90A4856B30014E966 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1090A484C2A0014E966 /* pngerror.c */; }; + 4C53E3CA0A4856B30014E966 /* gzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E17D0A484C2C0014E966 /* gzio.c */; }; + 4C53E3D70A4856B30014E966 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E11D0A484C2B0014E966 /* pngtrans.c */; }; + 4C53E3D80A4856B30014E966 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1800A484C2C0014E966 /* inffast.c */; }; + 4C53E3DC0A4856B30014E966 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1850A484C2C0014E966 /* inftrees.c */; }; + 4C53E3E40A4856B30014E966 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18D0A484C2C0014E966 /* uncompr.c */; }; + 4C53E3E90A4856B30014E966 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1180A484C2A0014E966 /* pngset.c */; }; + 4C53E3EE0A4856B30014E966 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1150A484C2A0014E966 /* pngrio.c */; }; + 4C53E3F30A4856B30014E966 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1750A484C2C0014E966 /* compress.c */; }; + 4C53E3F60A4856B30014E966 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1770A484C2C0014E966 /* crc32.c */; }; + 4C53E3FE0A4856B30014E966 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1920A484C2C0014E966 /* zutil.c */; }; + 4C53E4010A4856B30014E966 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18B0A484C2C0014E966 /* trees.c */; }; + 4C53E4030A4856B30014E966 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1210A484C2B0014E966 /* pngwio.c */; }; + 4C53E4040A4856B30014E966 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E10E0A484C2A0014E966 /* pngmem.c */; }; + 4C53E40A0A4856B30014E966 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1790A484C2C0014E966 /* deflate.c */; }; + 4C53E4110A4856B30014E966 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1130A484C2A0014E966 /* pngpread.c */; }; + 4C53E4140A4856B30014E966 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1010A484C2A0014E966 /* png.c */; }; + 4C53E4150A4856B30014E966 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1720A484C2C0014E966 /* adler32.c */; }; + 4C53E4160A4856B30014E966 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1230A484C2B0014E966 /* pngwtran.c */; }; + 4C53E41A0A4856B30014E966 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1240A484C2B0014E966 /* pngwutil.c */; }; + 4C53E4280A4856B30014E966 /* CImageLoaderPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */; }; + 4C53E4290A4856B30014E966 /* CColorConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */; }; + 4C53E42A0A4856B30014E966 /* CSceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */; }; + 4C53E42B0A4856B30014E966 /* CTRTextureGouraudAdd2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */; }; + 4C53E42C0A4856B30014E966 /* CNullDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF820A484C240014E966 /* CNullDriver.cpp */; }; + 4C53E42D0A4856B30014E966 /* CCSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */; }; + 4C53E42E0A4856B30014E966 /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00E0A484C250014E966 /* irrXML.cpp */; }; + 4C53E42F0A4856B30014E966 /* CGUIListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF420A484C230014E966 /* CGUIListBox.cpp */; }; + 4C53E4300A4856B30014E966 /* CTRGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */; }; + 4C53E4310A4856B30014E966 /* CIrrDeviceStub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */; }; + 4C53E4320A4856B30014E966 /* CGUIMessageBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */; }; + 4C53E4330A4856B30014E966 /* CMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */; }; + 4C53E4340A4856B30014E966 /* CGUIStaticText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */; }; + 4C53E4350A4856B30014E966 /* os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E16A0A484C2C0014E966 /* os.cpp */; }; + 4C53E4360A4856B30014E966 /* COCTLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF840A484C240014E966 /* COCTLoader.cpp */; }; + 4C53E4370A4856B30014E966 /* CGUIContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */; }; + 4C53E4390A4856B30014E966 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */; }; + 4C53E43A0A4856B30014E966 /* CDefaultSceneNodeFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */; }; + 4C53E43B0A4856B30014E966 /* CD3D9Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */; }; + 4C53E43C0A4856B30014E966 /* CTRGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */; }; + 4C53E43D0A4856B30014E966 /* C3DSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */; }; + 4C53E43E0A4856B30014E966 /* COgreMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */; }; + 4C53E43F0A4856B30014E966 /* CMY3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */; }; + 4C53E4400A4856B30014E966 /* CLMTSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */; }; + 4C53E4410A4856B30014E966 /* CGUIFileOpenDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */; }; + 4C53E4420A4856B30014E966 /* CSceneNodeAnimatorDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */; }; + 4C53E4430A4856B30014E966 /* CTRGouraudAlphaNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */; }; + 4C53E4440A4856B30014E966 /* CGeometryCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */; }; + 4C53E4450A4856B30014E966 /* CD3D8Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */; }; + 4C53E4460A4856B30014E966 /* CSkyBoxSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */; }; + 4C53E4470A4856B30014E966 /* CMeshManipulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */; }; + 4C53E4480A4856B30014E966 /* CTextSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */; }; + 4C53E4490A4856B30014E966 /* CTRTextureDetailMap2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */; }; + 4C53E44A0A4856B30014E966 /* CTRTextureGouraudAddNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */; }; + 4C53E44C0A4856B30014E966 /* CTRTextureGouraudNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */; }; + 4C53E44D0A4856B30014E966 /* CXFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF60A484C250014E966 /* CXFileReader.cpp */; }; + 4C53E44E0A4856B30014E966 /* CGUIScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */; }; + 4C53E44F0A4856B30014E966 /* CSceneCollisionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */; }; + 4C53E4500A4856B30014E966 /* CGUICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */; }; + 4C53E4510A4856B30014E966 /* CQ3LevelMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */; }; + 4C53E4520A4856B30014E966 /* CParticleGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */; }; + 4C53E4530A4856B30014E966 /* CSoftwareDriver2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */; }; + 4C53E4540A4856B30014E966 /* CD3D9ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */; }; + 4C53E4550A4856B30014E966 /* CD3D8ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */; }; + 4C53E4560A4856B30014E966 /* CAnimatedMeshMD2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */; }; + 4C53E4570A4856B30014E966 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */; }; + 4C53E4580A4856B30014E966 /* CImageLoaderPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */; }; + 4C53E4590A4856B30014E966 /* CAnimatedMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */; }; + 4C53E45A0A4856B30014E966 /* CTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */; }; + 4C53E45B0A4856B30014E966 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */; }; + 4C53E45C0A4856B30014E966 /* CTRTextureWire2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */; }; + 4C53E45D0A4856B30014E966 /* CTRTextureFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */; }; + 4C53E45E0A4856B30014E966 /* CTRGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */; }; + 4C53E45F0A4856B30014E966 /* CEmptySceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */; }; + 4C53E4600A4856B30014E966 /* CTRTextureLightMap2_Add.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */; }; + 4C53E4610A4856B30014E966 /* CReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA70A484C240014E966 /* CReadFile.cpp */; }; + 4C53E4620A4856B30014E966 /* COpenGLTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */; }; + 4C53E4630A4856B30014E966 /* CAnimatedMeshMS3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEEB0A484C220014E966 /* CAnimatedMeshMS3D.cpp */; }; + 4C53E4640A4856B30014E966 /* COSOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF990A484C240014E966 /* COSOperator.cpp */; }; + 4C53E4650A4856B30014E966 /* CMemoryReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF740A484C230014E966 /* CMemoryReadFile.cpp */; }; + 4C53E4660A4856B30014E966 /* CColladaFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */; }; + 4C53E4670A4856B30014E966 /* CCameraSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */; }; + 4C53E4680A4856B30014E966 /* CMetaTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */; }; + 4C53E4690A4856B30014E966 /* CTRTextureFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */; }; + 4C53E46A0A4856B30014E966 /* CVideoModeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */; }; + 4C53E46B0A4856B30014E966 /* CXMLReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */; }; + 4C53E46C0A4856B30014E966 /* COpenGLParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */; }; + 4C53E46D0A4856B30014E966 /* CDefaultMeshFormatLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1A0A484C230014E966 /* CDefaultMeshFormatLoader.cpp */; }; + 4C53E46E0A4856B30014E966 /* CTRTextureGouraudNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */; }; + 4C53E46F0A4856B30014E966 /* CTRTextureGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */; }; + 4C53E4700A4856B30014E966 /* CParticlePointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */; }; + 4C53E4710A4856B30014E966 /* CGUIWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF560A484C230014E966 /* CGUIWindow.cpp */; }; + 4C53E4720A4856B30014E966 /* CGUIModalScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */; }; + 4C53E4730A4856B30014E966 /* CImageLoaderPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */; }; + 4C53E4740A4856B30014E966 /* CWaterSurfaceSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */; }; + 4C53E4750A4856B30014E966 /* CXMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */; }; + 4C53E4760A4856B30014E966 /* CIrrDeviceLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */; }; + 4C53E4770A4856B30014E966 /* CLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */; }; + 4C53E4780A4856B30014E966 /* CTRTextureGouraudAdd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */; }; + 4C53E4790A4856B30014E966 /* CTRTextureGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */; }; + 4C53E47A0A4856B30014E966 /* CSoftwareDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */; }; + 4C53E47B0A4856B30014E966 /* CTRFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */; }; + 4C53E47C0A4856B30014E966 /* CTRGouraudAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */; }; + 4C53E47D0A4856B30014E966 /* CSoftwareTexture2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */; }; + 4C53E47E0A4856B30014E966 /* CZipReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E0030A484C250014E966 /* CZipReader.cpp */; }; + 4C53E47F0A4856B30014E966 /* COpenGLNormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */; }; + 4C53E4800A4856B30014E966 /* CTRTextureLightMap2_M1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */; }; + 4C53E4810A4856B30014E966 /* CTRTextureLightMap2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */; }; + 4C53E4820A4856B30014E966 /* CGUISkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */; }; + 4C53E4830A4856B30014E966 /* CD3D8Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */; }; + 4C53E4840A4856B30014E966 /* CIrrDeviceWin32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */; }; + 4C53E4850A4856B30014E966 /* CFileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF280A484C230014E966 /* CFileSystem.cpp */; }; + 4C53E4860A4856B30014E966 /* CGUIMeshViewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */; }; + 4C53E4870A4856B30014E966 /* CGUIComboBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */; }; + 4C53E4880A4856B30014E966 /* CSceneNodeAnimatorRotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */; }; + 4C53E4890A4856B30014E966 /* CSceneNodeAnimatorTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */; }; + 4C53E48A0A4856B30014E966 /* COctTreeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF860A484C240014E966 /* COctTreeSceneNode.cpp */; }; + 4C53E48B0A4856B30014E966 /* CParticleSystemSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */; }; + 4C53E48C0A4856B30014E966 /* CTerrainSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */; }; + 4C53E48D0A4856B30014E966 /* CCameraFPSSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF40A484C220014E966 /* CCameraFPSSceneNode.cpp */; }; + 4C53E48E0A4856B30014E966 /* CGUIFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */; }; + 4C53E48F0A4856B30014E966 /* CParticleFadeOutAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */; }; + 4C53E4910A4856B30014E966 /* CDummyTransformationSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */; }; + 4C53E4920A4856B30014E966 /* CFileList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF260A484C230014E966 /* CFileList.cpp */; }; + 4C53E4930A4856B30014E966 /* CImageLoaderTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */; }; + 4C53E4940A4856B30014E966 /* CXMLWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */; }; + 4C53E4950A4856B30014E966 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */; }; + 4C53E4960A4856B30014E966 /* CZBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */; }; + 4C53E4970A4856B30014E966 /* CDMFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF200A484C230014E966 /* CDMFLoader.cpp */; }; + 4C53E4980A4856B30014E966 /* CD3D9Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */; }; + 4C53E4990A4856B30014E966 /* COpenGLShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */; }; + 4C53E49A0A4856B30014E966 /* Irrlicht.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00A0A484C250014E966 /* Irrlicht.cpp */; }; + 4C53E49B0A4856B30014E966 /* CGUIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */; }; + 4C53E49C0A4856B30014E966 /* COpenGLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */; }; + 4C53E49D0A4856B30014E966 /* CD3D9HLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */; }; + 4C53E49E0A4856B30014E966 /* CSoftwareTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */; }; + 4C53E49F0A4856B30014E966 /* CCubeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */; }; + 4C53E4A00A4856B30014E966 /* CTriangleBBSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */; }; + 4C53E4A10A4856B30014E966 /* CD3D9ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */; }; + 4C53E4A20A4856B30014E966 /* CD3D8ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */; }; + 4C53E4A30A4856B30014E966 /* CGUIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */; }; + 4C53E4A40A4856B30014E966 /* CGUIToolBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */; }; + 4C53E4A50A4856B30014E966 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */; }; + 4C53E4A60A4856B30014E966 /* CBillboardSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */; }; + 4C53E4A70A4856B30014E966 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */; }; + 4C53E4A80A4856B30014E966 /* CLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF720A484C230014E966 /* CLogger.cpp */; }; + 4C53E4A90A4856B30014E966 /* CGUIInOutFader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */; }; + 4C53E4AA0A4856B30014E966 /* CWriteFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF20A484C250014E966 /* CWriteFile.cpp */; }; + 4C53E4AB0A4856B30014E966 /* CXAnimationPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF40A484C250014E966 /* CXAnimationPlayer.cpp */; }; + 4C53E4AC0A4856B30014E966 /* CCameraMayaSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF60A484C220014E966 /* CCameraMayaSceneNode.cpp */; }; + 4C53E4AD0A4856B30014E966 /* CTRTextureGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */; }; + 4C53E4AE0A4856B30014E966 /* CTRFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD10A484C240014E966 /* CTRFlat.cpp */; }; + 4C53E4AF0A4856B30014E966 /* CTerrainTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */; }; + 4C53E4B00A4856B30014E966 /* COctTreeTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF880A484C240014E966 /* COctTreeTriangleSelector.cpp */; }; + 4C53E4B10A4856B30014E966 /* CGUITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF520A484C230014E966 /* CGUITabControl.cpp */; }; + 4C53E4B20A4856B30014E966 /* CParticleBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */; }; + 4C53E4B30A4856B30014E966 /* CGUIMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF440A484C230014E966 /* CGUIMenu.cpp */; }; + 4C53E4B40A4856B30014E966 /* CImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF580A484C230014E966 /* CImage.cpp */; }; + 4C53E4B50A4856B30014E966 /* CShadowVolumeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */; }; + 4C53E4B70A4856B30014E966 /* CGUIEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */; }; + 4C53E4B80A4856B30014E966 /* CLimitReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */; }; + 4C53E4B90A4856B30014E966 /* CAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF00A484C220014E966 /* CAttributes.cpp */; }; + 4C53E4BA0A4856B30014E966 /* COpenGLDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */; }; + 4C53E4BB0A4856B30014E966 /* CTRTextureLightMap2_M2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */; }; + 4C53E4BC0A4856B30014E966 /* CGUIImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */; }; + 4C53E4BD0A4856B30014E966 /* CD3D9NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */; }; + 4C53E4BE0A4856B30014E966 /* CD3D8NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */; }; + 4C53E4BF0A4856B30014E966 /* CMeshCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF760A484C230014E966 /* CMeshCache.cpp */; }; + 4C53E4C00A4856B30014E966 /* CImageLoaderJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */; }; + 4C53E4C10A4856B30014E966 /* CFPSCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */; }; + 4C53E57E0A4856B30014E966 /* OSXClipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */; }; + 4C53E57F0A4856B30014E966 /* CIrrDeviceMacOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */; }; + 4C53E5800A4856B30014E966 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */; }; + 4C53E62E0A485ABF0014E966 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1140A484C2A0014E966 /* pngread.c */; }; + 4C6DC9B70A48715A0017A6E5 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6DC9B60A48715A0017A6E5 /* inflate.c */; }; + 4CA25BCE0A485EAD00B4E469 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F10A485CD80014E966 /* jcapimin.c */; }; + 4CA25BCF0A485EAD00B4E469 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F20A485CD80014E966 /* jcapistd.c */; }; + 4CA25BD00A485EAD00B4E469 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F30A485CD80014E966 /* jccoefct.c */; }; + 4CA25BD10A485EAD00B4E469 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F40A485CD80014E966 /* jccolor.c */; }; + 4CA25BD20A485EAD00B4E469 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F50A485CD80014E966 /* jcdctmgr.c */; }; + 4CA25BD30A485EAD00B4E469 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F60A485CD80014E966 /* jchuff.c */; }; + 4CA25BD50A485EAD00B4E469 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F80A485CD80014E966 /* jcinit.c */; }; + 4CA25BD60A485EAD00B4E469 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F90A485CD80014E966 /* jcmainct.c */; }; + 4CA25BD70A485EAD00B4E469 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FA0A485CD80014E966 /* jcmarker.c */; }; + 4CA25BD80A485EAD00B4E469 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FB0A485CD80014E966 /* jcmaster.c */; }; + 4CA25BD90A485EAD00B4E469 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FC0A485CD80014E966 /* jcomapi.c */; }; + 4CA25BDB0A485EAD00B4E469 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70A0A485CD80014E966 /* jcparam.c */; }; + 4CA25BDC0A485EAD00B4E469 /* jcphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70B0A485CD80014E966 /* jcphuff.c */; }; + 4CA25BDD0A485EAD00B4E469 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70C0A485CD80014E966 /* jcprepct.c */; }; + 4CA25BDE0A485EAD00B4E469 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70D0A485CD80014E966 /* jcsample.c */; }; + 4CA25BDF0A485EAD00B4E469 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70E0A485CD80014E966 /* jctrans.c */; }; + 4CA25BE00A485EAD00B4E469 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70F0A485CD80014E966 /* jdapimin.c */; }; + 4CA25BE10A485EAD00B4E469 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7100A485CD80014E966 /* jdapistd.c */; }; + 4CA25BE20A485EAD00B4E469 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7110A485CD80014E966 /* jdatadst.c */; }; + 4CA25BE30A485EAD00B4E469 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7120A485CD80014E966 /* jdatasrc.c */; }; + 4CA25BE40A485EAD00B4E469 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7130A485CD80014E966 /* jdcoefct.c */; }; + 4CA25BE50A485EAD00B4E469 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7140A485CD80014E966 /* jdcolor.c */; }; + 4CA25BE70A485EAD00B4E469 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7160A485CD80014E966 /* jddctmgr.c */; }; + 4CA25BE80A485EAD00B4E469 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7170A485CD80014E966 /* jdhuff.c */; }; + 4CA25BEA0A485EAD00B4E469 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7190A485CD80014E966 /* jdinput.c */; }; + 4CA25BEB0A485EAD00B4E469 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71A0A485CD80014E966 /* jdmainct.c */; }; + 4CA25BEC0A485EAD00B4E469 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71B0A485CD80014E966 /* jdmarker.c */; }; + 4CA25BED0A485EAD00B4E469 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71C0A485CD80014E966 /* jdmaster.c */; }; + 4CA25BEE0A485EAD00B4E469 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71D0A485CD80014E966 /* jdmerge.c */; }; + 4CA25BEF0A485EAD00B4E469 /* jdphuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71E0A485CD80014E966 /* jdphuff.c */; }; + 4CA25BF00A485EAD00B4E469 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71F0A485CD80014E966 /* jdpostct.c */; }; + 4CA25BF10A485EAD00B4E469 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7200A485CD80014E966 /* jdsample.c */; }; + 4CA25BF20A485EAD00B4E469 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7210A485CD80014E966 /* jdtrans.c */; }; + 4CA25BF30A485EAD00B4E469 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7220A485CD80014E966 /* jerror.c */; }; + 4CA25BF50A485EAD00B4E469 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7240A485CD80014E966 /* jfdctflt.c */; }; + 4CA25BF60A485EAD00B4E469 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7250A485CD80014E966 /* jfdctfst.c */; }; + 4CA25BF70A485EAD00B4E469 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7260A485CD80014E966 /* jfdctint.c */; }; + 4CA25BF80A485EAD00B4E469 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7270A485CD80014E966 /* jidctflt.c */; }; + 4CA25BF90A485EAD00B4E469 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7280A485CD80014E966 /* jidctfst.c */; }; + 4CA25BFA0A485EAD00B4E469 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7290A485CD80014E966 /* jidctint.c */; }; + 4CA25BFB0A485EAD00B4E469 /* jidctred.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E72A0A485CD80014E966 /* jidctred.c */; }; + 4CA25C000A485EAD00B4E469 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7300A485CD80014E966 /* jmemmgr.c */; }; + 4CA25C020A485EAD00B4E469 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7320A485CD80014E966 /* jmemnobs.c */; }; + 4CA25C080A485EAD00B4E469 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7390A485CD80014E966 /* jquant1.c */; }; + 4CA25C090A485EAD00B4E469 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73A0A485CD80014E966 /* jquant2.c */; }; + 4CA25C0A0A485EAD00B4E469 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73B0A485CD80014E966 /* jutils.c */; }; + 4CA25C0C0A485EAD00B4E469 /* rdbmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7540A485CD90014E966 /* rdbmp.c */; }; + 4CA25C0D0A485EAD00B4E469 /* rdcolmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7550A485CD90014E966 /* rdcolmap.c */; }; + 4CA25C0E0A485EAD00B4E469 /* rdgif.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7560A485CD90014E966 /* rdgif.c */; }; + 4CA25C100A485EAD00B4E469 /* rdppm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7590A485CD90014E966 /* rdppm.c */; }; + 4CA25C110A485EAD00B4E469 /* rdrle.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E75A0A485CD90014E966 /* rdrle.c */; }; + 4CA25C120A485EAD00B4E469 /* rdswitch.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E75B0A485CD90014E966 /* rdswitch.c */; }; + 4CA25C130A485EAD00B4E469 /* rdtarga.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E75C0A485CD90014E966 /* rdtarga.c */; }; + 4CA25C150A485EAD00B4E469 /* transupp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7660A485CD90014E966 /* transupp.c */; }; + 4CA25C170A485EAD00B4E469 /* wrbmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E76A0A485CD90014E966 /* wrbmp.c */; }; + 4CA25C180A485EAD00B4E469 /* wrgif.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E76B0A485CD90014E966 /* wrgif.c */; }; + 4CA25C1A0A485EAD00B4E469 /* wrppm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E76E0A485CD90014E966 /* wrppm.c */; }; + 4CA25C1B0A485EAD00B4E469 /* wrrle.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E76F0A485CD90014E966 /* wrrle.c */; }; + 4CA25C1C0A485EAD00B4E469 /* wrtarga.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7700A485CD90014E966 /* wrtarga.c */; }; + 4CA25C350A4860EE00B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00547D0A48470500C844C2 /* main.cpp */; }; + 4CA25C360A48610400B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C520A48618800B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA25C560A4861AE00B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA25C690A4861D100B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054830A48470500C844C2 /* main.cpp */; }; + 4CA25C6A0A4861D800B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C8B0A48626600B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C8C0A48627600B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054890A48470500C844C2 /* main.cpp */; }; + 4CA25C8D0A48628200B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBA70A4869C600ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBA90A4869DD00ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBAE0A4869E600ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054A30A48470500C844C2 /* main.cpp */; }; + 4CA5CBAF0A4869F300ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB00A4869FD00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054AA0A48470500C844C2 /* main.cpp */; }; + 4CA5CBB10A486A0200ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB20A486A0D00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054B00A48470500C844C2 /* main.cpp */; }; + 4CA5CBB30A486A1300ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBB40A486A1600ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB50A486A1F00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054B60A48470500C844C2 /* main.cpp */; }; + 4CA5CBB60A486A2200ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBB70A486A2500ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB80A486A2E00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054BC0A48470500C844C2 /* main.cpp */; }; + 4CA5CBB90A486A3100ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBBA0A486A3A00ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBBB0A486A4C00ADB3D7 /* CMainMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054C70A48470500C844C2 /* CMainMenu.cpp */; }; + 4CA5CBBC0A486A4C00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054CA0A48470500C844C2 /* main.cpp */; }; + 4CA5CBBD0A486A4C00ADB3D7 /* CDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054C50A48470500C844C2 /* CDemo.cpp */; }; + 4CA5CBBE0A486A4F00ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBBF0A486A5700ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CC36B0F0A6B61DB0076C4B2 /* CSphereSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */; }; + 4CF146F50A486648006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF146F60A486651006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF146F70A486668006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00548F0A48470500C844C2 /* main.cpp */; }; + 4CF1470A0A4866FA006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF1470B0A486704006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF147100A486709006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054950A48470500C844C2 /* main.cpp */; }; + 4CF147180A48676A006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF147190A48676E006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF1471A0A486774006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00549B0A48470500C844C2 /* main.cpp */; }; + 4CFA7BEE0A88735A00B03626 /* CImageLoaderBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */; }; + 4CFA7BF00A88735A00B03626 /* CImageWriterBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */; }; + 4CFA7BF20A88735A00B03626 /* CImageWriterJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */; }; + 4CFA7BF40A88735A00B03626 /* CImageWriterPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */; }; + 4CFA7BF60A88735A00B03626 /* CImageWriterPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */; }; + 4CFA7BF80A88735A00B03626 /* CImageWriterPPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */; }; + 4CFA7BFA0A88735A00B03626 /* CImageWriterPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */; }; + 4CFA7BFC0A88735A00B03626 /* CImageWriterTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */; }; + 4CFA7BFE0A88735A00B03626 /* CSkyDomeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */; }; + 5DD480480C7D8B9100728AA9 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480470C7D8B9100728AA9 /* pngwrite.c */; }; + 5DD4804E0C7D91DF00728AA9 /* CDepthBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */; }; + 5DD4804F0C7D91DF00728AA9 /* CDepthBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */; }; + 5DD480520C7D936700728AA9 /* IBurningShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480500C7D936700728AA9 /* IBurningShader.cpp */; }; + 5DD480530C7D936700728AA9 /* IBurningShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480510C7D936700728AA9 /* IBurningShader.h */; }; + 5DD480550C7D93AB00728AA9 /* IDepthBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */; }; + 5DD4805A0C7D945800728AA9 /* CAnimatedMeshMD3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */; }; + 5DD4805B0C7D945800728AA9 /* CAnimatedMeshMD3.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */; }; + 5DD4805C0C7D945800728AA9 /* CDefaultGUIElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */; }; + 5DD4805D0C7D945800728AA9 /* CDefaultGUIElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */; }; + 5DD480640C7D947B00728AA9 /* CGUIColorSelectDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */; }; + 5DD480650C7D947B00728AA9 /* CGUIColorSelectDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */; }; + 5DD480660C7D947B00728AA9 /* CGUISpinBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */; }; + 5DD480670C7D947B00728AA9 /* CGUISpinBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */; }; + 5DD480680C7D947B00728AA9 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */; }; + 5DD480690C7D947B00728AA9 /* CGUISpriteBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */; }; + 5DD480710C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */; }; + 5DD480720C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */; }; + 5DD480730C7D94AC00728AA9 /* CTRTextureBlend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */; }; + 5DD480740C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */; }; + 5DD480750C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */; }; + 5DD480760C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */; }; + 5DD480770C7D94AC00728AA9 /* glxext.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480700C7D94AC00728AA9 /* glxext.h */; }; + 5DD480C70C7DA66800728AA9 /* COpenGLExtensionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */; }; + 5DD480C80C7DA66800728AA9 /* CMD3MeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */; }; + 5DD480C90C7DA66800728AA9 /* CIrrDeviceSDL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */; }; + 5DD480CA0C7DA66800728AA9 /* CIrrDeviceSDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */; }; + 5DD480CB0C7DA66800728AA9 /* COpenGLExtensionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */; }; + 5DD480CC0C7DA66800728AA9 /* CMD3MeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 4CA5CB810A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B8DEF35C0950229200FDEA7E; + remoteInfo = Demo; + }; + 4CA5CB830A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFFAF097FE5F80057C06F; + remoteInfo = RenderToTexture; + }; + 4CA5CB850A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEC2097FDF020057C06F; + remoteInfo = TerrainRendering; + }; + 4CA5CB870A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEA4097FDE900057C06F; + remoteInfo = PerPixelLightning; + }; + 4CA5CB890A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF4A097FE3050057C06F; + remoteInfo = Shaders; + }; + 4CA5CB8B0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF91097FE45E0057C06F; + remoteInfo = MeshViewer; + }; + 4CA5CB8D0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEE8097FE05F0057C06F; + remoteInfo = SpecialFx; + }; + 4CA5CB8F0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFE82097FDDE20057C06F; + remoteInfo = Collision; + }; + 4CA5CB910A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFDFE097FD9F50057C06F; + remoteInfo = 2DGraphics; + }; + 4CA5CB930A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF07097FE13E0057C06F; + remoteInfo = UserInterface; + }; + 4CA5CB950A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF78097FE3DC0057C06F; + remoteInfo = Movement; + }; + 4CA5CB970A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF1E097FE1E00057C06F; + remoteInfo = CustomSceneNode; + }; + 4CA5CB990A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF33097FE25F0057C06F; + remoteInfo = Quake3Map; + }; + B81CFE00097FD9F50057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFE84097FDDE20057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEA6097FDE900057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEC4097FDF020057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEEA097FE05F0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF09097FE13E0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF20097FE1E00057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF35097FE25F0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF4C097FE3050057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF7A097FE3DC0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF93097FE45E0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFFB1097FE5F80057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B8DEF374095024F600FDEA7E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 4C0054710A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054770A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00547D0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054830A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = main.cpp; sourceTree = ""; }; + 4C0054890A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00548F0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054950A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00549B0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054A30A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054AA0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054B00A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054B60A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054BC0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054C50A48470500C844C2 /* CDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDemo.cpp; sourceTree = ""; }; + 4C0054C60A48470500C844C2 /* CDemo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDemo.h; sourceTree = ""; }; + 4C0054C70A48470500C844C2 /* CMainMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMainMenu.cpp; sourceTree = ""; }; + 4C0054C80A48470500C844C2 /* CMainMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMainMenu.h; sourceTree = ""; }; + 4C0054CA0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COBJMeshFileLoader.cpp; sourceTree = ""; }; + 4C364EA30A6C6DC2004CFBB4 /* COBJMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COBJMeshFileLoader.h; sourceTree = ""; }; + 4C43EEBB0A74A5A300F942FC /* CAnimatedMeshB3d.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CAnimatedMeshB3d.cpp; sourceTree = ""; }; + 4C43EEBD0A74A5AB00F942FC /* CAnimatedMeshB3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshB3d.h; sourceTree = ""; }; + 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CPakReader.cpp; sourceTree = ""; }; + 4C43EEBF0A74A5C800F942FC /* CPakReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CPakReader.h; sourceTree = ""; }; + 4C53DEE60A484C220014E966 /* BuiltInFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = BuiltInFont.h; sourceTree = ""; }; + 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = C3DSMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DEE80A484C220014E966 /* C3DSMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = C3DSMeshFileLoader.h; sourceTree = ""; }; + 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CAnimatedMeshMD2.cpp; sourceTree = ""; }; + 4C53DEEA0A484C220014E966 /* CAnimatedMeshMD2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshMD2.h; sourceTree = ""; }; + 4C53DEEB0A484C220014E966 /* CAnimatedMeshMS3D.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAnimatedMeshMS3D.cpp; sourceTree = ""; }; + 4C53DEEC0A484C220014E966 /* CAnimatedMeshMS3D.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshMS3D.h; sourceTree = ""; }; + 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAnimatedMeshSceneNode.cpp; sourceTree = ""; }; + 4C53DEEE0A484C220014E966 /* CAnimatedMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshSceneNode.h; sourceTree = ""; }; + 4C53DEEF0A484C220014E966 /* CAttributeImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAttributeImpl.h; sourceTree = ""; }; + 4C53DEF00A484C220014E966 /* CAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAttributes.cpp; sourceTree = ""; }; + 4C53DEF10A484C220014E966 /* CAttributes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAttributes.h; sourceTree = ""; }; + 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBillboardSceneNode.cpp; sourceTree = ""; }; + 4C53DEF30A484C220014E966 /* CBillboardSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CBillboardSceneNode.h; sourceTree = ""; }; + 4C53DEF40A484C220014E966 /* CCameraFPSSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCameraFPSSceneNode.cpp; sourceTree = ""; }; + 4C53DEF50A484C220014E966 /* CCameraFPSSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCameraFPSSceneNode.h; sourceTree = ""; }; + 4C53DEF60A484C220014E966 /* CCameraMayaSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCameraMayaSceneNode.cpp; sourceTree = ""; }; + 4C53DEF70A484C220014E966 /* CCameraMayaSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCameraMayaSceneNode.h; sourceTree = ""; }; + 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCameraSceneNode.cpp; sourceTree = ""; }; + 4C53DEF90A484C220014E966 /* CCameraSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCameraSceneNode.h; sourceTree = ""; }; + 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CColladaFileLoader.cpp; sourceTree = ""; }; + 4C53DEFB0A484C220014E966 /* CColladaFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CColladaFileLoader.h; sourceTree = ""; }; + 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CColorConverter.cpp; sourceTree = ""; }; + 4C53DEFD0A484C220014E966 /* CColorConverter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CColorConverter.h; sourceTree = ""; }; + 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCSMLoader.cpp; sourceTree = ""; }; + 4C53DEFF0A484C220014E966 /* CCSMLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCSMLoader.h; sourceTree = ""; }; + 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCubeSceneNode.cpp; sourceTree = ""; }; + 4C53DF010A484C220014E966 /* CCubeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCubeSceneNode.h; sourceTree = ""; }; + 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8Driver.cpp; sourceTree = ""; }; + 4C53DF030A484C220014E966 /* CD3D8Driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8Driver.h; sourceTree = ""; }; + 4C53DF040A484C220014E966 /* CD3D8MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8MaterialRenderer.h; sourceTree = ""; }; + 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8NormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF060A484C220014E966 /* CD3D8NormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8NormalMapRenderer.h; sourceTree = ""; }; + 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8ParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF080A484C230014E966 /* CD3D8ParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8ParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8ShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF0A0A484C230014E966 /* CD3D8ShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8ShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8Texture.cpp; sourceTree = ""; }; + 4C53DF0C0A484C230014E966 /* CD3D8Texture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8Texture.h; sourceTree = ""; }; + 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9Driver.cpp; sourceTree = ""; }; + 4C53DF0E0A484C230014E966 /* CD3D9Driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9Driver.h; sourceTree = ""; }; + 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9HLSLMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF100A484C230014E966 /* CD3D9HLSLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9HLSLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF110A484C230014E966 /* CD3D9MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9MaterialRenderer.h; sourceTree = ""; }; + 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9NormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF130A484C230014E966 /* CD3D9NormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9NormalMapRenderer.h; sourceTree = ""; }; + 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9ParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF150A484C230014E966 /* CD3D9ParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9ParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9ShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF170A484C230014E966 /* CD3D9ShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9ShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9Texture.cpp; sourceTree = ""; }; + 4C53DF190A484C230014E966 /* CD3D9Texture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9Texture.h; sourceTree = ""; }; + 4C53DF1A0A484C230014E966 /* CDefaultMeshFormatLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultMeshFormatLoader.cpp; sourceTree = ""; }; + 4C53DF1B0A484C230014E966 /* CDefaultMeshFormatLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDefaultMeshFormatLoader.h; sourceTree = ""; }; + 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultSceneNodeAnimatorFactory.cpp; sourceTree = ""; }; + 4C53DF1D0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDefaultSceneNodeAnimatorFactory.h; sourceTree = ""; }; + 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultSceneNodeFactory.cpp; sourceTree = ""; }; + 4C53DF1F0A484C230014E966 /* CDefaultSceneNodeFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDefaultSceneNodeFactory.h; sourceTree = ""; }; + 4C53DF200A484C230014E966 /* CDMFLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDMFLoader.cpp; sourceTree = ""; }; + 4C53DF210A484C230014E966 /* CDMFLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDMFLoader.h; sourceTree = ""; }; + 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDummyTransformationSceneNode.cpp; sourceTree = ""; }; + 4C53DF230A484C230014E966 /* CDummyTransformationSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDummyTransformationSceneNode.h; sourceTree = ""; }; + 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CEmptySceneNode.cpp; sourceTree = ""; }; + 4C53DF250A484C230014E966 /* CEmptySceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CEmptySceneNode.h; sourceTree = ""; }; + 4C53DF260A484C230014E966 /* CFileList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFileList.cpp; sourceTree = ""; }; + 4C53DF270A484C230014E966 /* CFileList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFileList.h; sourceTree = ""; }; + 4C53DF280A484C230014E966 /* CFileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFileSystem.cpp; sourceTree = ""; }; + 4C53DF290A484C230014E966 /* CFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFileSystem.h; sourceTree = ""; }; + 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFPSCounter.cpp; sourceTree = ""; }; + 4C53DF2B0A484C230014E966 /* CFPSCounter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFPSCounter.h; sourceTree = ""; }; + 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGeometryCreator.cpp; sourceTree = ""; }; + 4C53DF2D0A484C230014E966 /* CGeometryCreator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGeometryCreator.h; sourceTree = ""; }; + 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIButton.cpp; sourceTree = ""; }; + 4C53DF2F0A484C230014E966 /* CGUIButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIButton.h; sourceTree = ""; }; + 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUICheckBox.cpp; sourceTree = ""; }; + 4C53DF310A484C230014E966 /* CGUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUICheckBox.h; sourceTree = ""; }; + 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIComboBox.cpp; sourceTree = ""; }; + 4C53DF330A484C230014E966 /* CGUIComboBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIComboBox.h; sourceTree = ""; }; + 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIContextMenu.cpp; sourceTree = ""; }; + 4C53DF350A484C230014E966 /* CGUIContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIContextMenu.h; sourceTree = ""; }; + 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIEditBox.cpp; sourceTree = ""; }; + 4C53DF370A484C230014E966 /* CGUIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIEditBox.h; sourceTree = ""; }; + 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CGUIEnvironment.cpp; sourceTree = ""; }; + 4C53DF390A484C230014E966 /* CGUIEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIEnvironment.h; sourceTree = ""; }; + 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIFileOpenDialog.cpp; sourceTree = ""; }; + 4C53DF3B0A484C230014E966 /* CGUIFileOpenDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIFileOpenDialog.h; sourceTree = ""; }; + 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CGUIFont.cpp; sourceTree = ""; }; + 4C53DF3D0A484C230014E966 /* CGUIFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIFont.h; sourceTree = ""; }; + 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIImage.cpp; sourceTree = ""; }; + 4C53DF3F0A484C230014E966 /* CGUIImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIImage.h; sourceTree = ""; }; + 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIInOutFader.cpp; sourceTree = ""; }; + 4C53DF410A484C230014E966 /* CGUIInOutFader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIInOutFader.h; sourceTree = ""; }; + 4C53DF420A484C230014E966 /* CGUIListBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIListBox.cpp; sourceTree = ""; }; + 4C53DF430A484C230014E966 /* CGUIListBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIListBox.h; sourceTree = ""; }; + 4C53DF440A484C230014E966 /* CGUIMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMenu.cpp; sourceTree = ""; }; + 4C53DF450A484C230014E966 /* CGUIMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMenu.h; sourceTree = ""; }; + 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMeshViewer.cpp; sourceTree = ""; }; + 4C53DF470A484C230014E966 /* CGUIMeshViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMeshViewer.h; sourceTree = ""; }; + 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMessageBox.cpp; sourceTree = ""; }; + 4C53DF490A484C230014E966 /* CGUIMessageBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMessageBox.h; sourceTree = ""; }; + 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIModalScreen.cpp; sourceTree = ""; }; + 4C53DF4B0A484C230014E966 /* CGUIModalScreen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIModalScreen.h; sourceTree = ""; }; + 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIScrollBar.cpp; sourceTree = ""; }; + 4C53DF4D0A484C230014E966 /* CGUIScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIScrollBar.h; sourceTree = ""; }; + 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISkin.cpp; sourceTree = ""; }; + 4C53DF4F0A484C230014E966 /* CGUISkin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUISkin.h; sourceTree = ""; }; + 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIStaticText.cpp; sourceTree = ""; }; + 4C53DF510A484C230014E966 /* CGUIStaticText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIStaticText.h; sourceTree = ""; }; + 4C53DF520A484C230014E966 /* CGUITabControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUITabControl.cpp; sourceTree = ""; }; + 4C53DF530A484C230014E966 /* CGUITabControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUITabControl.h; sourceTree = ""; }; + 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIToolBar.cpp; sourceTree = ""; }; + 4C53DF550A484C230014E966 /* CGUIToolBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIToolBar.h; sourceTree = ""; }; + 4C53DF560A484C230014E966 /* CGUIWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIWindow.cpp; sourceTree = ""; }; + 4C53DF570A484C230014E966 /* CGUIWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIWindow.h; sourceTree = ""; }; + 4C53DF580A484C230014E966 /* CImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImage.cpp; sourceTree = ""; }; + 4C53DF590A484C230014E966 /* CImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImage.h; sourceTree = ""; }; + 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderJPG.cpp; sourceTree = ""; }; + 4C53DF5D0A484C230014E966 /* CImageLoaderJPG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderJPG.h; sourceTree = ""; }; + 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderPCX.cpp; sourceTree = ""; }; + 4C53DF5F0A484C230014E966 /* CImageLoaderPCX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPCX.h; sourceTree = ""; }; + 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderPNG.cpp; sourceTree = ""; }; + 4C53DF610A484C230014E966 /* CImageLoaderPNG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPNG.h; sourceTree = ""; }; + 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderPSD.cpp; sourceTree = ""; }; + 4C53DF630A484C230014E966 /* CImageLoaderPSD.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPSD.h; sourceTree = ""; }; + 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderTGA.cpp; sourceTree = ""; }; + 4C53DF650A484C230014E966 /* CImageLoaderTGA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderTGA.h; sourceTree = ""; }; + 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceLinux.cpp; sourceTree = ""; }; + 4C53DF670A484C230014E966 /* CIrrDeviceLinux.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceLinux.h; sourceTree = ""; }; + 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceStub.cpp; sourceTree = ""; }; + 4C53DF690A484C230014E966 /* CIrrDeviceStub.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceStub.h; sourceTree = ""; }; + 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceWin32.cpp; sourceTree = ""; }; + 4C53DF6B0A484C230014E966 /* CIrrDeviceWin32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceWin32.h; sourceTree = ""; }; + 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLightSceneNode.cpp; sourceTree = ""; }; + 4C53DF6D0A484C230014E966 /* CLightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLightSceneNode.h; sourceTree = ""; }; + 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CLimitReadFile.cpp; sourceTree = ""; }; + 4C53DF6F0A484C230014E966 /* CLimitReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = CLimitReadFile.h; sourceTree = ""; }; + 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLMTSMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF710A484C230014E966 /* CLMTSMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLMTSMeshFileLoader.h; sourceTree = ""; }; + 4C53DF720A484C230014E966 /* CLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLogger.cpp; sourceTree = ""; }; + 4C53DF730A484C230014E966 /* CLogger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLogger.h; sourceTree = ""; }; + 4C53DF740A484C230014E966 /* CMemoryReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CMemoryReadFile.cpp; sourceTree = ""; }; + 4C53DF750A484C230014E966 /* CMemoryReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = CMemoryReadFile.h; sourceTree = ""; }; + 4C53DF760A484C230014E966 /* CMeshCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshCache.cpp; sourceTree = ""; }; + 4C53DF770A484C230014E966 /* CMeshCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshCache.h; sourceTree = ""; }; + 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshManipulator.cpp; sourceTree = ""; }; + 4C53DF790A484C230014E966 /* CMeshManipulator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshManipulator.h; sourceTree = ""; }; + 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshSceneNode.cpp; sourceTree = ""; }; + 4C53DF7B0A484C230014E966 /* CMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshSceneNode.h; sourceTree = ""; }; + 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMetaTriangleSelector.cpp; sourceTree = ""; }; + 4C53DF7D0A484C230014E966 /* CMetaTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMetaTriangleSelector.h; sourceTree = ""; }; + 4C53DF7E0A484C230014E966 /* CMY3DHelper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMY3DHelper.h; sourceTree = ""; }; + 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMY3DMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF800A484C230014E966 /* CMY3DMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMY3DMeshFileLoader.h; sourceTree = ""; }; + 4C53DF810A484C230014E966 /* CMY3DStuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMY3DStuff.h; sourceTree = ""; }; + 4C53DF820A484C240014E966 /* CNullDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CNullDriver.cpp; sourceTree = ""; }; + 4C53DF830A484C240014E966 /* CNullDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CNullDriver.h; sourceTree = ""; }; + 4C53DF840A484C240014E966 /* COCTLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COCTLoader.cpp; sourceTree = ""; }; + 4C53DF850A484C240014E966 /* COCTLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COCTLoader.h; sourceTree = ""; }; + 4C53DF860A484C240014E966 /* COctTreeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COctTreeSceneNode.cpp; sourceTree = ""; }; + 4C53DF870A484C240014E966 /* COctTreeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COctTreeSceneNode.h; sourceTree = ""; }; + 4C53DF880A484C240014E966 /* COctTreeTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COctTreeTriangleSelector.cpp; sourceTree = ""; }; + 4C53DF890A484C240014E966 /* COctTreeTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COctTreeTriangleSelector.h; sourceTree = ""; }; + 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = COgreMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF8B0A484C240014E966 /* COgreMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = COgreMeshFileLoader.h; sourceTree = ""; }; + 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = COpenGLDriver.cpp; sourceTree = ""; }; + 4C53DF8D0A484C240014E966 /* COpenGLDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = COpenGLDriver.h; sourceTree = ""; }; + 4C53DF8E0A484C240014E966 /* COpenGLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLNormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF900A484C240014E966 /* COpenGLNormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLNormalMapRenderer.h; sourceTree = ""; }; + 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF920A484C240014E966 /* COpenGLParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF940A484C240014E966 /* COpenGLShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = COpenGLSLMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF960A484C240014E966 /* COpenGLSLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLSLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLTexture.cpp; sourceTree = ""; }; + 4C53DF980A484C240014E966 /* COpenGLTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLTexture.h; sourceTree = ""; }; + 4C53DF990A484C240014E966 /* COSOperator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COSOperator.cpp; sourceTree = ""; }; + 4C53DF9A0A484C240014E966 /* COSOperator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COSOperator.h; sourceTree = ""; }; + 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleBoxEmitter.cpp; sourceTree = ""; }; + 4C53DF9C0A484C240014E966 /* CParticleBoxEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleBoxEmitter.h; sourceTree = ""; }; + 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleFadeOutAffector.cpp; sourceTree = ""; }; + 4C53DF9E0A484C240014E966 /* CParticleFadeOutAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleFadeOutAffector.h; sourceTree = ""; }; + 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleGravityAffector.cpp; sourceTree = ""; }; + 4C53DFA00A484C240014E966 /* CParticleGravityAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleGravityAffector.h; sourceTree = ""; }; + 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticlePointEmitter.cpp; sourceTree = ""; }; + 4C53DFA20A484C240014E966 /* CParticlePointEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticlePointEmitter.h; sourceTree = ""; }; + 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleSystemSceneNode.cpp; sourceTree = ""; }; + 4C53DFA40A484C240014E966 /* CParticleSystemSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleSystemSceneNode.h; sourceTree = ""; }; + 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CQ3LevelMesh.cpp; sourceTree = ""; }; + 4C53DFA60A484C240014E966 /* CQ3LevelMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CQ3LevelMesh.h; sourceTree = ""; }; + 4C53DFA70A484C240014E966 /* CReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CReadFile.cpp; sourceTree = ""; }; + 4C53DFA80A484C240014E966 /* CReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = CReadFile.h; sourceTree = ""; }; + 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneCollisionManager.cpp; sourceTree = ""; }; + 4C53DFAA0A484C240014E966 /* CSceneCollisionManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneCollisionManager.h; sourceTree = ""; }; + 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneManager.cpp; sourceTree = ""; }; + 4C53DFAC0A484C240014E966 /* CSceneManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneManager.h; sourceTree = ""; }; + 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorCollisionResponse.cpp; sourceTree = ""; }; + 4C53DFAE0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorCollisionResponse.h; sourceTree = ""; }; + 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorDelete.cpp; sourceTree = ""; }; + 4C53DFB00A484C240014E966 /* CSceneNodeAnimatorDelete.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorDelete.h; sourceTree = ""; }; + 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFlyCircle.cpp; sourceTree = ""; }; + 4C53DFB20A484C240014E966 /* CSceneNodeAnimatorFlyCircle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFlyCircle.h; sourceTree = ""; }; + 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFlyStraight.cpp; sourceTree = ""; }; + 4C53DFB40A484C240014E966 /* CSceneNodeAnimatorFlyStraight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFlyStraight.h; sourceTree = ""; }; + 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFollowSpline.cpp; sourceTree = ""; }; + 4C53DFB60A484C240014E966 /* CSceneNodeAnimatorFollowSpline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFollowSpline.h; sourceTree = ""; }; + 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorRotation.cpp; sourceTree = ""; }; + 4C53DFB80A484C240014E966 /* CSceneNodeAnimatorRotation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorRotation.h; sourceTree = ""; }; + 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorTexture.cpp; sourceTree = ""; }; + 4C53DFBA0A484C240014E966 /* CSceneNodeAnimatorTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorTexture.h; sourceTree = ""; }; + 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CShadowVolumeSceneNode.cpp; sourceTree = ""; }; + 4C53DFBC0A484C240014E966 /* CShadowVolumeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CShadowVolumeSceneNode.h; sourceTree = ""; }; + 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSkyBoxSceneNode.cpp; sourceTree = ""; }; + 4C53DFBE0A484C240014E966 /* CSkyBoxSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSkyBoxSceneNode.h; sourceTree = ""; }; + 4C53DFBF0A484C240014E966 /* CSoftware2MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftware2MaterialRenderer.h; sourceTree = ""; }; + 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareDriver.cpp; sourceTree = ""; }; + 4C53DFC10A484C240014E966 /* CSoftwareDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareDriver.h; sourceTree = ""; }; + 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareDriver2.cpp; sourceTree = ""; }; + 4C53DFC30A484C240014E966 /* CSoftwareDriver2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareDriver2.h; sourceTree = ""; }; + 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareTexture.cpp; sourceTree = ""; }; + 4C53DFC50A484C240014E966 /* CSoftwareTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareTexture.h; sourceTree = ""; }; + 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareTexture2.cpp; sourceTree = ""; }; + 4C53DFC70A484C240014E966 /* CSoftwareTexture2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareTexture2.h; sourceTree = ""; }; + 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTerrainSceneNode.cpp; sourceTree = ""; }; + 4C53DFCB0A484C240014E966 /* CTerrainSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTerrainSceneNode.h; sourceTree = ""; }; + 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTerrainTriangleSelector.cpp; sourceTree = ""; }; + 4C53DFCD0A484C240014E966 /* CTerrainTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTerrainTriangleSelector.h; sourceTree = ""; }; + 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTextSceneNode.cpp; sourceTree = ""; }; + 4C53DFCF0A484C240014E966 /* CTextSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTextSceneNode.h; sourceTree = ""; }; + 4C53DFD00A484C240014E966 /* CTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTimer.h; sourceTree = ""; }; + 4C53DFD10A484C240014E966 /* CTRFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRFlat.cpp; sourceTree = ""; }; + 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRFlatWire.cpp; sourceTree = ""; }; + 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraud.cpp; sourceTree = ""; }; + 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraud2.cpp; sourceTree = ""; }; + 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudAlpha2.cpp; sourceTree = ""; }; + 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudAlphaNoZ2.cpp; sourceTree = ""; }; + 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudWire.cpp; sourceTree = ""; }; + 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTriangleBBSelector.cpp; sourceTree = ""; }; + 4C53DFD90A484C250014E966 /* CTriangleBBSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTriangleBBSelector.h; sourceTree = ""; }; + 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTriangleSelector.cpp; sourceTree = ""; }; + 4C53DFDB0A484C250014E966 /* CTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTriangleSelector.h; sourceTree = ""; }; + 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureDetailMap2.cpp; sourceTree = ""; }; + 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureFlat.cpp; sourceTree = ""; }; + 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureFlatWire.cpp; sourceTree = ""; }; + 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraud.cpp; sourceTree = ""; }; + 4C53DFE00A484C250014E966 /* CTRTextureGouraud.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTRTextureGouraud.h; sourceTree = ""; }; + 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraud2.cpp; sourceTree = ""; }; + 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAdd.cpp; sourceTree = ""; }; + 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAdd2.cpp; sourceTree = ""; }; + 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAddNoZ2.cpp; sourceTree = ""; }; + 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudNoZ.cpp; sourceTree = ""; }; + 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudNoZ2.cpp; sourceTree = ""; }; + 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudVertexAlpha2.cpp; sourceTree = ""; }; + 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudWire.cpp; sourceTree = ""; }; + 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_Add.cpp; sourceTree = ""; }; + 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M1.cpp; sourceTree = ""; }; + 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M2.cpp; sourceTree = ""; }; + 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M4.cpp; sourceTree = ""; }; + 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureWire2.cpp; sourceTree = ""; }; + 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVideoModeList.cpp; sourceTree = ""; }; + 4C53DFEF0A484C250014E966 /* CVideoModeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVideoModeList.h; sourceTree = ""; }; + 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CWaterSurfaceSceneNode.cpp; sourceTree = ""; }; + 4C53DFF10A484C250014E966 /* CWaterSurfaceSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CWaterSurfaceSceneNode.h; sourceTree = ""; }; + 4C53DFF20A484C250014E966 /* CWriteFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CWriteFile.cpp; sourceTree = ""; }; + 4C53DFF30A484C250014E966 /* CWriteFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CWriteFile.h; sourceTree = ""; }; + 4C53DFF40A484C250014E966 /* CXAnimationPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXAnimationPlayer.cpp; sourceTree = ""; }; + 4C53DFF50A484C250014E966 /* CXAnimationPlayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXAnimationPlayer.h; sourceTree = ""; }; + 4C53DFF60A484C250014E966 /* CXFileReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXFileReader.cpp; sourceTree = ""; }; + 4C53DFF70A484C250014E966 /* CXFileReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXFileReader.h; sourceTree = ""; }; + 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DFF90A484C250014E966 /* CXMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMeshFileLoader.h; sourceTree = ""; }; + 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMLReader.cpp; sourceTree = ""; }; + 4C53DFFB0A484C250014E966 /* CXMLReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLReader.h; sourceTree = ""; }; + 4C53DFFC0A484C250014E966 /* CXMLReaderImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLReaderImpl.h; sourceTree = ""; }; + 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMLWriter.cpp; sourceTree = ""; }; + 4C53DFFE0A484C250014E966 /* CXMLWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLWriter.h; sourceTree = ""; }; + 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CZBuffer.cpp; sourceTree = ""; }; + 4C53E0000A484C250014E966 /* CZBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CZBuffer.h; sourceTree = ""; }; + 4C53E0030A484C250014E966 /* CZipReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CZipReader.cpp; sourceTree = ""; }; + 4C53E0040A484C250014E966 /* CZipReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CZipReader.h; sourceTree = ""; }; + 4C53E0050A484C250014E966 /* dmfsupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dmfsupport.h; sourceTree = ""; }; + 4C53E0070A484C250014E966 /* glext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = glext.h; sourceTree = ""; }; + 4C53E0090A484C250014E966 /* IImagePresenter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImagePresenter.h; sourceTree = ""; }; + 4C53E00A0A484C250014E966 /* Irrlicht.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Irrlicht.cpp; sourceTree = ""; }; + 4C53E00E0A484C250014E966 /* irrXML.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = irrXML.cpp; sourceTree = ""; }; + 4C53E00F0A484C250014E966 /* ITriangleRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITriangleRenderer.h; sourceTree = ""; }; + 4C53E0110A484C250014E966 /* IZBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IZBuffer.h; sourceTree = ""; }; + 4C53E1010A484C2A0014E966 /* png.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = png.c; sourceTree = ""; }; + 4C53E1090A484C2A0014E966 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngerror.c; sourceTree = ""; }; + 4C53E10D0A484C2A0014E966 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngget.c; sourceTree = ""; }; + 4C53E10E0A484C2A0014E966 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngmem.c; sourceTree = ""; }; + 4C53E1130A484C2A0014E966 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngpread.c; sourceTree = ""; }; + 4C53E1140A484C2A0014E966 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngread.c; sourceTree = ""; }; + 4C53E1150A484C2A0014E966 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngrio.c; sourceTree = ""; }; + 4C53E1160A484C2A0014E966 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngrtran.c; sourceTree = ""; }; + 4C53E1170A484C2A0014E966 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngrutil.c; sourceTree = ""; }; + 4C53E1180A484C2A0014E966 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngset.c; sourceTree = ""; }; + 4C53E11D0A484C2B0014E966 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngtrans.c; sourceTree = ""; }; + 4C53E1210A484C2B0014E966 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngwio.c; sourceTree = ""; }; + 4C53E1230A484C2B0014E966 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngwtran.c; sourceTree = ""; }; + 4C53E1240A484C2B0014E966 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = pngwutil.c; sourceTree = ""; }; + 4C53E14C0A484C2C0014E966 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = ""; }; + 4C53E15E0A484C2C0014E966 /* CIrrDeviceMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceMacOSX.h; sourceTree = ""; }; + 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = CIrrDeviceMacOSX.mm; sourceTree = ""; }; + 4C53E1640A484C2C0014E966 /* MacOSX_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacOSX_Prefix.pch; sourceTree = ""; }; + 4C53E1650A484C2C0014E966 /* MainMenu.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = MainMenu.nib; sourceTree = ""; }; + 4C53E1660A484C2C0014E966 /* OSXClipboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OSXClipboard.h; sourceTree = ""; }; + 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = OSXClipboard.mm; sourceTree = ""; }; + 4C53E1690A484C2C0014E966 /* OctTree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OctTree.h; sourceTree = ""; }; + 4C53E16A0A484C2C0014E966 /* os.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = os.cpp; sourceTree = ""; }; + 4C53E16B0A484C2C0014E966 /* os.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = os.h; sourceTree = ""; }; + 4C53E16C0A484C2C0014E966 /* S2DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S2DVertex.h; sourceTree = ""; }; + 4C53E16D0A484C2C0014E966 /* S4DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S4DVertex.h; sourceTree = ""; }; + 4C53E16E0A484C2C0014E966 /* SoftwareDriver2_compile_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoftwareDriver2_compile_config.h; sourceTree = ""; }; + 4C53E16F0A484C2C0014E966 /* SoftwareDriver2_helper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoftwareDriver2_helper.h; sourceTree = ""; }; + 4C53E1720A484C2C0014E966 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = adler32.c; sourceTree = ""; }; + 4C53E1750A484C2C0014E966 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = ""; }; + 4C53E1770A484C2C0014E966 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = crc32.c; sourceTree = ""; }; + 4C53E1790A484C2C0014E966 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = deflate.c; sourceTree = ""; }; + 4C53E17D0A484C2C0014E966 /* gzio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = gzio.c; sourceTree = ""; }; + 4C53E1800A484C2C0014E966 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inffast.c; sourceTree = ""; }; + 4C53E1850A484C2C0014E966 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inftrees.c; sourceTree = ""; }; + 4C53E18B0A484C2C0014E966 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = trees.c; sourceTree = ""; }; + 4C53E18D0A484C2C0014E966 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = uncompr.c; sourceTree = ""; }; + 4C53E1920A484C2C0014E966 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = zutil.c; sourceTree = ""; }; + 4C53E24D0A4850120014E966 /* libIrrlicht.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIrrlicht.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C53E2520A4850550014E966 /* Quake3Map.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Quake3Map.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C53E26D0A4850D60014E966 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 4C53E26E0A4850D60014E966 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "DemoApp-Info.plist"; sourceTree = ""; }; + 4C53E6F10A485CD80014E966 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapimin.c; sourceTree = ""; }; + 4C53E6F20A485CD80014E966 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapistd.c; sourceTree = ""; }; + 4C53E6F30A485CD80014E966 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccoefct.c; sourceTree = ""; }; + 4C53E6F40A485CD80014E966 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccolor.c; sourceTree = ""; }; + 4C53E6F50A485CD80014E966 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcdctmgr.c; sourceTree = ""; }; + 4C53E6F60A485CD80014E966 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jchuff.c; sourceTree = ""; }; + 4C53E6F80A485CD80014E966 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcinit.c; sourceTree = ""; }; + 4C53E6F90A485CD80014E966 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmainct.c; sourceTree = ""; }; + 4C53E6FA0A485CD80014E966 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmarker.c; sourceTree = ""; }; + 4C53E6FB0A485CD80014E966 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmaster.c; sourceTree = ""; }; + 4C53E6FC0A485CD80014E966 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcomapi.c; sourceTree = ""; }; + 4C53E70A0A485CD80014E966 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcparam.c; sourceTree = ""; }; + 4C53E70B0A485CD80014E966 /* jcphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcphuff.c; sourceTree = ""; }; + 4C53E70C0A485CD80014E966 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcprepct.c; sourceTree = ""; }; + 4C53E70D0A485CD80014E966 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcsample.c; sourceTree = ""; }; + 4C53E70E0A485CD80014E966 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jctrans.c; sourceTree = ""; }; + 4C53E70F0A485CD80014E966 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapimin.c; sourceTree = ""; }; + 4C53E7100A485CD80014E966 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapistd.c; sourceTree = ""; }; + 4C53E7110A485CD80014E966 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatadst.c; sourceTree = ""; }; + 4C53E7120A485CD80014E966 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatasrc.c; sourceTree = ""; }; + 4C53E7130A485CD80014E966 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcoefct.c; sourceTree = ""; }; + 4C53E7140A485CD80014E966 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcolor.c; sourceTree = ""; }; + 4C53E7160A485CD80014E966 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jddctmgr.c; sourceTree = ""; }; + 4C53E7170A485CD80014E966 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdhuff.c; sourceTree = ""; }; + 4C53E7190A485CD80014E966 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdinput.c; sourceTree = ""; }; + 4C53E71A0A485CD80014E966 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmainct.c; sourceTree = ""; }; + 4C53E71B0A485CD80014E966 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmarker.c; sourceTree = ""; }; + 4C53E71C0A485CD80014E966 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmaster.c; sourceTree = ""; }; + 4C53E71D0A485CD80014E966 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmerge.c; sourceTree = ""; }; + 4C53E71E0A485CD80014E966 /* jdphuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdphuff.c; sourceTree = ""; }; + 4C53E71F0A485CD80014E966 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdpostct.c; sourceTree = ""; }; + 4C53E7200A485CD80014E966 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdsample.c; sourceTree = ""; }; + 4C53E7210A485CD80014E966 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdtrans.c; sourceTree = ""; }; + 4C53E7220A485CD80014E966 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jerror.c; sourceTree = ""; }; + 4C53E7240A485CD80014E966 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctflt.c; sourceTree = ""; }; + 4C53E7250A485CD80014E966 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctfst.c; sourceTree = ""; }; + 4C53E7260A485CD80014E966 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctint.c; sourceTree = ""; }; + 4C53E7270A485CD80014E966 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctflt.c; sourceTree = ""; }; + 4C53E7280A485CD80014E966 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctfst.c; sourceTree = ""; }; + 4C53E7290A485CD80014E966 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctint.c; sourceTree = ""; }; + 4C53E72A0A485CD80014E966 /* jidctred.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctred.c; sourceTree = ""; }; + 4C53E7300A485CD80014E966 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemmgr.c; sourceTree = ""; }; + 4C53E7320A485CD80014E966 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemnobs.c; sourceTree = ""; }; + 4C53E7390A485CD80014E966 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant1.c; sourceTree = ""; }; + 4C53E73A0A485CD80014E966 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant2.c; sourceTree = ""; }; + 4C53E73B0A485CD80014E966 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jutils.c; sourceTree = ""; }; + 4C53E7540A485CD90014E966 /* rdbmp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdbmp.c; sourceTree = ""; }; + 4C53E7550A485CD90014E966 /* rdcolmap.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdcolmap.c; sourceTree = ""; }; + 4C53E7560A485CD90014E966 /* rdgif.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdgif.c; sourceTree = ""; }; + 4C53E7590A485CD90014E966 /* rdppm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdppm.c; sourceTree = ""; }; + 4C53E75A0A485CD90014E966 /* rdrle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdrle.c; sourceTree = ""; }; + 4C53E75B0A485CD90014E966 /* rdswitch.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdswitch.c; sourceTree = ""; }; + 4C53E75C0A485CD90014E966 /* rdtarga.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = rdtarga.c; sourceTree = ""; }; + 4C53E7660A485CD90014E966 /* transupp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = transupp.c; sourceTree = ""; }; + 4C53E76A0A485CD90014E966 /* wrbmp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrbmp.c; sourceTree = ""; }; + 4C53E76B0A485CD90014E966 /* wrgif.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrgif.c; sourceTree = ""; }; + 4C53E76E0A485CD90014E966 /* wrppm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrppm.c; sourceTree = ""; }; + 4C53E76F0A485CD90014E966 /* wrrle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrrle.c; sourceTree = ""; }; + 4C53E7700A485CD90014E966 /* wrtarga.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrtarga.c; sourceTree = ""; }; + 4C6DC9B60A48715A0017A6E5 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inflate.c; sourceTree = ""; }; + 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9E0A485D9800B4E469 /* UserInterface.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerPixelLighting.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA20A485D9800B4E469 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA40A485D9800B4E469 /* Movement.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA60A485D9800B4E469 /* Shaders.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Shaders.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA80A485D9800B4E469 /* SpecialFx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAE0A485D9800B4E469 /* Collision.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSphereSceneNode.cpp; sourceTree = ""; }; + 4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSphereSceneNode.h; sourceTree = ""; }; + 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderBMP.cpp; sourceTree = ""; }; + 4CFA7BDD0A88735900B03626 /* CImageLoaderBMP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderBMP.h; sourceTree = ""; }; + 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterBMP.cpp; sourceTree = ""; }; + 4CFA7BDF0A88735900B03626 /* CImageWriterBMP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterBMP.h; sourceTree = ""; }; + 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterJPG.cpp; sourceTree = ""; }; + 4CFA7BE10A88735900B03626 /* CImageWriterJPG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterJPG.h; sourceTree = ""; }; + 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPCX.cpp; sourceTree = ""; }; + 4CFA7BE30A88735900B03626 /* CImageWriterPCX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPCX.h; sourceTree = ""; }; + 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPNG.cpp; sourceTree = ""; }; + 4CFA7BE50A88735900B03626 /* CImageWriterPNG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPNG.h; sourceTree = ""; }; + 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPPM.cpp; sourceTree = ""; }; + 4CFA7BE70A88735900B03626 /* CImageWriterPPM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPPM.h; sourceTree = ""; }; + 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPSD.cpp; sourceTree = ""; }; + 4CFA7BE90A88735900B03626 /* CImageWriterPSD.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPSD.h; sourceTree = ""; }; + 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterTGA.cpp; sourceTree = ""; }; + 4CFA7BEB0A88735900B03626 /* CImageWriterTGA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterTGA.h; sourceTree = ""; }; + 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSkyDomeSceneNode.cpp; sourceTree = ""; }; + 4CFA7BED0A88735A00B03626 /* CSkyDomeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSkyDomeSceneNode.h; sourceTree = ""; }; + 4CFA7C0A0A88742800B03626 /* aabbox3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = aabbox3d.h; sourceTree = ""; }; + 4CFA7C0B0A88742800B03626 /* dimension2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dimension2d.h; sourceTree = ""; }; + 4CFA7C0C0A88742800B03626 /* EDriverTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EDriverTypes.h; sourceTree = ""; }; + 4CFA7C0D0A88742800B03626 /* EGUIElementTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EGUIElementTypes.h; sourceTree = ""; }; + 4CFA7C0E0A88742800B03626 /* ESceneNodeAnimatorTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ESceneNodeAnimatorTypes.h; sourceTree = ""; }; + 4CFA7C0F0A88742800B03626 /* ESceneNodeTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ESceneNodeTypes.h; sourceTree = ""; }; + 4CFA7C100A88742800B03626 /* heapsort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = heapsort.h; sourceTree = ""; }; + 4CFA7C110A88742900B03626 /* IAnimatedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMesh.h; sourceTree = ""; }; + 4CFA7C120A88742900B03626 /* IAnimatedMeshB3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshB3d.h; sourceTree = ""; }; + 4CFA7C130A88742900B03626 /* IAnimatedMeshMD2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshMD2.h; sourceTree = ""; }; + 4CFA7C140A88742900B03626 /* IAnimatedMeshMS3D.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshMS3D.h; sourceTree = ""; }; + 4CFA7C150A88742900B03626 /* IAnimatedMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshSceneNode.h; sourceTree = ""; }; + 4CFA7C160A88742900B03626 /* IAnimatedMeshX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshX.h; sourceTree = ""; }; + 4CFA7C170A88742900B03626 /* IAttributeExchangingObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAttributeExchangingObject.h; sourceTree = ""; }; + 4CFA7C180A88742900B03626 /* IAttributes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAttributes.h; sourceTree = ""; }; + 4CFA7C190A88742900B03626 /* IBillboardSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IBillboardSceneNode.h; sourceTree = ""; }; + 4CFA7C1A0A88742900B03626 /* ICameraSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ICameraSceneNode.h; sourceTree = ""; }; + 4CFA7C1B0A88742900B03626 /* ICursorControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ICursorControl.h; sourceTree = ""; }; + 4CFA7C1C0A88742900B03626 /* IDummyTransformationSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IDummyTransformationSceneNode.h; sourceTree = ""; }; + 4CFA7C1D0A88742900B03626 /* IEventReceiver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IEventReceiver.h; sourceTree = ""; }; + 4CFA7C1E0A88742900B03626 /* IFileList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IFileList.h; sourceTree = ""; }; + 4CFA7C1F0A88742900B03626 /* IFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IFileSystem.h; sourceTree = ""; }; + 4CFA7C200A88742900B03626 /* IGPUProgrammingServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGPUProgrammingServices.h; sourceTree = ""; }; + 4CFA7C210A88742900B03626 /* IGUIButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIButton.h; sourceTree = ""; }; + 4CFA7C220A88742900B03626 /* IGUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUICheckBox.h; sourceTree = ""; }; + 4CFA7C230A88742900B03626 /* IGUIComboBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIComboBox.h; sourceTree = ""; }; + 4CFA7C240A88742900B03626 /* IGUIContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIContextMenu.h; sourceTree = ""; }; + 4CFA7C250A88742900B03626 /* IGUIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIEditBox.h; sourceTree = ""; }; + 4CFA7C260A88742900B03626 /* IGUIElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIElement.h; sourceTree = ""; }; + 4CFA7C270A88742900B03626 /* IGUIEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIEnvironment.h; sourceTree = ""; }; + 4CFA7C280A88742900B03626 /* IGUIFileOpenDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIFileOpenDialog.h; sourceTree = ""; }; + 4CFA7C290A88742900B03626 /* IGUIFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIFont.h; sourceTree = ""; }; + 4CFA7C2A0A88742900B03626 /* IGUIImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIImage.h; sourceTree = ""; }; + 4CFA7C2B0A88742900B03626 /* IGUIInOutFader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIInOutFader.h; sourceTree = ""; }; + 4CFA7C2C0A88742900B03626 /* IGUIListBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIListBox.h; sourceTree = ""; }; + 4CFA7C2D0A88742900B03626 /* IGUIMeshViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIMeshViewer.h; sourceTree = ""; }; + 4CFA7C2E0A88742900B03626 /* IGUIScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIScrollBar.h; sourceTree = ""; }; + 4CFA7C2F0A88742900B03626 /* IGUISkin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUISkin.h; sourceTree = ""; }; + 4CFA7C300A88742900B03626 /* IGUIStaticText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIStaticText.h; sourceTree = ""; }; + 4CFA7C310A88742900B03626 /* IGUITabControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUITabControl.h; sourceTree = ""; }; + 4CFA7C320A88742900B03626 /* IGUIToolbar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIToolbar.h; sourceTree = ""; }; + 4CFA7C330A88742900B03626 /* IGUIWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIWindow.h; sourceTree = ""; }; + 4CFA7C340A88742900B03626 /* IImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImage.h; sourceTree = ""; }; + 4CFA7C350A88742900B03626 /* IImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImageLoader.h; sourceTree = ""; }; + 4CFA7C360A88742900B03626 /* IImageWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImageWriter.h; sourceTree = ""; }; + 4CFA7C370A88742900B03626 /* ILightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ILightSceneNode.h; sourceTree = ""; }; + 4CFA7C380A88742900B03626 /* ILogger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ILogger.h; sourceTree = ""; }; + 4CFA7C390A88742900B03626 /* IMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMaterialRenderer.h; sourceTree = ""; }; + 4CFA7C3A0A88742900B03626 /* IMaterialRendererServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMaterialRendererServices.h; sourceTree = ""; }; + 4CFA7C3B0A88742900B03626 /* IMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMesh.h; sourceTree = ""; }; + 4CFA7C3C0A88742900B03626 /* IMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshBuffer.h; sourceTree = ""; }; + 4CFA7C3D0A88742900B03626 /* IMeshCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshCache.h; sourceTree = ""; }; + 4CFA7C3E0A88742900B03626 /* IMeshLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshLoader.h; sourceTree = ""; }; + 4CFA7C3F0A88742900B03626 /* IMeshManipulator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshManipulator.h; sourceTree = ""; }; + 4CFA7C400A88742900B03626 /* IMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshSceneNode.h; sourceTree = ""; }; + 4CFA7C410A88742900B03626 /* IMetaTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMetaTriangleSelector.h; sourceTree = ""; }; + 4CFA7C420A88742900B03626 /* IOSOperator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IOSOperator.h; sourceTree = ""; }; + 4CFA7C430A88742900B03626 /* IParticleAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleAffector.h; sourceTree = ""; }; + 4CFA7C440A88742900B03626 /* IParticleEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleEmitter.h; sourceTree = ""; }; + 4CFA7C450A88742900B03626 /* IParticleSystemSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleSystemSceneNode.h; sourceTree = ""; }; + 4CFA7C460A88742900B03626 /* IQ3LevelMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IQ3LevelMesh.h; sourceTree = ""; }; + 4CFA7C470A88742900B03626 /* IReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = IReadFile.h; sourceTree = ""; }; + 4CFA7C480A88742900B03626 /* irrAllocator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrAllocator.h; sourceTree = ""; }; + 4CFA7C490A88742900B03626 /* irrArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrArray.h; sourceTree = ""; }; + 4CFA7C4A0A88742900B03626 /* IrrCompileConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IrrCompileConfig.h; sourceTree = ""; }; + 4CFA7C4B0A88742900B03626 /* irrlicht.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrlicht.h; sourceTree = ""; }; + 4CFA7C4C0A88742900B03626 /* IrrlichtDevice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IrrlichtDevice.h; sourceTree = ""; }; + 4CFA7C4D0A88742900B03626 /* irrList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrList.h; sourceTree = ""; }; + 4CFA7C4E0A88742900B03626 /* irrMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrMath.h; sourceTree = ""; }; + 4CFA7C4F0A88742900B03626 /* irrString.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrString.h; sourceTree = ""; }; + 4CFA7C500A88742900B03626 /* irrTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = irrTypes.h; sourceTree = ""; }; + 4CFA7C510A88742900B03626 /* irrXML.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrXML.h; sourceTree = ""; }; + 4CFA7C520A88742900B03626 /* ISceneCollisionManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneCollisionManager.h; sourceTree = ""; }; + 4CFA7C530A88742900B03626 /* ISceneManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneManager.h; sourceTree = ""; }; + 4CFA7C540A88742900B03626 /* ISceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNode.h; sourceTree = ""; }; + 4CFA7C550A88742900B03626 /* ISceneNodeAnimator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimator.h; sourceTree = ""; }; + 4CFA7C560A88742900B03626 /* ISceneNodeAnimatorCollisionResponse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimatorCollisionResponse.h; sourceTree = ""; }; + 4CFA7C570A88742900B03626 /* ISceneNodeAnimatorFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimatorFactory.h; sourceTree = ""; }; + 4CFA7C580A88742900B03626 /* ISceneNodeFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeFactory.h; sourceTree = ""; }; + 4CFA7C590A88742900B03626 /* ISceneUserDataSerializer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneUserDataSerializer.h; sourceTree = ""; }; + 4CFA7C5A0A88742900B03626 /* IShaderConstantSetCallBack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IShaderConstantSetCallBack.h; sourceTree = ""; }; + 4CFA7C5B0A88742900B03626 /* IShadowVolumeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IShadowVolumeSceneNode.h; sourceTree = ""; }; + 4CFA7C5C0A88742900B03626 /* ITerrainSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITerrainSceneNode.h; sourceTree = ""; }; + 4CFA7C5D0A88742900B03626 /* ITextSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITextSceneNode.h; sourceTree = ""; }; + 4CFA7C5E0A88742900B03626 /* ITexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITexture.h; sourceTree = ""; }; + 4CFA7C5F0A88742900B03626 /* ITimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITimer.h; sourceTree = ""; }; + 4CFA7C600A88742900B03626 /* ITriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITriangleSelector.h; sourceTree = ""; }; + 4CFA7C610A88742900B03626 /* IUnknown.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IUnknown.h; sourceTree = ""; }; + 4CFA7C620A88742900B03626 /* IVideoDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IVideoDriver.h; sourceTree = ""; }; + 4CFA7C630A88742900B03626 /* IVideoModeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IVideoModeList.h; sourceTree = ""; }; + 4CFA7C640A88742900B03626 /* IWriteFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IWriteFile.h; sourceTree = ""; }; + 4CFA7C650A88742900B03626 /* IXMLReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IXMLReader.h; sourceTree = ""; }; + 4CFA7C660A88742900B03626 /* IXMLWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IXMLWriter.h; sourceTree = ""; }; + 4CFA7C670A88742900B03626 /* Keycodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Keycodes.h; sourceTree = ""; }; + 4CFA7C680A88742900B03626 /* line2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = line2d.h; sourceTree = ""; }; + 4CFA7C690A88742900B03626 /* line3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = line3d.h; sourceTree = ""; }; + 4CFA7C6A0A88742900B03626 /* matrix4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = matrix4.h; sourceTree = ""; }; + 4CFA7C6B0A88742900B03626 /* plane3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plane3d.h; sourceTree = ""; }; + 4CFA7C6C0A88742900B03626 /* position2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = position2d.h; sourceTree = ""; }; + 4CFA7C6D0A88742900B03626 /* quaternion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = quaternion.h; sourceTree = ""; }; + 4CFA7C6E0A88742900B03626 /* rect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = rect.h; sourceTree = ""; }; + 4CFA7C6F0A88742900B03626 /* S3DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S3DVertex.h; sourceTree = ""; }; + 4CFA7C700A88742900B03626 /* SAnimatedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SAnimatedMesh.h; sourceTree = ""; }; + 4CFA7C710A88742900B03626 /* SceneParameters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SceneParameters.h; sourceTree = ""; }; + 4CFA7C720A88742900B03626 /* SColor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SColor.h; sourceTree = ""; }; + 4CFA7C730A88742900B03626 /* SExposedVideoData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SExposedVideoData.h; sourceTree = ""; }; + 4CFA7C740A88742900B03626 /* SIrrCreationParameters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SIrrCreationParameters.h; sourceTree = ""; }; + 4CFA7C750A88742900B03626 /* SKeyMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SKeyMap.h; sourceTree = ""; }; + 4CFA7C760A88742900B03626 /* SLight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SLight.h; sourceTree = ""; }; + 4CFA7C770A88742900B03626 /* SMaterial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMaterial.h; sourceTree = ""; }; + 4CFA7C780A88742900B03626 /* SMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMesh.h; sourceTree = ""; }; + 4CFA7C790A88742900B03626 /* SMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBuffer.h; sourceTree = ""; }; + 4CFA7C7A0A88742900B03626 /* SMeshBufferLightMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBufferLightMap.h; sourceTree = ""; }; + 4CFA7C7B0A88742900B03626 /* SMeshBufferTangents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBufferTangents.h; sourceTree = ""; }; + 4CFA7C7C0A88742900B03626 /* SParticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SParticle.h; sourceTree = ""; }; + 4CFA7C7D0A88742900B03626 /* SViewFrustrum.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SViewFrustrum.h; sourceTree = ""; }; + 4CFA7C7E0A88742900B03626 /* triangle3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = triangle3d.h; sourceTree = ""; }; + 4CFA7C7F0A88742900B03626 /* vector2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vector2d.h; sourceTree = ""; }; + 4CFA7C800A88742900B03626 /* vector3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vector3d.h; sourceTree = ""; }; + 5DD480470C7D8B9100728AA9 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pngwrite.c; sourceTree = ""; }; + 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDepthBuffer.cpp; sourceTree = ""; }; + 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDepthBuffer.h; sourceTree = ""; }; + 5DD480500C7D936700728AA9 /* IBurningShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IBurningShader.cpp; sourceTree = ""; }; + 5DD480510C7D936700728AA9 /* IBurningShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IBurningShader.h; sourceTree = ""; }; + 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDepthBuffer.h; sourceTree = ""; }; + 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAnimatedMeshMD3.cpp; sourceTree = ""; }; + 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshMD3.h; sourceTree = ""; }; + 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultGUIElementFactory.cpp; sourceTree = ""; }; + 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDefaultGUIElementFactory.h; sourceTree = ""; }; + 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIColorSelectDialog.cpp; sourceTree = ""; }; + 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUIColorSelectDialog.h; sourceTree = ""; }; + 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISpinBox.cpp; sourceTree = ""; }; + 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUISpinBox.h; sourceTree = ""; }; + 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISpriteBank.cpp; sourceTree = ""; }; + 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUISpriteBank.h; sourceTree = ""; }; + 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CQuake3ShaderSceneNode.cpp; sourceTree = ""; }; + 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CQuake3ShaderSceneNode.h; sourceTree = ""; }; + 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureBlend.cpp; sourceTree = ""; }; + 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAlpha.cpp; sourceTree = ""; }; + 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAlphaNoZ.cpp; sourceTree = ""; }; + 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMapGouraud2_M4.cpp; sourceTree = ""; }; + 5DD480700C7D94AC00728AA9 /* glxext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glxext.h; sourceTree = ""; }; + 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = COpenGLExtensionHandler.h; sourceTree = ""; }; + 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMD3MeshFileLoader.h; sourceTree = ""; }; + 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceSDL.h; sourceTree = ""; }; + 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceSDL.cpp; sourceTree = ""; }; + 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLExtensionHandler.cpp; sourceTree = ""; }; + 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CMD3MeshFileLoader.cpp; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B81CFE08097FD9F50057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F50A486648006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2750A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2760A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE89097FDDE20057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1470A0A4866FA006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2770A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2780A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEAB097FDE900057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB40A486A1600ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27F0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2800A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC9097FDF020057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB70A486A2500ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2810A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2820A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEEF097FE05F0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147190A48676E006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2790A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27A0A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0E097FE13E0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8D0A48628200B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E2730A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2740A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF25097FE1E00057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C520A48618800B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E26F0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2700A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF3A097FE25F0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E2510A4850550014E966 /* libIrrlicht.a in Frameworks */, + 4C53E2870A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2880A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF51097FE3050057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB10A486A0200ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27D0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27E0A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7F097FE3DC0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C560A4861AE00B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E2710A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2720A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF98097FE45E0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBAF0A4869F300ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27B0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27C0A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB6097FE5F80057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBA0A486A3A00ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2830A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2840A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF35B0950229200FDEA7E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBF0A486A5700ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2850A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2860A4850D60014E966 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC07C0554694100DB518D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0867D691FE84028FC02AAC07 /* MacOSX */ = { + isa = PBXGroup; + children = ( + 4CFA7C090A88742800B03626 /* include */, + 4C53DEE50A484C220014E966 /* Irrlicht */, + 4C00546D0A48470500C844C2 /* examples */, + 4C53E2540A48505D0014E966 /* Libraries */, + 4C53E24C0A484FED0014E966 /* Products */, + ); + name = MacOSX; + sourceTree = ""; + }; + 4C00546D0A48470500C844C2 /* examples */ = { + isa = PBXGroup; + children = ( + 4C00546E0A48470500C844C2 /* 01.HelloWorld */, + 4C0054740A48470500C844C2 /* 02.Quake3Map */, + 4C00547A0A48470500C844C2 /* 03.CustomSceneNode */, + 4C0054800A48470500C844C2 /* 04.Movement */, + 4C0054860A48470500C844C2 /* 05.UserInterface */, + 4C00548C0A48470500C844C2 /* 06.2DGraphics */, + 4C0054920A48470500C844C2 /* 07.Collision */, + 4C0054980A48470500C844C2 /* 08.SpecialFX */, + 4C00549E0A48470500C844C2 /* 09.Meshviewer */, + 4C0054A70A48470500C844C2 /* 10.Shaders */, + 4C0054AD0A48470500C844C2 /* 11.PerPixelLighting */, + 4C0054B30A48470500C844C2 /* 12.TerrainRendering */, + 4C0054B90A48470500C844C2 /* 13.RenderToTexture */, + 4C0054C40A48470500C844C2 /* Demo */, + ); + name = examples; + path = ../../../examples; + sourceTree = SOURCE_ROOT; + }; + 4C00546E0A48470500C844C2 /* 01.HelloWorld */ = { + isa = PBXGroup; + children = ( + 4C0054710A48470500C844C2 /* main.cpp */, + ); + path = 01.HelloWorld; + sourceTree = ""; + }; + 4C0054740A48470500C844C2 /* 02.Quake3Map */ = { + isa = PBXGroup; + children = ( + 4C0054770A48470500C844C2 /* main.cpp */, + ); + path = 02.Quake3Map; + sourceTree = ""; + }; + 4C00547A0A48470500C844C2 /* 03.CustomSceneNode */ = { + isa = PBXGroup; + children = ( + 4C00547D0A48470500C844C2 /* main.cpp */, + ); + path = 03.CustomSceneNode; + sourceTree = ""; + }; + 4C0054800A48470500C844C2 /* 04.Movement */ = { + isa = PBXGroup; + children = ( + 4C0054830A48470500C844C2 /* main.cpp */, + ); + path = 04.Movement; + sourceTree = ""; + }; + 4C0054860A48470500C844C2 /* 05.UserInterface */ = { + isa = PBXGroup; + children = ( + 4C0054890A48470500C844C2 /* main.cpp */, + ); + path = 05.UserInterface; + sourceTree = ""; + }; + 4C00548C0A48470500C844C2 /* 06.2DGraphics */ = { + isa = PBXGroup; + children = ( + 4C00548F0A48470500C844C2 /* main.cpp */, + ); + path = 06.2DGraphics; + sourceTree = ""; + }; + 4C0054920A48470500C844C2 /* 07.Collision */ = { + isa = PBXGroup; + children = ( + 4C0054950A48470500C844C2 /* main.cpp */, + ); + path = 07.Collision; + sourceTree = ""; + }; + 4C0054980A48470500C844C2 /* 08.SpecialFX */ = { + isa = PBXGroup; + children = ( + 4C00549B0A48470500C844C2 /* main.cpp */, + ); + path = 08.SpecialFX; + sourceTree = ""; + }; + 4C00549E0A48470500C844C2 /* 09.Meshviewer */ = { + isa = PBXGroup; + children = ( + 4C0054A30A48470500C844C2 /* main.cpp */, + ); + path = 09.Meshviewer; + sourceTree = ""; + }; + 4C0054A70A48470500C844C2 /* 10.Shaders */ = { + isa = PBXGroup; + children = ( + 4C0054AA0A48470500C844C2 /* main.cpp */, + ); + path = 10.Shaders; + sourceTree = ""; + }; + 4C0054AD0A48470500C844C2 /* 11.PerPixelLighting */ = { + isa = PBXGroup; + children = ( + 4C0054B00A48470500C844C2 /* main.cpp */, + ); + path = 11.PerPixelLighting; + sourceTree = ""; + }; + 4C0054B30A48470500C844C2 /* 12.TerrainRendering */ = { + isa = PBXGroup; + children = ( + 4C0054B60A48470500C844C2 /* main.cpp */, + ); + path = 12.TerrainRendering; + sourceTree = ""; + }; + 4C0054B90A48470500C844C2 /* 13.RenderToTexture */ = { + isa = PBXGroup; + children = ( + 4C0054BC0A48470500C844C2 /* main.cpp */, + ); + path = 13.RenderToTexture; + sourceTree = ""; + }; + 4C0054C40A48470500C844C2 /* Demo */ = { + isa = PBXGroup; + children = ( + 4C0054C50A48470500C844C2 /* CDemo.cpp */, + 4C0054C60A48470500C844C2 /* CDemo.h */, + 4C0054C70A48470500C844C2 /* CMainMenu.cpp */, + 4C0054C80A48470500C844C2 /* CMainMenu.h */, + 4C0054CA0A48470500C844C2 /* main.cpp */, + ); + path = Demo; + sourceTree = ""; + }; + 4C53DEE50A484C220014E966 /* Irrlicht */ = { + isa = PBXGroup; + children = ( + 4C6DC9960A486B110017A6E5 /* Engine */, + 4C53E14A0A484C2C0014E966 /* MacOSX */, + 4C53E0130A484C250014E966 /* jpeglib */, + 4C53E0A80A484C280014E966 /* libpng */, + 4C53E1710A484C2C0014E966 /* zlib */, + ); + name = Irrlicht; + path = ..; + sourceTree = SOURCE_ROOT; + }; + 4C53E0130A484C250014E966 /* jpeglib */ = { + isa = PBXGroup; + children = ( + 4C53E6F10A485CD80014E966 /* jcapimin.c */, + 4C53E6F20A485CD80014E966 /* jcapistd.c */, + 4C53E6F30A485CD80014E966 /* jccoefct.c */, + 4C53E6F40A485CD80014E966 /* jccolor.c */, + 4C53E6F50A485CD80014E966 /* jcdctmgr.c */, + 4C53E6F60A485CD80014E966 /* jchuff.c */, + 4C53E6F80A485CD80014E966 /* jcinit.c */, + 4C53E6F90A485CD80014E966 /* jcmainct.c */, + 4C53E6FA0A485CD80014E966 /* jcmarker.c */, + 4C53E6FB0A485CD80014E966 /* jcmaster.c */, + 4C53E6FC0A485CD80014E966 /* jcomapi.c */, + 4C53E70A0A485CD80014E966 /* jcparam.c */, + 4C53E70B0A485CD80014E966 /* jcphuff.c */, + 4C53E70C0A485CD80014E966 /* jcprepct.c */, + 4C53E70D0A485CD80014E966 /* jcsample.c */, + 4C53E70E0A485CD80014E966 /* jctrans.c */, + 4C53E70F0A485CD80014E966 /* jdapimin.c */, + 4C53E7100A485CD80014E966 /* jdapistd.c */, + 4C53E7110A485CD80014E966 /* jdatadst.c */, + 4C53E7120A485CD80014E966 /* jdatasrc.c */, + 4C53E7130A485CD80014E966 /* jdcoefct.c */, + 4C53E7140A485CD80014E966 /* jdcolor.c */, + 4C53E7160A485CD80014E966 /* jddctmgr.c */, + 4C53E7170A485CD80014E966 /* jdhuff.c */, + 4C53E7190A485CD80014E966 /* jdinput.c */, + 4C53E71A0A485CD80014E966 /* jdmainct.c */, + 4C53E71B0A485CD80014E966 /* jdmarker.c */, + 4C53E71C0A485CD80014E966 /* jdmaster.c */, + 4C53E71D0A485CD80014E966 /* jdmerge.c */, + 4C53E71E0A485CD80014E966 /* jdphuff.c */, + 4C53E71F0A485CD80014E966 /* jdpostct.c */, + 4C53E7200A485CD80014E966 /* jdsample.c */, + 4C53E7210A485CD80014E966 /* jdtrans.c */, + 4C53E7220A485CD80014E966 /* jerror.c */, + 4C53E7240A485CD80014E966 /* jfdctflt.c */, + 4C53E7250A485CD80014E966 /* jfdctfst.c */, + 4C53E7260A485CD80014E966 /* jfdctint.c */, + 4C53E7270A485CD80014E966 /* jidctflt.c */, + 4C53E7280A485CD80014E966 /* jidctfst.c */, + 4C53E7290A485CD80014E966 /* jidctint.c */, + 4C53E72A0A485CD80014E966 /* jidctred.c */, + 4C53E7300A485CD80014E966 /* jmemmgr.c */, + 4C53E7320A485CD80014E966 /* jmemnobs.c */, + 4C53E7390A485CD80014E966 /* jquant1.c */, + 4C53E73A0A485CD80014E966 /* jquant2.c */, + 4C53E73B0A485CD80014E966 /* jutils.c */, + 4C53E7540A485CD90014E966 /* rdbmp.c */, + 4C53E7550A485CD90014E966 /* rdcolmap.c */, + 4C53E7560A485CD90014E966 /* rdgif.c */, + 4C53E7590A485CD90014E966 /* rdppm.c */, + 4C53E75A0A485CD90014E966 /* rdrle.c */, + 4C53E75B0A485CD90014E966 /* rdswitch.c */, + 4C53E75C0A485CD90014E966 /* rdtarga.c */, + 4C53E7660A485CD90014E966 /* transupp.c */, + 4C53E76A0A485CD90014E966 /* wrbmp.c */, + 4C53E76B0A485CD90014E966 /* wrgif.c */, + 4C53E76E0A485CD90014E966 /* wrppm.c */, + 4C53E76F0A485CD90014E966 /* wrrle.c */, + 4C53E7700A485CD90014E966 /* wrtarga.c */, + ); + path = jpeglib; + sourceTree = ""; + }; + 4C53E0A80A484C280014E966 /* libpng */ = { + isa = PBXGroup; + children = ( + 5DD480470C7D8B9100728AA9 /* pngwrite.c */, + 4C53E1010A484C2A0014E966 /* png.c */, + 4C53E1090A484C2A0014E966 /* pngerror.c */, + 4C53E10D0A484C2A0014E966 /* pngget.c */, + 4C53E10E0A484C2A0014E966 /* pngmem.c */, + 4C53E1130A484C2A0014E966 /* pngpread.c */, + 4C53E1140A484C2A0014E966 /* pngread.c */, + 4C53E1150A484C2A0014E966 /* pngrio.c */, + 4C53E1160A484C2A0014E966 /* pngrtran.c */, + 4C53E1170A484C2A0014E966 /* pngrutil.c */, + 4C53E1180A484C2A0014E966 /* pngset.c */, + 4C53E11D0A484C2B0014E966 /* pngtrans.c */, + 4C53E1210A484C2B0014E966 /* pngwio.c */, + 4C53E1230A484C2B0014E966 /* pngwtran.c */, + 4C53E1240A484C2B0014E966 /* pngwutil.c */, + ); + path = libpng; + sourceTree = ""; + }; + 4C53E14A0A484C2C0014E966 /* MacOSX */ = { + isa = PBXGroup; + children = ( + 4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */, + 4C53E14C0A484C2C0014E966 /* AppDelegate.h */, + 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */, + 4C53E14E0A484C2C0014E966 /* build */, + 4C53E15E0A484C2C0014E966 /* CIrrDeviceMacOSX.h */, + 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */, + 4C53E1640A484C2C0014E966 /* MacOSX_Prefix.pch */, + 4C53E1650A484C2C0014E966 /* MainMenu.nib */, + 4C53E1660A484C2C0014E966 /* OSXClipboard.h */, + 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */, + ); + path = MacOSX; + sourceTree = ""; + }; + 4C53E14E0A484C2C0014E966 /* build */ = { + isa = PBXGroup; + children = ( + 4C53E14F0A484C2C0014E966 /* MacOSX.build */, + ); + path = build; + sourceTree = ""; + }; + 4C53E14F0A484C2C0014E966 /* MacOSX.build */ = { + isa = PBXGroup; + children = ( + 4C53E1500A484C2C0014E966 /* MacOSX.pbxindex */, + ); + path = MacOSX.build; + sourceTree = ""; + }; + 4C53E1500A484C2C0014E966 /* MacOSX.pbxindex */ = { + isa = PBXGroup; + children = ( + 4C53E1590A484C2C0014E966 /* strings.pbxstrings */, + ); + path = MacOSX.pbxindex; + sourceTree = ""; + }; + 4C53E1590A484C2C0014E966 /* strings.pbxstrings */ = { + isa = PBXGroup; + children = ( + ); + path = strings.pbxstrings; + sourceTree = ""; + }; + 4C53E1710A484C2C0014E966 /* zlib */ = { + isa = PBXGroup; + children = ( + 4C6DC9B60A48715A0017A6E5 /* inflate.c */, + 4C53E1720A484C2C0014E966 /* adler32.c */, + 4C53E1750A484C2C0014E966 /* compress.c */, + 4C53E1770A484C2C0014E966 /* crc32.c */, + 4C53E1790A484C2C0014E966 /* deflate.c */, + 4C53E17D0A484C2C0014E966 /* gzio.c */, + 4C53E1800A484C2C0014E966 /* inffast.c */, + 4C53E1850A484C2C0014E966 /* inftrees.c */, + 4C53E18B0A484C2C0014E966 /* trees.c */, + 4C53E18D0A484C2C0014E966 /* uncompr.c */, + 4C53E1920A484C2C0014E966 /* zutil.c */, + ); + path = zlib; + sourceTree = ""; + }; + 4C53E24C0A484FED0014E966 /* Products */ = { + isa = PBXGroup; + children = ( + 4C53E24D0A4850120014E966 /* libIrrlicht.a */, + 4C53E2520A4850550014E966 /* Quake3Map.app */, + 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */, + 4CA25BA40A485D9800B4E469 /* Movement.app */, + 4CA25B9E0A485D9800B4E469 /* UserInterface.app */, + 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */, + 4CA25BAE0A485D9800B4E469 /* Collision.app */, + 4CA25BA80A485D9800B4E469 /* SpecialFx.app */, + 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */, + 4CA25BA60A485D9800B4E469 /* Shaders.app */, + 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */, + 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */, + 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */, + 4CA25BA20A485D9800B4E469 /* Demo.app */, + ); + name = Products; + sourceTree = ""; + }; + 4C53E2540A48505D0014E966 /* Libraries */ = { + isa = PBXGroup; + children = ( + 4C53E26D0A4850D60014E966 /* Cocoa.framework */, + 4C53E26E0A4850D60014E966 /* OpenGL.framework */, + ); + name = Libraries; + sourceTree = ""; + }; + 4C6DC9960A486B110017A6E5 /* Engine */ = { + isa = PBXGroup; + children = ( + 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */, + 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */, + 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */, + 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */, + 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */, + 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */, + 5DD480500C7D936700728AA9 /* IBurningShader.cpp */, + 5DD480510C7D936700728AA9 /* IBurningShader.h */, + 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */, + 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */, + 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */, + 4CFA7BDD0A88735900B03626 /* CImageLoaderBMP.h */, + 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */, + 4CFA7BDF0A88735900B03626 /* CImageWriterBMP.h */, + 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */, + 4CFA7BE10A88735900B03626 /* CImageWriterJPG.h */, + 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */, + 4CFA7BE30A88735900B03626 /* CImageWriterPCX.h */, + 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */, + 4CFA7BE50A88735900B03626 /* CImageWriterPNG.h */, + 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */, + 4CFA7BE70A88735900B03626 /* CImageWriterPPM.h */, + 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */, + 4CFA7BE90A88735900B03626 /* CImageWriterPSD.h */, + 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */, + 4CFA7BEB0A88735900B03626 /* CImageWriterTGA.h */, + 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */, + 4CFA7BED0A88735A00B03626 /* CSkyDomeSceneNode.h */, + 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */, + 4C43EEBF0A74A5C800F942FC /* CPakReader.h */, + 4C43EEBD0A74A5AB00F942FC /* CAnimatedMeshB3d.h */, + 4C43EEBB0A74A5A300F942FC /* CAnimatedMeshB3d.cpp */, + 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */, + 4C364EA30A6C6DC2004CFBB4 /* COBJMeshFileLoader.h */, + 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */, + 4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */, + 4C53DEE60A484C220014E966 /* BuiltInFont.h */, + 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */, + 4C53DEE80A484C220014E966 /* C3DSMeshFileLoader.h */, + 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */, + 4C53DEEA0A484C220014E966 /* CAnimatedMeshMD2.h */, + 4C53DEEB0A484C220014E966 /* CAnimatedMeshMS3D.cpp */, + 4C53DEEC0A484C220014E966 /* CAnimatedMeshMS3D.h */, + 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */, + 4C53DEEE0A484C220014E966 /* CAnimatedMeshSceneNode.h */, + 4C53DEEF0A484C220014E966 /* CAttributeImpl.h */, + 4C53DEF00A484C220014E966 /* CAttributes.cpp */, + 4C53DEF10A484C220014E966 /* CAttributes.h */, + 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */, + 4C53DEF30A484C220014E966 /* CBillboardSceneNode.h */, + 4C53DEF40A484C220014E966 /* CCameraFPSSceneNode.cpp */, + 4C53DEF50A484C220014E966 /* CCameraFPSSceneNode.h */, + 4C53DEF60A484C220014E966 /* CCameraMayaSceneNode.cpp */, + 4C53DEF70A484C220014E966 /* CCameraMayaSceneNode.h */, + 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */, + 4C53DEF90A484C220014E966 /* CCameraSceneNode.h */, + 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */, + 4C53DEFB0A484C220014E966 /* CColladaFileLoader.h */, + 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */, + 4C53DEFD0A484C220014E966 /* CColorConverter.h */, + 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */, + 4C53DEFF0A484C220014E966 /* CCSMLoader.h */, + 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */, + 4C53DF010A484C220014E966 /* CCubeSceneNode.h */, + 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */, + 4C53DF030A484C220014E966 /* CD3D8Driver.h */, + 4C53DF040A484C220014E966 /* CD3D8MaterialRenderer.h */, + 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */, + 4C53DF060A484C220014E966 /* CD3D8NormalMapRenderer.h */, + 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */, + 4C53DF080A484C230014E966 /* CD3D8ParallaxMapRenderer.h */, + 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */, + 4C53DF0A0A484C230014E966 /* CD3D8ShaderMaterialRenderer.h */, + 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */, + 4C53DF0C0A484C230014E966 /* CD3D8Texture.h */, + 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */, + 4C53DF0E0A484C230014E966 /* CD3D9Driver.h */, + 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */, + 4C53DF100A484C230014E966 /* CD3D9HLSLMaterialRenderer.h */, + 4C53DF110A484C230014E966 /* CD3D9MaterialRenderer.h */, + 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */, + 4C53DF130A484C230014E966 /* CD3D9NormalMapRenderer.h */, + 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */, + 4C53DF150A484C230014E966 /* CD3D9ParallaxMapRenderer.h */, + 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */, + 4C53DF170A484C230014E966 /* CD3D9ShaderMaterialRenderer.h */, + 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */, + 4C53DF190A484C230014E966 /* CD3D9Texture.h */, + 4C53DF1A0A484C230014E966 /* CDefaultMeshFormatLoader.cpp */, + 4C53DF1B0A484C230014E966 /* CDefaultMeshFormatLoader.h */, + 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */, + 4C53DF1D0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.h */, + 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */, + 4C53DF1F0A484C230014E966 /* CDefaultSceneNodeFactory.h */, + 4C53DF200A484C230014E966 /* CDMFLoader.cpp */, + 4C53DF210A484C230014E966 /* CDMFLoader.h */, + 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */, + 4C53DF230A484C230014E966 /* CDummyTransformationSceneNode.h */, + 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */, + 4C53DF250A484C230014E966 /* CEmptySceneNode.h */, + 4C53DF260A484C230014E966 /* CFileList.cpp */, + 4C53DF270A484C230014E966 /* CFileList.h */, + 4C53DF280A484C230014E966 /* CFileSystem.cpp */, + 4C53DF290A484C230014E966 /* CFileSystem.h */, + 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */, + 4C53DF2B0A484C230014E966 /* CFPSCounter.h */, + 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */, + 4C53DF2D0A484C230014E966 /* CGeometryCreator.h */, + 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */, + 4C53DF2F0A484C230014E966 /* CGUIButton.h */, + 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */, + 4C53DF310A484C230014E966 /* CGUICheckBox.h */, + 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */, + 4C53DF330A484C230014E966 /* CGUIComboBox.h */, + 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */, + 4C53DF350A484C230014E966 /* CGUIContextMenu.h */, + 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */, + 4C53DF370A484C230014E966 /* CGUIEditBox.h */, + 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */, + 4C53DF390A484C230014E966 /* CGUIEnvironment.h */, + 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */, + 4C53DF3B0A484C230014E966 /* CGUIFileOpenDialog.h */, + 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */, + 4C53DF3D0A484C230014E966 /* CGUIFont.h */, + 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */, + 4C53DF3F0A484C230014E966 /* CGUIImage.h */, + 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */, + 4C53DF410A484C230014E966 /* CGUIInOutFader.h */, + 4C53DF420A484C230014E966 /* CGUIListBox.cpp */, + 4C53DF430A484C230014E966 /* CGUIListBox.h */, + 4C53DF440A484C230014E966 /* CGUIMenu.cpp */, + 4C53DF450A484C230014E966 /* CGUIMenu.h */, + 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */, + 4C53DF470A484C230014E966 /* CGUIMeshViewer.h */, + 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */, + 4C53DF490A484C230014E966 /* CGUIMessageBox.h */, + 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */, + 4C53DF4B0A484C230014E966 /* CGUIModalScreen.h */, + 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */, + 4C53DF4D0A484C230014E966 /* CGUIScrollBar.h */, + 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */, + 4C53DF4F0A484C230014E966 /* CGUISkin.h */, + 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */, + 4C53DF510A484C230014E966 /* CGUIStaticText.h */, + 4C53DF520A484C230014E966 /* CGUITabControl.cpp */, + 4C53DF530A484C230014E966 /* CGUITabControl.h */, + 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */, + 4C53DF550A484C230014E966 /* CGUIToolBar.h */, + 4C53DF560A484C230014E966 /* CGUIWindow.cpp */, + 4C53DF570A484C230014E966 /* CGUIWindow.h */, + 4C53DF580A484C230014E966 /* CImage.cpp */, + 4C53DF590A484C230014E966 /* CImage.h */, + 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */, + 4C53DF5D0A484C230014E966 /* CImageLoaderJPG.h */, + 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */, + 4C53DF5F0A484C230014E966 /* CImageLoaderPCX.h */, + 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */, + 4C53DF610A484C230014E966 /* CImageLoaderPNG.h */, + 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */, + 4C53DF630A484C230014E966 /* CImageLoaderPSD.h */, + 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */, + 4C53DF650A484C230014E966 /* CImageLoaderTGA.h */, + 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */, + 4C53DF670A484C230014E966 /* CIrrDeviceLinux.h */, + 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */, + 4C53DF690A484C230014E966 /* CIrrDeviceStub.h */, + 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */, + 4C53DF6B0A484C230014E966 /* CIrrDeviceWin32.h */, + 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */, + 4C53DF6D0A484C230014E966 /* CLightSceneNode.h */, + 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */, + 4C53DF6F0A484C230014E966 /* CLimitReadFile.h */, + 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */, + 4C53DF710A484C230014E966 /* CLMTSMeshFileLoader.h */, + 4C53DF720A484C230014E966 /* CLogger.cpp */, + 4C53DF730A484C230014E966 /* CLogger.h */, + 4C53DF740A484C230014E966 /* CMemoryReadFile.cpp */, + 4C53DF750A484C230014E966 /* CMemoryReadFile.h */, + 4C53DF760A484C230014E966 /* CMeshCache.cpp */, + 4C53DF770A484C230014E966 /* CMeshCache.h */, + 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */, + 4C53DF790A484C230014E966 /* CMeshManipulator.h */, + 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */, + 4C53DF7B0A484C230014E966 /* CMeshSceneNode.h */, + 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */, + 4C53DF7D0A484C230014E966 /* CMetaTriangleSelector.h */, + 4C53DF7E0A484C230014E966 /* CMY3DHelper.h */, + 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */, + 4C53DF800A484C230014E966 /* CMY3DMeshFileLoader.h */, + 4C53DF810A484C230014E966 /* CMY3DStuff.h */, + 4C53DF820A484C240014E966 /* CNullDriver.cpp */, + 4C53DF830A484C240014E966 /* CNullDriver.h */, + 4C53DF840A484C240014E966 /* COCTLoader.cpp */, + 4C53DF850A484C240014E966 /* COCTLoader.h */, + 4C53DF860A484C240014E966 /* COctTreeSceneNode.cpp */, + 4C53DF870A484C240014E966 /* COctTreeSceneNode.h */, + 4C53DF880A484C240014E966 /* COctTreeTriangleSelector.cpp */, + 4C53DF890A484C240014E966 /* COctTreeTriangleSelector.h */, + 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */, + 4C53DF8B0A484C240014E966 /* COgreMeshFileLoader.h */, + 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */, + 4C53DF8D0A484C240014E966 /* COpenGLDriver.h */, + 4C53DF8E0A484C240014E966 /* COpenGLMaterialRenderer.h */, + 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */, + 4C53DF900A484C240014E966 /* COpenGLNormalMapRenderer.h */, + 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */, + 4C53DF920A484C240014E966 /* COpenGLParallaxMapRenderer.h */, + 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */, + 4C53DF940A484C240014E966 /* COpenGLShaderMaterialRenderer.h */, + 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */, + 4C53DF960A484C240014E966 /* COpenGLSLMaterialRenderer.h */, + 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */, + 4C53DF980A484C240014E966 /* COpenGLTexture.h */, + 4C53DF990A484C240014E966 /* COSOperator.cpp */, + 4C53DF9A0A484C240014E966 /* COSOperator.h */, + 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */, + 4C53DF9C0A484C240014E966 /* CParticleBoxEmitter.h */, + 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */, + 4C53DF9E0A484C240014E966 /* CParticleFadeOutAffector.h */, + 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */, + 4C53DFA00A484C240014E966 /* CParticleGravityAffector.h */, + 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */, + 4C53DFA20A484C240014E966 /* CParticlePointEmitter.h */, + 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */, + 4C53DFA40A484C240014E966 /* CParticleSystemSceneNode.h */, + 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */, + 4C53DFA60A484C240014E966 /* CQ3LevelMesh.h */, + 4C53DFA70A484C240014E966 /* CReadFile.cpp */, + 4C53DFA80A484C240014E966 /* CReadFile.h */, + 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */, + 4C53DFAA0A484C240014E966 /* CSceneCollisionManager.h */, + 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */, + 4C53DFAC0A484C240014E966 /* CSceneManager.h */, + 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */, + 4C53DFAE0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.h */, + 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */, + 4C53DFB00A484C240014E966 /* CSceneNodeAnimatorDelete.h */, + 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */, + 4C53DFB20A484C240014E966 /* CSceneNodeAnimatorFlyCircle.h */, + 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */, + 4C53DFB40A484C240014E966 /* CSceneNodeAnimatorFlyStraight.h */, + 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */, + 4C53DFB60A484C240014E966 /* CSceneNodeAnimatorFollowSpline.h */, + 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */, + 4C53DFB80A484C240014E966 /* CSceneNodeAnimatorRotation.h */, + 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */, + 4C53DFBA0A484C240014E966 /* CSceneNodeAnimatorTexture.h */, + 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */, + 4C53DFBC0A484C240014E966 /* CShadowVolumeSceneNode.h */, + 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */, + 4C53DFBE0A484C240014E966 /* CSkyBoxSceneNode.h */, + 4C53DFBF0A484C240014E966 /* CSoftware2MaterialRenderer.h */, + 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */, + 4C53DFC10A484C240014E966 /* CSoftwareDriver.h */, + 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */, + 4C53DFC30A484C240014E966 /* CSoftwareDriver2.h */, + 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */, + 4C53DFC50A484C240014E966 /* CSoftwareTexture.h */, + 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */, + 4C53DFC70A484C240014E966 /* CSoftwareTexture2.h */, + 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */, + 4C53DFCB0A484C240014E966 /* CTerrainSceneNode.h */, + 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */, + 4C53DFCD0A484C240014E966 /* CTerrainTriangleSelector.h */, + 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */, + 4C53DFCF0A484C240014E966 /* CTextSceneNode.h */, + 4C53DFD00A484C240014E966 /* CTimer.h */, + 4C53DFD10A484C240014E966 /* CTRFlat.cpp */, + 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */, + 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */, + 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */, + 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */, + 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */, + 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */, + 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */, + 4C53DFD90A484C250014E966 /* CTriangleBBSelector.h */, + 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */, + 4C53DFDB0A484C250014E966 /* CTriangleSelector.h */, + 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */, + 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */, + 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */, + 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */, + 4C53DFE00A484C250014E966 /* CTRTextureGouraud.h */, + 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */, + 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */, + 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */, + 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */, + 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */, + 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */, + 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */, + 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */, + 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */, + 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */, + 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */, + 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */, + 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */, + 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */, + 4C53DFEF0A484C250014E966 /* CVideoModeList.h */, + 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */, + 4C53DFF10A484C250014E966 /* CWaterSurfaceSceneNode.h */, + 4C53DFF20A484C250014E966 /* CWriteFile.cpp */, + 4C53DFF30A484C250014E966 /* CWriteFile.h */, + 4C53DFF40A484C250014E966 /* CXAnimationPlayer.cpp */, + 4C53DFF50A484C250014E966 /* CXAnimationPlayer.h */, + 4C53DFF60A484C250014E966 /* CXFileReader.cpp */, + 4C53DFF70A484C250014E966 /* CXFileReader.h */, + 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */, + 4C53DFF90A484C250014E966 /* CXMeshFileLoader.h */, + 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */, + 4C53DFFB0A484C250014E966 /* CXMLReader.h */, + 4C53DFFC0A484C250014E966 /* CXMLReaderImpl.h */, + 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */, + 4C53DFFE0A484C250014E966 /* CXMLWriter.h */, + 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */, + 4C53E0000A484C250014E966 /* CZBuffer.h */, + 4C53E0030A484C250014E966 /* CZipReader.cpp */, + 4C53E0040A484C250014E966 /* CZipReader.h */, + 4C53E0050A484C250014E966 /* dmfsupport.h */, + 4C53E0070A484C250014E966 /* glext.h */, + 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */, + 4C53E0090A484C250014E966 /* IImagePresenter.h */, + 4C53E00A0A484C250014E966 /* Irrlicht.cpp */, + 4C53E00E0A484C250014E966 /* irrXML.cpp */, + 4C53E00F0A484C250014E966 /* ITriangleRenderer.h */, + 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */, + 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */, + 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */, + 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */, + 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */, + 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */, + 5DD480700C7D94AC00728AA9 /* glxext.h */, + 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */, + 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */, + 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */, + 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */, + 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */, + 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */, + 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */, + 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */, + 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */, + 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */, + 4C53E0110A484C250014E966 /* IZBuffer.h */, + 4C53E1690A484C2C0014E966 /* OctTree.h */, + 4C53E16A0A484C2C0014E966 /* os.cpp */, + 4C53E16B0A484C2C0014E966 /* os.h */, + 4C53E16C0A484C2C0014E966 /* S2DVertex.h */, + 4C53E16D0A484C2C0014E966 /* S4DVertex.h */, + 4C53E16E0A484C2C0014E966 /* SoftwareDriver2_compile_config.h */, + 4C53E16F0A484C2C0014E966 /* SoftwareDriver2_helper.h */, + ); + name = Engine; + sourceTree = ""; + }; + 4CFA7C090A88742800B03626 /* include */ = { + isa = PBXGroup; + children = ( + 4CFA7C0A0A88742800B03626 /* aabbox3d.h */, + 4CFA7C0B0A88742800B03626 /* dimension2d.h */, + 4CFA7C0C0A88742800B03626 /* EDriverTypes.h */, + 4CFA7C0D0A88742800B03626 /* EGUIElementTypes.h */, + 4CFA7C0E0A88742800B03626 /* ESceneNodeAnimatorTypes.h */, + 4CFA7C0F0A88742800B03626 /* ESceneNodeTypes.h */, + 4CFA7C100A88742800B03626 /* heapsort.h */, + 4CFA7C110A88742900B03626 /* IAnimatedMesh.h */, + 4CFA7C120A88742900B03626 /* IAnimatedMeshB3d.h */, + 4CFA7C130A88742900B03626 /* IAnimatedMeshMD2.h */, + 4CFA7C140A88742900B03626 /* IAnimatedMeshMS3D.h */, + 4CFA7C150A88742900B03626 /* IAnimatedMeshSceneNode.h */, + 4CFA7C160A88742900B03626 /* IAnimatedMeshX.h */, + 4CFA7C170A88742900B03626 /* IAttributeExchangingObject.h */, + 4CFA7C180A88742900B03626 /* IAttributes.h */, + 4CFA7C190A88742900B03626 /* IBillboardSceneNode.h */, + 4CFA7C1A0A88742900B03626 /* ICameraSceneNode.h */, + 4CFA7C1B0A88742900B03626 /* ICursorControl.h */, + 4CFA7C1C0A88742900B03626 /* IDummyTransformationSceneNode.h */, + 4CFA7C1D0A88742900B03626 /* IEventReceiver.h */, + 4CFA7C1E0A88742900B03626 /* IFileList.h */, + 4CFA7C1F0A88742900B03626 /* IFileSystem.h */, + 4CFA7C200A88742900B03626 /* IGPUProgrammingServices.h */, + 4CFA7C210A88742900B03626 /* IGUIButton.h */, + 4CFA7C220A88742900B03626 /* IGUICheckBox.h */, + 4CFA7C230A88742900B03626 /* IGUIComboBox.h */, + 4CFA7C240A88742900B03626 /* IGUIContextMenu.h */, + 4CFA7C250A88742900B03626 /* IGUIEditBox.h */, + 4CFA7C260A88742900B03626 /* IGUIElement.h */, + 4CFA7C270A88742900B03626 /* IGUIEnvironment.h */, + 4CFA7C280A88742900B03626 /* IGUIFileOpenDialog.h */, + 4CFA7C290A88742900B03626 /* IGUIFont.h */, + 4CFA7C2A0A88742900B03626 /* IGUIImage.h */, + 4CFA7C2B0A88742900B03626 /* IGUIInOutFader.h */, + 4CFA7C2C0A88742900B03626 /* IGUIListBox.h */, + 4CFA7C2D0A88742900B03626 /* IGUIMeshViewer.h */, + 4CFA7C2E0A88742900B03626 /* IGUIScrollBar.h */, + 4CFA7C2F0A88742900B03626 /* IGUISkin.h */, + 4CFA7C300A88742900B03626 /* IGUIStaticText.h */, + 4CFA7C310A88742900B03626 /* IGUITabControl.h */, + 4CFA7C320A88742900B03626 /* IGUIToolbar.h */, + 4CFA7C330A88742900B03626 /* IGUIWindow.h */, + 4CFA7C340A88742900B03626 /* IImage.h */, + 4CFA7C350A88742900B03626 /* IImageLoader.h */, + 4CFA7C360A88742900B03626 /* IImageWriter.h */, + 4CFA7C370A88742900B03626 /* ILightSceneNode.h */, + 4CFA7C380A88742900B03626 /* ILogger.h */, + 4CFA7C390A88742900B03626 /* IMaterialRenderer.h */, + 4CFA7C3A0A88742900B03626 /* IMaterialRendererServices.h */, + 4CFA7C3B0A88742900B03626 /* IMesh.h */, + 4CFA7C3C0A88742900B03626 /* IMeshBuffer.h */, + 4CFA7C3D0A88742900B03626 /* IMeshCache.h */, + 4CFA7C3E0A88742900B03626 /* IMeshLoader.h */, + 4CFA7C3F0A88742900B03626 /* IMeshManipulator.h */, + 4CFA7C400A88742900B03626 /* IMeshSceneNode.h */, + 4CFA7C410A88742900B03626 /* IMetaTriangleSelector.h */, + 4CFA7C420A88742900B03626 /* IOSOperator.h */, + 4CFA7C430A88742900B03626 /* IParticleAffector.h */, + 4CFA7C440A88742900B03626 /* IParticleEmitter.h */, + 4CFA7C450A88742900B03626 /* IParticleSystemSceneNode.h */, + 4CFA7C460A88742900B03626 /* IQ3LevelMesh.h */, + 4CFA7C470A88742900B03626 /* IReadFile.h */, + 4CFA7C480A88742900B03626 /* irrAllocator.h */, + 4CFA7C490A88742900B03626 /* irrArray.h */, + 4CFA7C4A0A88742900B03626 /* IrrCompileConfig.h */, + 4CFA7C4B0A88742900B03626 /* irrlicht.h */, + 4CFA7C4C0A88742900B03626 /* IrrlichtDevice.h */, + 4CFA7C4D0A88742900B03626 /* irrList.h */, + 4CFA7C4E0A88742900B03626 /* irrMath.h */, + 4CFA7C4F0A88742900B03626 /* irrString.h */, + 4CFA7C500A88742900B03626 /* irrTypes.h */, + 4CFA7C510A88742900B03626 /* irrXML.h */, + 4CFA7C520A88742900B03626 /* ISceneCollisionManager.h */, + 4CFA7C530A88742900B03626 /* ISceneManager.h */, + 4CFA7C540A88742900B03626 /* ISceneNode.h */, + 4CFA7C550A88742900B03626 /* ISceneNodeAnimator.h */, + 4CFA7C560A88742900B03626 /* ISceneNodeAnimatorCollisionResponse.h */, + 4CFA7C570A88742900B03626 /* ISceneNodeAnimatorFactory.h */, + 4CFA7C580A88742900B03626 /* ISceneNodeFactory.h */, + 4CFA7C590A88742900B03626 /* ISceneUserDataSerializer.h */, + 4CFA7C5A0A88742900B03626 /* IShaderConstantSetCallBack.h */, + 4CFA7C5B0A88742900B03626 /* IShadowVolumeSceneNode.h */, + 4CFA7C5C0A88742900B03626 /* ITerrainSceneNode.h */, + 4CFA7C5D0A88742900B03626 /* ITextSceneNode.h */, + 4CFA7C5E0A88742900B03626 /* ITexture.h */, + 4CFA7C5F0A88742900B03626 /* ITimer.h */, + 4CFA7C600A88742900B03626 /* ITriangleSelector.h */, + 4CFA7C610A88742900B03626 /* IUnknown.h */, + 4CFA7C620A88742900B03626 /* IVideoDriver.h */, + 4CFA7C630A88742900B03626 /* IVideoModeList.h */, + 4CFA7C640A88742900B03626 /* IWriteFile.h */, + 4CFA7C650A88742900B03626 /* IXMLReader.h */, + 4CFA7C660A88742900B03626 /* IXMLWriter.h */, + 4CFA7C670A88742900B03626 /* Keycodes.h */, + 4CFA7C680A88742900B03626 /* line2d.h */, + 4CFA7C690A88742900B03626 /* line3d.h */, + 4CFA7C6A0A88742900B03626 /* matrix4.h */, + 4CFA7C6B0A88742900B03626 /* plane3d.h */, + 4CFA7C6C0A88742900B03626 /* position2d.h */, + 4CFA7C6D0A88742900B03626 /* quaternion.h */, + 4CFA7C6E0A88742900B03626 /* rect.h */, + 4CFA7C6F0A88742900B03626 /* S3DVertex.h */, + 4CFA7C700A88742900B03626 /* SAnimatedMesh.h */, + 4CFA7C710A88742900B03626 /* SceneParameters.h */, + 4CFA7C720A88742900B03626 /* SColor.h */, + 4CFA7C730A88742900B03626 /* SExposedVideoData.h */, + 4CFA7C740A88742900B03626 /* SIrrCreationParameters.h */, + 4CFA7C750A88742900B03626 /* SKeyMap.h */, + 4CFA7C760A88742900B03626 /* SLight.h */, + 4CFA7C770A88742900B03626 /* SMaterial.h */, + 4CFA7C780A88742900B03626 /* SMesh.h */, + 4CFA7C790A88742900B03626 /* SMeshBuffer.h */, + 4CFA7C7A0A88742900B03626 /* SMeshBufferLightMap.h */, + 4CFA7C7B0A88742900B03626 /* SMeshBufferTangents.h */, + 4CFA7C7C0A88742900B03626 /* SParticle.h */, + 4CFA7C7D0A88742900B03626 /* SViewFrustrum.h */, + 4CFA7C7E0A88742900B03626 /* triangle3d.h */, + 4CFA7C7F0A88742900B03626 /* vector2d.h */, + 4CFA7C800A88742900B03626 /* vector3d.h */, + ); + name = include; + path = ../../../include; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC07A0554694100DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5DD4804F0C7D91DF00728AA9 /* CDepthBuffer.h in Headers */, + 5DD480530C7D936700728AA9 /* IBurningShader.h in Headers */, + 5DD480550C7D93AB00728AA9 /* IDepthBuffer.h in Headers */, + 5DD4805B0C7D945800728AA9 /* CAnimatedMeshMD3.h in Headers */, + 5DD4805D0C7D945800728AA9 /* CDefaultGUIElementFactory.h in Headers */, + 5DD480650C7D947B00728AA9 /* CGUIColorSelectDialog.h in Headers */, + 5DD480670C7D947B00728AA9 /* CGUISpinBox.h in Headers */, + 5DD480690C7D947B00728AA9 /* CGUISpriteBank.h in Headers */, + 5DD480720C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h in Headers */, + 5DD480770C7D94AC00728AA9 /* glxext.h in Headers */, + 5DD480C70C7DA66800728AA9 /* COpenGLExtensionHandler.h in Headers */, + 5DD480C80C7DA66800728AA9 /* CMD3MeshFileLoader.h in Headers */, + 5DD480C90C7DA66800728AA9 /* CIrrDeviceSDL.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + B81CFDFE097FD9F50057C06F /* 2DGraphics */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFE0C097FD9F50057C06F /* Build configuration list for PBXNativeTarget "2DGraphics" */; + buildPhases = ( + B81CFE01097FD9F50057C06F /* Resources */, + B81CFE03097FD9F50057C06F /* Sources */, + B81CFE08097FD9F50057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFDFF097FD9F50057C06F /* PBXTargetDependency */, + ); + name = 2DGraphics; + productName = DemoApp; + productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */; + productType = "com.apple.product-type.application"; + }; + B81CFE82097FDDE20057C06F /* Collision */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFE8D097FDDE20057C06F /* Build configuration list for PBXNativeTarget "Collision" */; + buildPhases = ( + B81CFE85097FDDE20057C06F /* Resources */, + B81CFE87097FDDE20057C06F /* Sources */, + B81CFE89097FDDE20057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFE83097FDDE20057C06F /* PBXTargetDependency */, + ); + name = Collision; + productName = DemoApp; + productReference = 4CA25BAE0A485D9800B4E469 /* Collision.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEA4097FDE900057C06F /* PerPixelLightning */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFEAF097FDE900057C06F /* Build configuration list for PBXNativeTarget "PerPixelLightning" */; + buildPhases = ( + B81CFEA7097FDE900057C06F /* Resources */, + B81CFEA9097FDE900057C06F /* Sources */, + B81CFEAB097FDE900057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEA5097FDE900057C06F /* PBXTargetDependency */, + ); + name = PerPixelLightning; + productName = DemoApp; + productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEC2097FDF020057C06F /* TerrainRendering */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFECD097FDF020057C06F /* Build configuration list for PBXNativeTarget "TerrainRendering" */; + buildPhases = ( + B81CFEC5097FDF020057C06F /* Resources */, + B81CFEC7097FDF020057C06F /* Sources */, + B81CFEC9097FDF020057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEC3097FDF020057C06F /* PBXTargetDependency */, + ); + name = TerrainRendering; + productName = DemoApp; + productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEE8097FE05F0057C06F /* SpecialFx */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFEF3097FE05F0057C06F /* Build configuration list for PBXNativeTarget "SpecialFx" */; + buildPhases = ( + B81CFEEB097FE05F0057C06F /* Resources */, + B81CFEED097FE05F0057C06F /* Sources */, + B81CFEEF097FE05F0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEE9097FE05F0057C06F /* PBXTargetDependency */, + ); + name = SpecialFx; + productName = DemoApp; + productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF07097FE13E0057C06F /* UserInterface */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF12097FE13E0057C06F /* Build configuration list for PBXNativeTarget "UserInterface" */; + buildPhases = ( + B81CFF0A097FE13E0057C06F /* Resources */, + B81CFF0C097FE13E0057C06F /* Sources */, + B81CFF0E097FE13E0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF08097FE13E0057C06F /* PBXTargetDependency */, + ); + name = UserInterface; + productName = DemoApp; + productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF1E097FE1E00057C06F /* CustomSceneNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF29097FE1E00057C06F /* Build configuration list for PBXNativeTarget "CustomSceneNode" */; + buildPhases = ( + B81CFF21097FE1E00057C06F /* Resources */, + B81CFF23097FE1E00057C06F /* Sources */, + B81CFF25097FE1E00057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF1F097FE1E00057C06F /* PBXTargetDependency */, + ); + name = CustomSceneNode; + productName = DemoApp; + productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF33097FE25F0057C06F /* Quake3Map */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF3E097FE25F0057C06F /* Build configuration list for PBXNativeTarget "Quake3Map" */; + buildPhases = ( + B81CFF36097FE25F0057C06F /* Resources */, + B81CFF38097FE25F0057C06F /* Sources */, + B81CFF3A097FE25F0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF34097FE25F0057C06F /* PBXTargetDependency */, + ); + name = Quake3Map; + productName = DemoApp; + productReference = 4C53E2520A4850550014E966 /* Quake3Map.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF4A097FE3050057C06F /* Shaders */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF55097FE3050057C06F /* Build configuration list for PBXNativeTarget "Shaders" */; + buildPhases = ( + B81CFF4D097FE3050057C06F /* Resources */, + B81CFF4F097FE3050057C06F /* Sources */, + B81CFF51097FE3050057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF4B097FE3050057C06F /* PBXTargetDependency */, + ); + name = Shaders; + productName = DemoApp; + productReference = 4CA25BA60A485D9800B4E469 /* Shaders.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF78097FE3DC0057C06F /* Movement */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF83097FE3DC0057C06F /* Build configuration list for PBXNativeTarget "Movement" */; + buildPhases = ( + B81CFF7B097FE3DC0057C06F /* Resources */, + B81CFF7D097FE3DC0057C06F /* Sources */, + B81CFF7F097FE3DC0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF79097FE3DC0057C06F /* PBXTargetDependency */, + ); + name = Movement; + productName = DemoApp; + productReference = 4CA25BA40A485D9800B4E469 /* Movement.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF91097FE45E0057C06F /* MeshViewer */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF9C097FE45E0057C06F /* Build configuration list for PBXNativeTarget "MeshViewer" */; + buildPhases = ( + B81CFF94097FE45E0057C06F /* Resources */, + B81CFF96097FE45E0057C06F /* Sources */, + B81CFF98097FE45E0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF92097FE45E0057C06F /* PBXTargetDependency */, + ); + name = MeshViewer; + productName = DemoApp; + productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */; + productType = "com.apple.product-type.application"; + }; + B81CFFAF097FE5F80057C06F /* RenderToTexture */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFFBA097FE5F80057C06F /* Build configuration list for PBXNativeTarget "RenderToTexture" */; + buildPhases = ( + B81CFFB2097FE5F80057C06F /* Resources */, + B81CFFB4097FE5F80057C06F /* Sources */, + B81CFFB6097FE5F80057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFFB0097FE5F80057C06F /* PBXTargetDependency */, + ); + name = RenderToTexture; + productName = DemoApp; + productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */; + productType = "com.apple.product-type.application"; + }; + B8DEF35C0950229200FDEA7E /* Demo */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8DEF3600950229300FDEA7E /* Build configuration list for PBXNativeTarget "Demo" */; + buildPhases = ( + B8DEF3590950229200FDEA7E /* Resources */, + B8DEF35A0950229200FDEA7E /* Sources */, + B8DEF35B0950229200FDEA7E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B8DEF375095024F600FDEA7E /* PBXTargetDependency */, + ); + name = Demo; + productName = DemoApp; + productReference = 4CA25BA20A485D9800B4E469 /* Demo.app */; + productType = "com.apple.product-type.application"; + }; + D2AAC07D0554694100DB518D /* libIrrlicht.a */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libIrrlicht.a" */; + buildPhases = ( + D2AAC07A0554694100DB518D /* Headers */, + D2AAC07B0554694100DB518D /* Sources */, + D2AAC07C0554694100DB518D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = libIrrlicht.a; + productName = MacOSX; + productReference = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "MacOSX" */; + hasScannedForEncodings = 1; + mainGroup = 0867D691FE84028FC02AAC07 /* MacOSX */; + productRefGroup = 0867D691FE84028FC02AAC07 /* MacOSX */; + projectDirPath = ""; + targets = ( + D2AAC07D0554694100DB518D /* libIrrlicht.a */, + B81CFF33097FE25F0057C06F /* Quake3Map */, + B81CFF1E097FE1E00057C06F /* CustomSceneNode */, + B81CFF78097FE3DC0057C06F /* Movement */, + B81CFF07097FE13E0057C06F /* UserInterface */, + B81CFDFE097FD9F50057C06F /* 2DGraphics */, + B81CFE82097FDDE20057C06F /* Collision */, + B81CFEE8097FE05F0057C06F /* SpecialFx */, + B81CFF91097FE45E0057C06F /* MeshViewer */, + B81CFF4A097FE3050057C06F /* Shaders */, + B81CFEA4097FDE900057C06F /* PerPixelLightning */, + B81CFEC2097FDF020057C06F /* TerrainRendering */, + B81CFFAF097FE5F80057C06F /* RenderToTexture */, + B8DEF35C0950229200FDEA7E /* Demo */, + B81CFFC6097FE9980057C06F /* All */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B81CFE01097FD9F50057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F60A486651006EBA03 /* MainMenu.nib in Resources */, + 4C53E3920A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE85097FDDE20057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1470B0A486704006EBA03 /* MainMenu.nib in Resources */, + 4C53E3930A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEA7097FDE900057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB30A486A1300ADB3D7 /* MainMenu.nib in Resources */, + 4C53E3970A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC5097FDF020057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB60A486A2200ADB3D7 /* MainMenu.nib in Resources */, + 4C53E3980A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEEB097FE05F0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147180A48676A006EBA03 /* MainMenu.nib in Resources */, + 4C53E3940A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0A097FE13E0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8B0A48626600B4E469 /* MainMenu.nib in Resources */, + 4C53E3910A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF21097FE1E00057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C360A48610400B4E469 /* MainMenu.nib in Resources */, + 4C53E38F0A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF36097FE25F0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E3890A48559C0014E966 /* MainMenu.nib in Resources */, + 4C53E39B0A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF4D097FE3050057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBA70A4869C600ADB3D7 /* MainMenu.nib in Resources */, + 4C53E3960A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7B097FE3DC0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C6A0A4861D800B4E469 /* MainMenu.nib in Resources */, + 4C53E3900A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF94097FE45E0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBA90A4869DD00ADB3D7 /* MainMenu.nib in Resources */, + 4C53E3950A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB2097FE5F80057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB90A486A3100ADB3D7 /* MainMenu.nib in Resources */, + 4C53E3990A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF3590950229200FDEA7E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBE0A486A4F00ADB3D7 /* MainMenu.nib in Resources */, + 4C53E39A0A4855BA0014E966 /* DemoApp-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B81CFE03097FD9F50057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F70A486668006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE87097FDDE20057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147100A486709006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEA9097FDE900057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB20A486A0D00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC7097FDF020057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB50A486A1F00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEED097FE05F0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1471A0A486774006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0C097FE13E0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8C0A48627600B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF23097FE1E00057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C350A4860EE00B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF38097FE25F0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E2500A48504D0014E966 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF4F097FE3050057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB00A4869FD00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7D097FE3DC0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C690A4861D100B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF96097FE45E0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBAE0A4869E600ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB4097FE5F80057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB80A486A2E00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF35A0950229200FDEA7E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBB0A486A4C00ADB3D7 /* CMainMenu.cpp in Sources */, + 4CA5CBBC0A486A4C00ADB3D7 /* main.cpp in Sources */, + 4CA5CBBD0A486A4C00ADB3D7 /* CDemo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC07B0554694100DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25BCE0A485EAD00B4E469 /* jcapimin.c in Sources */, + 4CA25BCF0A485EAD00B4E469 /* jcapistd.c in Sources */, + 4CA25BD00A485EAD00B4E469 /* jccoefct.c in Sources */, + 4CA25BD10A485EAD00B4E469 /* jccolor.c in Sources */, + 4CA25BD20A485EAD00B4E469 /* jcdctmgr.c in Sources */, + 4CA25BD30A485EAD00B4E469 /* jchuff.c in Sources */, + 4CA25BD50A485EAD00B4E469 /* jcinit.c in Sources */, + 4CA25BD60A485EAD00B4E469 /* jcmainct.c in Sources */, + 4CA25BD70A485EAD00B4E469 /* jcmarker.c in Sources */, + 4CA25BD80A485EAD00B4E469 /* jcmaster.c in Sources */, + 4CA25BD90A485EAD00B4E469 /* jcomapi.c in Sources */, + 4CA25BDB0A485EAD00B4E469 /* jcparam.c in Sources */, + 4CA25BDC0A485EAD00B4E469 /* jcphuff.c in Sources */, + 4CA25BDD0A485EAD00B4E469 /* jcprepct.c in Sources */, + 4CA25BDE0A485EAD00B4E469 /* jcsample.c in Sources */, + 4CA25BDF0A485EAD00B4E469 /* jctrans.c in Sources */, + 4CA25BE00A485EAD00B4E469 /* jdapimin.c in Sources */, + 4CA25BE10A485EAD00B4E469 /* jdapistd.c in Sources */, + 4CA25BE20A485EAD00B4E469 /* jdatadst.c in Sources */, + 4CA25BE30A485EAD00B4E469 /* jdatasrc.c in Sources */, + 4CA25BE40A485EAD00B4E469 /* jdcoefct.c in Sources */, + 4CA25BE50A485EAD00B4E469 /* jdcolor.c in Sources */, + 4CA25BE70A485EAD00B4E469 /* jddctmgr.c in Sources */, + 4CA25BE80A485EAD00B4E469 /* jdhuff.c in Sources */, + 4CA25BEA0A485EAD00B4E469 /* jdinput.c in Sources */, + 4CA25BEB0A485EAD00B4E469 /* jdmainct.c in Sources */, + 4CA25BEC0A485EAD00B4E469 /* jdmarker.c in Sources */, + 4CA25BED0A485EAD00B4E469 /* jdmaster.c in Sources */, + 4CA25BEE0A485EAD00B4E469 /* jdmerge.c in Sources */, + 4CA25BEF0A485EAD00B4E469 /* jdphuff.c in Sources */, + 4CA25BF00A485EAD00B4E469 /* jdpostct.c in Sources */, + 4CA25BF10A485EAD00B4E469 /* jdsample.c in Sources */, + 4CA25BF20A485EAD00B4E469 /* jdtrans.c in Sources */, + 4CA25BF30A485EAD00B4E469 /* jerror.c in Sources */, + 4CA25BF50A485EAD00B4E469 /* jfdctflt.c in Sources */, + 4CA25BF60A485EAD00B4E469 /* jfdctfst.c in Sources */, + 4CA25BF70A485EAD00B4E469 /* jfdctint.c in Sources */, + 4CA25BF80A485EAD00B4E469 /* jidctflt.c in Sources */, + 4CA25BF90A485EAD00B4E469 /* jidctfst.c in Sources */, + 4CA25BFA0A485EAD00B4E469 /* jidctint.c in Sources */, + 4CA25BFB0A485EAD00B4E469 /* jidctred.c in Sources */, + 4CA25C000A485EAD00B4E469 /* jmemmgr.c in Sources */, + 4CA25C020A485EAD00B4E469 /* jmemnobs.c in Sources */, + 4CA25C080A485EAD00B4E469 /* jquant1.c in Sources */, + 4CA25C090A485EAD00B4E469 /* jquant2.c in Sources */, + 4CA25C0A0A485EAD00B4E469 /* jutils.c in Sources */, + 4CA25C0C0A485EAD00B4E469 /* rdbmp.c in Sources */, + 4CA25C0D0A485EAD00B4E469 /* rdcolmap.c in Sources */, + 4CA25C0E0A485EAD00B4E469 /* rdgif.c in Sources */, + 4CA25C100A485EAD00B4E469 /* rdppm.c in Sources */, + 4CA25C110A485EAD00B4E469 /* rdrle.c in Sources */, + 4CA25C120A485EAD00B4E469 /* rdswitch.c in Sources */, + 4CA25C130A485EAD00B4E469 /* rdtarga.c in Sources */, + 4CA25C150A485EAD00B4E469 /* transupp.c in Sources */, + 4CA25C170A485EAD00B4E469 /* wrbmp.c in Sources */, + 4CA25C180A485EAD00B4E469 /* wrgif.c in Sources */, + 4CA25C1A0A485EAD00B4E469 /* wrppm.c in Sources */, + 4CA25C1B0A485EAD00B4E469 /* wrrle.c in Sources */, + 4CA25C1C0A485EAD00B4E469 /* wrtarga.c in Sources */, + 4C53E3B30A4856B30014E966 /* pngrutil.c in Sources */, + 4C53E3BB0A4856B30014E966 /* pngget.c in Sources */, + 4C53E3C40A4856B30014E966 /* pngrtran.c in Sources */, + 4C53E3C90A4856B30014E966 /* pngerror.c in Sources */, + 4C53E3CA0A4856B30014E966 /* gzio.c in Sources */, + 4C53E3D70A4856B30014E966 /* pngtrans.c in Sources */, + 4C53E3D80A4856B30014E966 /* inffast.c in Sources */, + 4C53E3DC0A4856B30014E966 /* inftrees.c in Sources */, + 4C53E3E40A4856B30014E966 /* uncompr.c in Sources */, + 4C53E3E90A4856B30014E966 /* pngset.c in Sources */, + 4C53E3EE0A4856B30014E966 /* pngrio.c in Sources */, + 4C53E3F30A4856B30014E966 /* compress.c in Sources */, + 4C53E3F60A4856B30014E966 /* crc32.c in Sources */, + 4C53E3FE0A4856B30014E966 /* zutil.c in Sources */, + 4C53E4010A4856B30014E966 /* trees.c in Sources */, + 4C53E4030A4856B30014E966 /* pngwio.c in Sources */, + 4C53E4040A4856B30014E966 /* pngmem.c in Sources */, + 4C53E40A0A4856B30014E966 /* deflate.c in Sources */, + 4C53E4110A4856B30014E966 /* pngpread.c in Sources */, + 4C53E4140A4856B30014E966 /* png.c in Sources */, + 4C53E4150A4856B30014E966 /* adler32.c in Sources */, + 4C53E4160A4856B30014E966 /* pngwtran.c in Sources */, + 4C53E41A0A4856B30014E966 /* pngwutil.c in Sources */, + 4C53E4280A4856B30014E966 /* CImageLoaderPNG.cpp in Sources */, + 4C53E4290A4856B30014E966 /* CColorConverter.cpp in Sources */, + 4C53E42A0A4856B30014E966 /* CSceneManager.cpp in Sources */, + 4C53E42B0A4856B30014E966 /* CTRTextureGouraudAdd2.cpp in Sources */, + 4C53E42C0A4856B30014E966 /* CNullDriver.cpp in Sources */, + 4C53E42D0A4856B30014E966 /* CCSMLoader.cpp in Sources */, + 4C53E42E0A4856B30014E966 /* irrXML.cpp in Sources */, + 4C53E42F0A4856B30014E966 /* CGUIListBox.cpp in Sources */, + 4C53E4300A4856B30014E966 /* CTRGouraudWire.cpp in Sources */, + 4C53E4310A4856B30014E966 /* CIrrDeviceStub.cpp in Sources */, + 4C53E4320A4856B30014E966 /* CGUIMessageBox.cpp in Sources */, + 4C53E4330A4856B30014E966 /* CMeshSceneNode.cpp in Sources */, + 4C53E4340A4856B30014E966 /* CGUIStaticText.cpp in Sources */, + 4C53E4350A4856B30014E966 /* os.cpp in Sources */, + 4C53E4360A4856B30014E966 /* COCTLoader.cpp in Sources */, + 4C53E4370A4856B30014E966 /* CGUIContextMenu.cpp in Sources */, + 4C53E4390A4856B30014E966 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */, + 4C53E43A0A4856B30014E966 /* CDefaultSceneNodeFactory.cpp in Sources */, + 4C53E43B0A4856B30014E966 /* CD3D9Driver.cpp in Sources */, + 4C53E43C0A4856B30014E966 /* CTRGouraud.cpp in Sources */, + 4C53E43D0A4856B30014E966 /* C3DSMeshFileLoader.cpp in Sources */, + 4C53E43E0A4856B30014E966 /* COgreMeshFileLoader.cpp in Sources */, + 4C53E43F0A4856B30014E966 /* CMY3DMeshFileLoader.cpp in Sources */, + 4C53E4400A4856B30014E966 /* CLMTSMeshFileLoader.cpp in Sources */, + 4C53E4410A4856B30014E966 /* CGUIFileOpenDialog.cpp in Sources */, + 4C53E4420A4856B30014E966 /* CSceneNodeAnimatorDelete.cpp in Sources */, + 4C53E4430A4856B30014E966 /* CTRGouraudAlphaNoZ2.cpp in Sources */, + 4C53E4440A4856B30014E966 /* CGeometryCreator.cpp in Sources */, + 4C53E4450A4856B30014E966 /* CD3D8Texture.cpp in Sources */, + 4C53E4460A4856B30014E966 /* CSkyBoxSceneNode.cpp in Sources */, + 4C53E4470A4856B30014E966 /* CMeshManipulator.cpp in Sources */, + 4C53E4480A4856B30014E966 /* CTextSceneNode.cpp in Sources */, + 4C53E4490A4856B30014E966 /* CTRTextureDetailMap2.cpp in Sources */, + 4C53E44A0A4856B30014E966 /* CTRTextureGouraudAddNoZ2.cpp in Sources */, + 4C53E44C0A4856B30014E966 /* CTRTextureGouraudNoZ.cpp in Sources */, + 4C53E44D0A4856B30014E966 /* CXFileReader.cpp in Sources */, + 4C53E44E0A4856B30014E966 /* CGUIScrollBar.cpp in Sources */, + 4C53E44F0A4856B30014E966 /* CSceneCollisionManager.cpp in Sources */, + 4C53E4500A4856B30014E966 /* CGUICheckBox.cpp in Sources */, + 4C53E4510A4856B30014E966 /* CQ3LevelMesh.cpp in Sources */, + 4C53E4520A4856B30014E966 /* CParticleGravityAffector.cpp in Sources */, + 4C53E4530A4856B30014E966 /* CSoftwareDriver2.cpp in Sources */, + 4C53E4540A4856B30014E966 /* CD3D9ParallaxMapRenderer.cpp in Sources */, + 4C53E4550A4856B30014E966 /* CD3D8ParallaxMapRenderer.cpp in Sources */, + 4C53E4560A4856B30014E966 /* CAnimatedMeshMD2.cpp in Sources */, + 4C53E4570A4856B30014E966 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */, + 4C53E4580A4856B30014E966 /* CImageLoaderPCX.cpp in Sources */, + 4C53E4590A4856B30014E966 /* CAnimatedMeshSceneNode.cpp in Sources */, + 4C53E45A0A4856B30014E966 /* CTriangleSelector.cpp in Sources */, + 4C53E45B0A4856B30014E966 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */, + 4C53E45C0A4856B30014E966 /* CTRTextureWire2.cpp in Sources */, + 4C53E45D0A4856B30014E966 /* CTRTextureFlatWire.cpp in Sources */, + 4C53E45E0A4856B30014E966 /* CTRGouraud2.cpp in Sources */, + 4C53E45F0A4856B30014E966 /* CEmptySceneNode.cpp in Sources */, + 4C53E4600A4856B30014E966 /* CTRTextureLightMap2_Add.cpp in Sources */, + 4C53E4610A4856B30014E966 /* CReadFile.cpp in Sources */, + 4C53E4620A4856B30014E966 /* COpenGLTexture.cpp in Sources */, + 4C53E4630A4856B30014E966 /* CAnimatedMeshMS3D.cpp in Sources */, + 4C53E4640A4856B30014E966 /* COSOperator.cpp in Sources */, + 4C53E4650A4856B30014E966 /* CMemoryReadFile.cpp in Sources */, + 4C53E4660A4856B30014E966 /* CColladaFileLoader.cpp in Sources */, + 4C53E4670A4856B30014E966 /* CCameraSceneNode.cpp in Sources */, + 4C53E4680A4856B30014E966 /* CMetaTriangleSelector.cpp in Sources */, + 4C53E4690A4856B30014E966 /* CTRTextureFlat.cpp in Sources */, + 4C53E46A0A4856B30014E966 /* CVideoModeList.cpp in Sources */, + 4C53E46B0A4856B30014E966 /* CXMLReader.cpp in Sources */, + 4C53E46C0A4856B30014E966 /* COpenGLParallaxMapRenderer.cpp in Sources */, + 4C53E46D0A4856B30014E966 /* CDefaultMeshFormatLoader.cpp in Sources */, + 4C53E46E0A4856B30014E966 /* CTRTextureGouraudNoZ2.cpp in Sources */, + 4C53E46F0A4856B30014E966 /* CTRTextureGouraudWire.cpp in Sources */, + 4C53E4700A4856B30014E966 /* CParticlePointEmitter.cpp in Sources */, + 4C53E4710A4856B30014E966 /* CGUIWindow.cpp in Sources */, + 4C53E4720A4856B30014E966 /* CGUIModalScreen.cpp in Sources */, + 4C53E4730A4856B30014E966 /* CImageLoaderPSD.cpp in Sources */, + 4C53E4740A4856B30014E966 /* CWaterSurfaceSceneNode.cpp in Sources */, + 4C53E4750A4856B30014E966 /* CXMeshFileLoader.cpp in Sources */, + 4C53E4760A4856B30014E966 /* CIrrDeviceLinux.cpp in Sources */, + 4C53E4770A4856B30014E966 /* CLightSceneNode.cpp in Sources */, + 4C53E4780A4856B30014E966 /* CTRTextureGouraudAdd.cpp in Sources */, + 4C53E4790A4856B30014E966 /* CTRTextureGouraud2.cpp in Sources */, + 4C53E47A0A4856B30014E966 /* CSoftwareDriver.cpp in Sources */, + 4C53E47B0A4856B30014E966 /* CTRFlatWire.cpp in Sources */, + 4C53E47C0A4856B30014E966 /* CTRGouraudAlpha2.cpp in Sources */, + 4C53E47D0A4856B30014E966 /* CSoftwareTexture2.cpp in Sources */, + 4C53E47E0A4856B30014E966 /* CZipReader.cpp in Sources */, + 4C53E47F0A4856B30014E966 /* COpenGLNormalMapRenderer.cpp in Sources */, + 4C53E4800A4856B30014E966 /* CTRTextureLightMap2_M1.cpp in Sources */, + 4C53E4810A4856B30014E966 /* CTRTextureLightMap2_M4.cpp in Sources */, + 4C53E4820A4856B30014E966 /* CGUISkin.cpp in Sources */, + 4C53E4830A4856B30014E966 /* CD3D8Driver.cpp in Sources */, + 4C53E4840A4856B30014E966 /* CIrrDeviceWin32.cpp in Sources */, + 4C53E4850A4856B30014E966 /* CFileSystem.cpp in Sources */, + 4C53E4860A4856B30014E966 /* CGUIMeshViewer.cpp in Sources */, + 4C53E4870A4856B30014E966 /* CGUIComboBox.cpp in Sources */, + 4C53E4880A4856B30014E966 /* CSceneNodeAnimatorRotation.cpp in Sources */, + 4C53E4890A4856B30014E966 /* CSceneNodeAnimatorTexture.cpp in Sources */, + 4C53E48A0A4856B30014E966 /* COctTreeSceneNode.cpp in Sources */, + 4C53E48B0A4856B30014E966 /* CParticleSystemSceneNode.cpp in Sources */, + 4C53E48C0A4856B30014E966 /* CTerrainSceneNode.cpp in Sources */, + 4C53E48D0A4856B30014E966 /* CCameraFPSSceneNode.cpp in Sources */, + 4C53E48E0A4856B30014E966 /* CGUIFont.cpp in Sources */, + 4C53E48F0A4856B30014E966 /* CParticleFadeOutAffector.cpp in Sources */, + 4C53E4910A4856B30014E966 /* CDummyTransformationSceneNode.cpp in Sources */, + 4C53E4920A4856B30014E966 /* CFileList.cpp in Sources */, + 4C53E4930A4856B30014E966 /* CImageLoaderTGA.cpp in Sources */, + 4C53E4940A4856B30014E966 /* CXMLWriter.cpp in Sources */, + 4C53E4950A4856B30014E966 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */, + 4C53E4960A4856B30014E966 /* CZBuffer.cpp in Sources */, + 4C53E4970A4856B30014E966 /* CDMFLoader.cpp in Sources */, + 4C53E4980A4856B30014E966 /* CD3D9Texture.cpp in Sources */, + 4C53E4990A4856B30014E966 /* COpenGLShaderMaterialRenderer.cpp in Sources */, + 4C53E49A0A4856B30014E966 /* Irrlicht.cpp in Sources */, + 4C53E49B0A4856B30014E966 /* CGUIEditBox.cpp in Sources */, + 4C53E49C0A4856B30014E966 /* COpenGLSLMaterialRenderer.cpp in Sources */, + 4C53E49D0A4856B30014E966 /* CD3D9HLSLMaterialRenderer.cpp in Sources */, + 4C53E49E0A4856B30014E966 /* CSoftwareTexture.cpp in Sources */, + 4C53E49F0A4856B30014E966 /* CCubeSceneNode.cpp in Sources */, + 4C53E4A00A4856B30014E966 /* CTriangleBBSelector.cpp in Sources */, + 4C53E4A10A4856B30014E966 /* CD3D9ShaderMaterialRenderer.cpp in Sources */, + 4C53E4A20A4856B30014E966 /* CD3D8ShaderMaterialRenderer.cpp in Sources */, + 4C53E4A30A4856B30014E966 /* CGUIButton.cpp in Sources */, + 4C53E4A40A4856B30014E966 /* CGUIToolBar.cpp in Sources */, + 4C53E4A50A4856B30014E966 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */, + 4C53E4A60A4856B30014E966 /* CBillboardSceneNode.cpp in Sources */, + 4C53E4A70A4856B30014E966 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */, + 4C53E4A80A4856B30014E966 /* CLogger.cpp in Sources */, + 4C53E4A90A4856B30014E966 /* CGUIInOutFader.cpp in Sources */, + 4C53E4AA0A4856B30014E966 /* CWriteFile.cpp in Sources */, + 4C53E4AB0A4856B30014E966 /* CXAnimationPlayer.cpp in Sources */, + 4C53E4AC0A4856B30014E966 /* CCameraMayaSceneNode.cpp in Sources */, + 4C53E4AD0A4856B30014E966 /* CTRTextureGouraud.cpp in Sources */, + 4C53E4AE0A4856B30014E966 /* CTRFlat.cpp in Sources */, + 4C53E4AF0A4856B30014E966 /* CTerrainTriangleSelector.cpp in Sources */, + 4C53E4B00A4856B30014E966 /* COctTreeTriangleSelector.cpp in Sources */, + 4C53E4B10A4856B30014E966 /* CGUITabControl.cpp in Sources */, + 4C53E4B20A4856B30014E966 /* CParticleBoxEmitter.cpp in Sources */, + 4C53E4B30A4856B30014E966 /* CGUIMenu.cpp in Sources */, + 4C53E4B40A4856B30014E966 /* CImage.cpp in Sources */, + 4C53E4B50A4856B30014E966 /* CShadowVolumeSceneNode.cpp in Sources */, + 4C53E4B70A4856B30014E966 /* CGUIEnvironment.cpp in Sources */, + 4C53E4B80A4856B30014E966 /* CLimitReadFile.cpp in Sources */, + 4C53E4B90A4856B30014E966 /* CAttributes.cpp in Sources */, + 4C53E4BA0A4856B30014E966 /* COpenGLDriver.cpp in Sources */, + 4C53E4BB0A4856B30014E966 /* CTRTextureLightMap2_M2.cpp in Sources */, + 4C53E4BC0A4856B30014E966 /* CGUIImage.cpp in Sources */, + 4C53E4BD0A4856B30014E966 /* CD3D9NormalMapRenderer.cpp in Sources */, + 4C53E4BE0A4856B30014E966 /* CD3D8NormalMapRenderer.cpp in Sources */, + 4C53E4BF0A4856B30014E966 /* CMeshCache.cpp in Sources */, + 4C53E4C00A4856B30014E966 /* CImageLoaderJPG.cpp in Sources */, + 4C53E4C10A4856B30014E966 /* CFPSCounter.cpp in Sources */, + 4C53E57E0A4856B30014E966 /* OSXClipboard.mm in Sources */, + 4C53E57F0A4856B30014E966 /* CIrrDeviceMacOSX.mm in Sources */, + 4C53E5800A4856B30014E966 /* AppDelegate.mm in Sources */, + 4C53E62E0A485ABF0014E966 /* pngread.c in Sources */, + 4C6DC9B70A48715A0017A6E5 /* inflate.c in Sources */, + 4CC36B0F0A6B61DB0076C4B2 /* CSphereSceneNode.cpp in Sources */, + 4C364EA40A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp in Sources */, + 4C43EEBC0A74A5A300F942FC /* CAnimatedMeshB3d.cpp in Sources */, + 4C43EEC00A74A5C800F942FC /* CPakReader.cpp in Sources */, + 4CFA7BEE0A88735A00B03626 /* CImageLoaderBMP.cpp in Sources */, + 4CFA7BF00A88735A00B03626 /* CImageWriterBMP.cpp in Sources */, + 4CFA7BF20A88735A00B03626 /* CImageWriterJPG.cpp in Sources */, + 4CFA7BF40A88735A00B03626 /* CImageWriterPCX.cpp in Sources */, + 4CFA7BF60A88735A00B03626 /* CImageWriterPNG.cpp in Sources */, + 4CFA7BF80A88735A00B03626 /* CImageWriterPPM.cpp in Sources */, + 4CFA7BFA0A88735A00B03626 /* CImageWriterPSD.cpp in Sources */, + 4CFA7BFC0A88735A00B03626 /* CImageWriterTGA.cpp in Sources */, + 4CFA7BFE0A88735A00B03626 /* CSkyDomeSceneNode.cpp in Sources */, + 5DD480480C7D8B9100728AA9 /* pngwrite.c in Sources */, + 5DD4804E0C7D91DF00728AA9 /* CDepthBuffer.cpp in Sources */, + 5DD480520C7D936700728AA9 /* IBurningShader.cpp in Sources */, + 5DD4805A0C7D945800728AA9 /* CAnimatedMeshMD3.cpp in Sources */, + 5DD4805C0C7D945800728AA9 /* CDefaultGUIElementFactory.cpp in Sources */, + 5DD480640C7D947B00728AA9 /* CGUIColorSelectDialog.cpp in Sources */, + 5DD480660C7D947B00728AA9 /* CGUISpinBox.cpp in Sources */, + 5DD480680C7D947B00728AA9 /* CGUISpriteBank.cpp in Sources */, + 5DD480710C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp in Sources */, + 5DD480730C7D94AC00728AA9 /* CTRTextureBlend.cpp in Sources */, + 5DD480740C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp in Sources */, + 5DD480750C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */, + 5DD480760C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */, + 5DD480CA0C7DA66800728AA9 /* CIrrDeviceSDL.cpp in Sources */, + 5DD480CB0C7DA66800728AA9 /* COpenGLExtensionHandler.cpp in Sources */, + 5DD480CC0C7DA66800728AA9 /* CMD3MeshFileLoader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 4CA5CB820A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B8DEF35C0950229200FDEA7E /* Demo */; + targetProxy = 4CA5CB810A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB840A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFFAF097FE5F80057C06F /* RenderToTexture */; + targetProxy = 4CA5CB830A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB860A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEC2097FDF020057C06F /* TerrainRendering */; + targetProxy = 4CA5CB850A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB880A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEA4097FDE900057C06F /* PerPixelLightning */; + targetProxy = 4CA5CB870A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8A0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF4A097FE3050057C06F /* Shaders */; + targetProxy = 4CA5CB890A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8C0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF91097FE45E0057C06F /* MeshViewer */; + targetProxy = 4CA5CB8B0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8E0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEE8097FE05F0057C06F /* SpecialFx */; + targetProxy = 4CA5CB8D0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB900A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFE82097FDDE20057C06F /* Collision */; + targetProxy = 4CA5CB8F0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB920A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFDFE097FD9F50057C06F /* 2DGraphics */; + targetProxy = 4CA5CB910A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB940A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF07097FE13E0057C06F /* UserInterface */; + targetProxy = 4CA5CB930A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB960A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF78097FE3DC0057C06F /* Movement */; + targetProxy = 4CA5CB950A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB980A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF1E097FE1E00057C06F /* CustomSceneNode */; + targetProxy = 4CA5CB970A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB9A0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF33097FE25F0057C06F /* Quake3Map */; + targetProxy = 4CA5CB990A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + B81CFDFF097FD9F50057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFE00097FD9F50057C06F /* PBXContainerItemProxy */; + }; + B81CFE83097FDDE20057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFE84097FDDE20057C06F /* PBXContainerItemProxy */; + }; + B81CFEA5097FDE900057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEA6097FDE900057C06F /* PBXContainerItemProxy */; + }; + B81CFEC3097FDF020057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEC4097FDF020057C06F /* PBXContainerItemProxy */; + }; + B81CFEE9097FE05F0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEEA097FE05F0057C06F /* PBXContainerItemProxy */; + }; + B81CFF08097FE13E0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF09097FE13E0057C06F /* PBXContainerItemProxy */; + }; + B81CFF1F097FE1E00057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF20097FE1E00057C06F /* PBXContainerItemProxy */; + }; + B81CFF34097FE25F0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF35097FE25F0057C06F /* PBXContainerItemProxy */; + }; + B81CFF4B097FE3050057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF4C097FE3050057C06F /* PBXContainerItemProxy */; + }; + B81CFF79097FE3DC0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF7A097FE3DC0057C06F /* PBXContainerItemProxy */; + }; + B81CFF92097FE45E0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF93097FE45E0057C06F /* PBXContainerItemProxy */; + }; + B81CFFB0097FE5F80057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFFB1097FE5F80057C06F /* PBXContainerItemProxy */; + }; + B8DEF375095024F600FDEA7E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B8DEF374095024F600FDEA7E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1DEB921F08733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MacOSX_Prefix.pch; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = Irrlicht; + SYMROOT = build; + ZERO_LINK = NO; + }; + name = Debug; + }; + 1DEB922008733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MacOSX_Prefix.pch; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = Irrlicht; + }; + name = Release; + }; + 1DEB922308733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ../../../include; + OTHER_CFLAGS = ( + "-DMACOSX", + "-D_DEBUG", + ); + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 1DEB922408733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ../../../include; + INSTALL_MODE_FLAG = "a+rwx"; + OTHER_CFLAGS = "-DMACOSX"; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; + B81CFE0D097FD9F50057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = 2DGraphics; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFE0E097FD9F50057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = 2DGraphics; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFE8E097FDDE20057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Collision; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFE8F097FDDE20057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Collision; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFEB0097FDE900057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = PerPixelLighting; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFEB1097FDE900057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_MODE_FLAG = "a+rwx"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = PerPixelLighting; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFECE097FDF020057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = TerrainRendering; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFECF097FDF020057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = TerrainRendering; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFEF4097FE05F0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SpecialFx; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFEF5097FE05F0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SpecialFx; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF13097FE13E0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = UserInterface; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF14097FE13E0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = UserInterface; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF2A097FE1E00057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = CustomSceneNode; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF2B097FE1E00057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = CustomSceneNode; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF3F097FE25F0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Map; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF40097FE25F0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Map; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF56097FE3050057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Shaders; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF57097FE3050057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Shaders; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF84097FE3DC0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Movement; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF85097FE3DC0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Movement; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF9D097FE45E0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MeshViewer; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF9E097FE45E0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MeshViewer; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFFBB097FE5F80057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = RenderToTexture; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFFBC097FE5F80057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = RenderToTexture; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFFE9097FE9C30057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = ALL; + }; + name = Debug; + }; + B81CFFEA097FE9C30057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + PRODUCT_NAME = ALL; + ZERO_LINK = NO; + }; + name = Release; + }; + B8DEF3610950229300FDEA7E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Demo; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B8DEF3620950229300FDEA7E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Demo; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libIrrlicht.a" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB921F08733DC00010E9CD /* Debug */, + 1DEB922008733DC00010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "MacOSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB922308733DC00010E9CD /* Debug */, + 1DEB922408733DC00010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFE0C097FD9F50057C06F /* Build configuration list for PBXNativeTarget "2DGraphics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFE0D097FD9F50057C06F /* Debug */, + B81CFE0E097FD9F50057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFE8D097FDDE20057C06F /* Build configuration list for PBXNativeTarget "Collision" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFE8E097FDDE20057C06F /* Debug */, + B81CFE8F097FDDE20057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFEAF097FDE900057C06F /* Build configuration list for PBXNativeTarget "PerPixelLightning" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFEB0097FDE900057C06F /* Debug */, + B81CFEB1097FDE900057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFECD097FDF020057C06F /* Build configuration list for PBXNativeTarget "TerrainRendering" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFECE097FDF020057C06F /* Debug */, + B81CFECF097FDF020057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFEF3097FE05F0057C06F /* Build configuration list for PBXNativeTarget "SpecialFx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFEF4097FE05F0057C06F /* Debug */, + B81CFEF5097FE05F0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF12097FE13E0057C06F /* Build configuration list for PBXNativeTarget "UserInterface" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF13097FE13E0057C06F /* Debug */, + B81CFF14097FE13E0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF29097FE1E00057C06F /* Build configuration list for PBXNativeTarget "CustomSceneNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF2A097FE1E00057C06F /* Debug */, + B81CFF2B097FE1E00057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF3E097FE25F0057C06F /* Build configuration list for PBXNativeTarget "Quake3Map" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF3F097FE25F0057C06F /* Debug */, + B81CFF40097FE25F0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF55097FE3050057C06F /* Build configuration list for PBXNativeTarget "Shaders" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF56097FE3050057C06F /* Debug */, + B81CFF57097FE3050057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF83097FE3DC0057C06F /* Build configuration list for PBXNativeTarget "Movement" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF84097FE3DC0057C06F /* Debug */, + B81CFF85097FE3DC0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF9C097FE45E0057C06F /* Build configuration list for PBXNativeTarget "MeshViewer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF9D097FE45E0057C06F /* Debug */, + B81CFF9E097FE45E0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFFBA097FE5F80057C06F /* Build configuration list for PBXNativeTarget "RenderToTexture" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFFBB097FE5F80057C06F /* Debug */, + B81CFFBC097FE5F80057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFFE8097FE9C30057C06F /* Build configuration list for PBXAggregateTarget "All" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFFE9097FE9C30057C06F /* Debug */, + B81CFFEA097FE9C30057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8DEF3600950229300FDEA7E /* Build configuration list for PBXNativeTarget "Demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8DEF3610950229300FDEA7E /* Debug */, + B8DEF3620950229300FDEA7E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.mode1 b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.mode1 new file mode 100644 index 0000000..86e10b9 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.mode1 @@ -0,0 +1,1316 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + 13A2354109D7E02B00660BB5 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 0867D691FE84028FC02AAC07 + 1C37FBAC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 23 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 566}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 584}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 322 169 841 625 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {633, 451}} + RubberWindowFrame + 322 169 841 625 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 451pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 456}, {633, 128}} + RubberWindowFrame + 322 169 841 625 0 0 1440 878 + + Module + XCDetailModule + Proportion + 128pt + + + Proportion + 633pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 139A8D7609D82183007061AD + 1CE0B1FE06471DED0097A5F4 + 139A8D7709D82183007061AD + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 13A2354609D7E09500660BB5 + /Users/susanne/Desktop/irrlicht-0.14.0/source/Irrlicht/MacOSX/MacOSX.xcodeproj + + WindowString + 322 169 841 625 0 0 1440 878 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 395 310 500 500 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 395 310 500 500 0 0 1440 878 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 13A2354609D7E09500660BB5 + 139A8D7809D82183007061AD + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 395 310 500 500 0 0 1440 878 + WindowToolGUID + 13A2354609D7E09500660BB5 + WindowToolIsVisible + + + + Identifier + windowTool.debugger + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {317, 164}} + {{317, 0}, {377, 164}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 164}} + {{0, 164}, {694, 216}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 380}} + RubberWindowFrame + 321 238 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 100% + + + Proportion + 100% + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1C0AD2AB069F1E9B00FABCE6 + 1C162984064C10D400B95A72 + 1C0AD2AC069F1E9B00FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 321 238 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + 0 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + CZipReader.cpp + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {768, 351}} + RubberWindowFrame + 375 124 768 664 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 768pt + + + Proportion + 351pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 356}, {768, 267}} + RubberWindowFrame + 375 124 768 664 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 267pt + + + Proportion + 623pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1358EE7709D7FA27005A4AEF + 1358EE7809D7FA27005A4AEF + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 375 124 768 664 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + Identifier + windowTool.debuggerConsole + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {440, 358}} + RubberWindowFrame + 650 41 440 400 0 0 1280 1002 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 358pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAAD065D492600B07095 + 1C78EAAE065D492600B07095 + 1C78EAAC065D492600B07095 + + WindowString + 650 41 440 400 0 0 1280 1002 + + + Identifier + windowTool.run + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {493, 167}} + {{0, 176}, {493, 267}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 443}} + {{414, 0}, {514, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {460, 159}} + RubberWindowFrame + 316 696 459 200 0 0 1280 1002 + + Module + PBXRunSessionModule + Proportion + 159pt + + + Proportion + 159pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + 1C0AD2B4069F1EA900FABCE6 + 1CD0528B0623707200166675 + 1C0AD2B5069F1EA900FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 316 696 459 200 0 0 1280 1002 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + + diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.pbxuser b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.pbxuser new file mode 100644 index 0000000..61128e3 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX.xcodeproj/susanne.pbxuser @@ -0,0 +1,682 @@ +// !$*UTF8*$! +{ + 0867D690FE84028FC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Release; + activeBuildStyle = 014CEA440018CDF011CA2923 /* Debug */; + activeExecutable = 13A2352B09D7E02400660BB5 /* Demo */; + activeTarget = B81CFEA4097FDE900057C06F /* PerPixelLightning */; + codeSenseManager = 13A2354309D7E02B00660BB5 /* Code sense */; + executables = ( + 13A2352B09D7E02400660BB5 /* Demo */, + 13A2352C09D7E02400660BB5 /* 2DGraphics */, + 13A2352D09D7E02400660BB5 /* Collision */, + 13A2352E09D7E02400660BB5 /* PerPixelLightning */, + 13A2352F09D7E02400660BB5 /* TerrainRendering */, + 13A2353009D7E02400660BB5 /* SpecialFx */, + 13A2353109D7E02400660BB5 /* UserInterface */, + 13A2353209D7E02400660BB5 /* CustomSceneNode */, + 13A2353309D7E02400660BB5 /* Quake3Map */, + 13A2353409D7E02400660BB5 /* Shaders */, + 13A2353509D7E02400660BB5 /* Movement */, + 13A2353609D7E02400660BB5 /* MeshViewer */, + 13A2353709D7E02400660BB5 /* RenderToTexture */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 394, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 214, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 165159288; + PBXWorkspaceStateSaveDate = 165159288; + }; + sourceControlManager = 13A2354209D7E02B00660BB5 /* Source Control */; + userBuildSettings = { + }; + }; + 13A2352B09D7E02400660BB5 /* Demo */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Demo; + sourceDirectories = ( + ); + }; + 13A2352C09D7E02400660BB5 /* 2DGraphics */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = 2DGraphics; + sourceDirectories = ( + ); + }; + 13A2352D09D7E02400660BB5 /* Collision */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Collision; + sourceDirectories = ( + ); + }; + 13A2352E09D7E02400660BB5 /* PerPixelLightning */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = PerPixelLightning; + sourceDirectories = ( + ); + }; + 13A2352F09D7E02400660BB5 /* TerrainRendering */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = TerrainRendering; + sourceDirectories = ( + ); + }; + 13A2353009D7E02400660BB5 /* SpecialFx */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = SpecialFx; + sourceDirectories = ( + ); + }; + 13A2353109D7E02400660BB5 /* UserInterface */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = UserInterface; + sourceDirectories = ( + ); + }; + 13A2353209D7E02400660BB5 /* CustomSceneNode */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = CustomSceneNode; + sourceDirectories = ( + ); + }; + 13A2353309D7E02400660BB5 /* Quake3Map */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Quake3Map; + sourceDirectories = ( + ); + }; + 13A2353409D7E02400660BB5 /* Shaders */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Shaders; + sourceDirectories = ( + ); + }; + 13A2353509D7E02400660BB5 /* Movement */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = Movement; + sourceDirectories = ( + ); + }; + 13A2353609D7E02400660BB5 /* MeshViewer */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = MeshViewer; + sourceDirectories = ( + ); + }; + 13A2353709D7E02400660BB5 /* RenderToTexture */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = RenderToTexture; + sourceDirectories = ( + ); + }; + 13A2354209D7E02B00660BB5 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + 13A2354309D7E02B00660BB5 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 32DBCF5E0370ADEE00C91783 /* MacOSX_Prefix.pch */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 319}}"; + sepNavSelRange = "{72, 6}"; + sepNavVisRect = "{{0, 0}, {727, 319}}"; + }; + }; + B81CFDFE097FD9F50057C06F /* 2DGraphics */ = { + activeExec = 0; + executables = ( + 13A2352C09D7E02400660BB5 /* 2DGraphics */, + ); + }; + B81CFE13097FDA590057C06F /* CMainMenu.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {746, 3486}}"; + sepNavSelRange = "{257, 0}"; + sepNavVisRect = "{{0, 0}, {592, 419}}"; + }; + }; + B81CFE14097FDA590057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {592, 686}}"; + sepNavSelRange = "{522, 6}"; + sepNavVisRect = "{{0, 183}, {592, 419}}"; + }; + }; + B81CFE21097FDAE40057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 2478}}"; + sepNavSelRange = "{770, 6}"; + sepNavVisRect = "{{0, 233}, {727, 319}}"; + }; + }; + B81CFE82097FDDE20057C06F /* Collision */ = { + activeExec = 0; + executables = ( + 13A2352D09D7E02400660BB5 /* Collision */, + ); + }; + B81CFE93097FDE0A0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 4102}}"; + sepNavSelRange = "{832, 6}"; + sepNavVisRect = "{{0, 226}, {727, 319}}"; + }; + }; + B81CFEA4097FDE900057C06F /* PerPixelLightning */ = { + activeExec = 0; + executables = ( + 13A2352E09D7E02400660BB5 /* PerPixelLightning */, + ); + }; + B81CFEB6097FDEC10057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 6454}}"; + sepNavSelRange = "{4570, 6}"; + sepNavVisRect = "{{0, 2116}, {727, 319}}"; + }; + }; + B81CFEC2097FDF020057C06F /* TerrainRendering */ = { + activeExec = 0; + executables = ( + 13A2352F09D7E02400660BB5 /* TerrainRendering */, + ); + }; + B81CFED4097FDF2E0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 3332}}"; + sepNavSelRange = "{1676, 6}"; + sepNavVisRect = "{{0, 730}, {727, 319}}"; + }; + }; + B81CFEE8097FE05F0057C06F /* SpecialFx */ = { + activeExec = 0; + executables = ( + 13A2353009D7E02400660BB5 /* SpecialFx */, + ); + }; + B81CFEFA097FE0900057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 3808}}"; + sepNavSelRange = "{757, 6}"; + sepNavVisRect = "{{0, 149}, {727, 319}}"; + }; + }; + B81CFF07097FE13E0057C06F /* UserInterface */ = { + activeExec = 0; + executables = ( + 13A2353109D7E02400660BB5 /* UserInterface */, + ); + }; + B81CFF19097FE17F0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 3374}}"; + sepNavSelRange = "{3624, 6}"; + sepNavVisRect = "{{0, 1822}, {727, 319}}"; + }; + }; + B81CFF1E097FE1E00057C06F /* CustomSceneNode */ = { + activeExec = 0; + executables = ( + 13A2353209D7E02400660BB5 /* CustomSceneNode */, + ); + }; + B81CFF33097FE25F0057C06F /* Quake3Map */ = { + activeExec = 0; + executables = ( + 13A2353309D7E02400660BB5 /* Quake3Map */, + ); + }; + B81CFF45097FE2920057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 2604}}"; + sepNavSelRange = "{1788, 6}"; + sepNavVisRect = "{{0, 576}, {727, 319}}"; + }; + }; + B81CFF4A097FE3050057C06F /* Shaders */ = { + activeExec = 0; + executables = ( + 13A2353409D7E02400660BB5 /* Shaders */, + ); + }; + B81CFF5C097FE33B0057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 5838}}"; + sepNavSelRange = "{4941, 6}"; + sepNavVisRect = "{{0, 1864}, {727, 319}}"; + }; + }; + B81CFF78097FE3DC0057C06F /* Movement */ = { + activeExec = 0; + executables = ( + 13A2353509D7E02400660BB5 /* Movement */, + ); + }; + B81CFF91097FE45E0057C06F /* MeshViewer */ = { + activeExec = 0; + executables = ( + 13A2353609D7E02400660BB5 /* MeshViewer */, + ); + }; + B81CFFA3097FE4A40057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 7420}}"; + sepNavSelRange = "{8220, 6}"; + sepNavVisRect = "{{0, 3726}, {727, 319}}"; + }; + }; + B81CFFAF097FE5F80057C06F /* RenderToTexture */ = { + activeExec = 0; + executables = ( + 13A2353709D7E02400660BB5 /* RenderToTexture */, + ); + }; + B81CFFC1097FE6420057C06F /* main.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 2926}}"; + sepNavSelRange = "{518, 6}"; + sepNavVisRect = "{{0, 0}, {727, 319}}"; + }; + }; + B81CFFC6097FE9980057C06F /* ALL */ = { + activeExec = 0; + }; + B8D46264094C6E5300898A14 /* CNullDriver.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {824, 19558}}"; + sepNavSelRange = "{17450, 14}"; + sepNavVisRect = "{{0, 10712}, {727, 319}}"; + }; + }; + B8D4626D094C6E5300898A14 /* COpenGLTexture.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {740, 4396}}"; + sepNavSelRange = "{4523, 14}"; + sepNavVisRect = "{{0, 2620}, {727, 319}}"; + sepNavWindowFrame = "{{292, 67}, {861, 780}}"; + }; + }; + B8D46272094C6E5300898A14 /* COpenGLDriver.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1100, 36106}}"; + sepNavSelRange = "{75498, 6}"; + sepNavVisRect = "{{0, 35632}, {727, 319}}"; + }; + }; + B8D46280094C6E5300898A14 /* CGUIFont.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {926, 4858}}"; + sepNavSelRange = "{1916, 14}"; + sepNavVisRect = "{{0, 1332}, {727, 319}}"; + }; + }; + B8D46282094C6E5300898A14 /* CGUIEnvironment.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {860, 9576}}"; + sepNavSelRange = "{2026, 14}"; + sepNavVisRect = "{{0, 1262}, {727, 319}}"; + }; + }; + B8D46298094C6E5300898A14 /* CQ3LevelMesh.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {908, 10290}}"; + sepNavSelRange = "{8402, 14}"; + sepNavVisRect = "{{0, 4020}, {727, 319}}"; + }; + }; + B8D4629C094C6E5300898A14 /* CImageLoaderTGA.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 2968}}"; + sepNavSelRange = "{2496, 14}"; + sepNavVisRect = "{{0, 1389}, {727, 319}}"; + }; + }; + B8D462A1094C6E5300898A14 /* CImageLoaderBmp.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {818, 5348}}"; + sepNavSelRange = "{5715, 14}"; + sepNavVisRect = "{{0, 3810}, {727, 319}}"; + }; + }; + B8D462A4094C6E5300898A14 /* CColorConverter.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {884, 4858}}"; + sepNavSelRange = "{6872, 14}"; + sepNavVisRect = "{{0, 4384}, {727, 319}}"; + }; + }; + B8D462AF094C6E5300898A14 /* CAnimatedMeshMD2.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {908, 11816}}"; + sepNavSelRange = "{16355, 14}"; + sepNavVisRect = "{{0, 8136}, {727, 319}}"; + }; + }; + B8D462B2094C6E5300898A14 /* CFileSystem.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 3304}}"; + sepNavSelRange = "{2600, 6}"; + sepNavVisRect = "{{0, 1654}, {727, 319}}"; + }; + }; + B8D462C7094C6E5300898A14 /* C3DSMeshFileLoader.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 9786}}"; + sepNavSelRange = "{14875, 14}"; + sepNavVisRect = "{{0, 8906}, {727, 319}}"; + }; + }; + B8D462D1094C6E5300898A14 /* CFileList.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 2422}}"; + sepNavSelRange = "{1285, 6}"; + sepNavVisRect = "{{0, 786}, {727, 319}}"; + }; + }; + B8D462D9094C6E5300898A14 /* CZipReader.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {866, 4872}}"; + sepNavSelRange = "{3788, 14}"; + sepNavVisRect = "{{0, 1836}, {727, 319}}"; + }; + }; + B8DEF35C0950229200FDEA7E /* Demo */ = { + activeExec = 0; + executables = ( + 13A2352B09D7E02400660BB5 /* Demo */, + ); + }; + B8E30CD3094ED594002CB3A0 /* CIrrDeviceMacOSX.mm */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1358, 8736}}"; + sepNavSelRange = "{16625, 6}"; + sepNavVisRect = "{{0, 8262}, {727, 319}}"; + }; + }; + B8F68273097AA76A00537976 /* AppDelegate.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 319}}"; + sepNavSelRange = "{346, 6}"; + sepNavVisRect = "{{0, 0}, {727, 319}}"; + }; + }; + B8F68274097AA76A00537976 /* AppDelegate.mm */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {727, 868}}"; + sepNavSelRange = "{257, 6}"; + sepNavVisRect = "{{0, 0}, {727, 319}}"; + }; + }; + D2AAC07D0554694100DB518D /* MacOSX */ = { + activeExec = 0; + }; +} diff --git a/src/dep/src/irrlicht/MacOSX/MacOSX_Prefix.pch b/src/dep/src/irrlicht/MacOSX/MacOSX_Prefix.pch new file mode 100644 index 0000000..b3ea109 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MacOSX_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'MacOSX' target in the 'MacOSX' project. +// + +#include diff --git a/src/dep/src/irrlicht/MacOSX/MainMenu.nib/classes.nib b/src/dep/src/irrlicht/MacOSX/MainMenu.nib/classes.nib new file mode 100644 index 0000000..b9b4b09 --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MainMenu.nib/classes.nib @@ -0,0 +1,4 @@ +{ + IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); + IBVersion = 1; +} \ No newline at end of file diff --git a/src/dep/src/irrlicht/MacOSX/MainMenu.nib/info.nib b/src/dep/src/irrlicht/MacOSX/MainMenu.nib/info.nib new file mode 100644 index 0000000..d4de41f --- /dev/null +++ b/src/dep/src/irrlicht/MacOSX/MainMenu.nib/info.nib @@ -0,0 +1,17 @@ + + + + + IBDocumentLocation + 195 413 356 240 0 0 1680 1028 + IBEditorPositions + + 29 + 62 343 338 44 0 0 1680 1028 + + IBFramework Version + 443.0 + IBSystem Version + 8F46 + + diff --git a/src/dep/src/irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib b/src/dep/src/irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..1a561028d8a607a9d0680a1d2d75e0bda3f7ec0a GIT binary patch literal 13030 zcmch7d0-Po*!Rq4XVcu9q`8xBt}TLq76^fG!4EkaAta`YxzgWg3O(I)gh`Vj3x`_O)L03Ak0(HH0x`VyT+=h64* zD!PV#L^sea^asY6!31lt3EQw8JFpx3@FTc7u8Hg5#<&T795=Wk>i}P?8=i}k{NnC+P;F0(#JONL}Q}9$g9nZq^@dErJUWgar6?i3n1FypC@Fx5o z-i$xMAK^Xt06vHh;UoAY{sN!EU*mK5JN!MqjIZLK@E!aszKj205Tj(07!{*sc*e%q z83*HGf{e(dGBubwOkJiP(}-!wv}M{c?U@eD6HFG94M#nhK1_%i0!O*bP$t5Z!qJmV z1v8d;niV@ieg0;{4zo@QZZgJ6^@=&EKn>` ztWc~}yrFnov01TQu|shHt{+q!R(z$nptz{`MsY=PRdG#m8?N3_+*RCD{K+a=J!@cj z*2dadpQ0~wgRQ~VgU|YGL$(R~INOY!$S!6-WVf?B**)xj_7M9idyM@Ijby)IPqAOJ zU$LjzGiV8Wp1sI^2j7?3E9{T#4fZDKOSY38>|6#9Tilb^^9@-z8`+$6WiZE}bFO74>1$nWG2a*zB;?sJI49K$I%mLnX;DY+z0 z#i=v@oRzb2cFw^$ITz>VJX{JVa9+;G`8kn$gnP7Su%x1> z=qztSI;2Mi#3LgzAu~!w7Gy;>WJeCB1%Qo&?Bfis(~Iw zHBl{88$E{7Vrkheo}#@%MHOL4R7XZutK8ghd3nK*f}(=x=r)m(5=h}lSv-l`6otym z!{zb2`(|WyE66K{#4hibk(CiD4#$oMWMoy|CjasZQE*nNL7dF?5BVPuuzeXwI5JXJ2xHnuN}^puC843= zvOa(p9uyQyTA|iUQESv4_TQ77PoOT#P#4q{wE$NoWC%xl zf&k%Yd}KEiS;q^gJIX{oP!`HYJy9=|gL>45(TQ{l zola-b7wF4$5q+J$N!K1nPl66*s2oL6MNURmm(Y-Kk!+<%MOki`TB(g{zCa_9dt^Hmj0)$)u2ZdP{Qdj)O^~XH>ZpP0shL_% zfDBWBe=2$wO+(Ys3}BXH2I5B+pi?wlTuwiw$LMx?q<7bXl7ixbG2zVO<7hSvs*C2J zx#)RtagT6$OubmR8L5f#AXtnx9x(vbW>`44usBp!829D^^x`t~B6>-VDaf^Wj3i({ zQ}LhI5|j&NN}4Ql#74?u#^h+QzTOOHsnzZ-Kj4Q#W|m@n7Cu z2i{#TdzWgd6CB`@9WaPDwU)Ed+p4I@8;y9|mjPe*xU}!d(i%c#WucOx;Z7y7pFq+C zjEMZKw+ zrE&U$D7{xH$QFHo^Aq4aLaPC1@V_{Z1LtRzoFZ_h%AAEj5Q0<-!%UC`pO71<6sRgS z{R*WIEUPH#4)NP1G&)l8Amtgj`5dhUl+_=mybx3KB2Zq6QP!Z30%gqy)w~R9UXd_E zw@X+7-p>e+e4y@mJBEu&Gh4(pz7F-Vd{|_peC+|He+CI|(z+nQV-HJkJ0`)MD&MBj zItkzYm0b7GpJ+Np^k;e#%>7H>Hbvo3nOBa@7%^7Jp0?!5S9^qW!zIzSk=%-6_$~)A zPGGLGrljE{6vb*N3vI*Y(SnkA7JDQd{-dm?3d;j&neLn@c#h05|`_jM1Igp2;cTN`-O zfVUO!Hvd<}aXnlg6mJ+;+yo5?qAfsxma_K!Iu_)Gz1^b2V1bZ1Y!Gi92IsNU2O^`q z$%C3U2ga7b*d7?${3|1vx(zV4t2A|6AZsU+^@)+m7VRn1{0+4Wpk@GSXF%=vU#OW6 z*sxQ=hP|^OPUWHj(pQwoz;OIG=_|_w?gJeCXg6T!@(=@xl?gl$;lDh}ZO2}PVd~g{AU6k&EklQ_o zcg7|MZ&qozs7S7bp>l7ZNQF0hbZK}HpAwA>9au^CyMWmuUc3W%&+*>8kC=h52 z?F$0+dRU;bF@c^2HOI%)%%QzOpgyvi34tbpK+n+kK%mXpJ)z^v921YtXHk033ON6( z9^e^3HIohks{a2)H3z7kucR6PR0CzI>^70o(V4k%+?N117tSBReFbn|qj`WEdKfou z(;o#8!A;8 z3RJ^lLD4-_9t~%Xh%>w|&k*v32avY{@-|um$b}ChZ;$z5M^#`H(PBW3O@s+Q>;*sU zr~APV2L@!p!d;GvP@&wfLKj(@IH_{`VW9hzmIGbs!*p>)j)5X4DiwJW=*nb8pyP;U zj*6@CB}&iEeQ?gfrvddW9R;Wr52MCCaRE@jsr1AMKpiQg7Qp0I3e#H={K>QFP?+MH z#7TaLP3H3K(g7AX<%z16$fs+-c%42CjAI^VjO+0;Fy5@x<0)VqD>G*I2t%y)jdT14 zF;xcV54htV;NGVb0C)U<;4%!Fz_69L6mTUOw{KRs2-aG1g~<%X&>1yM1m&@-aPcn+ zMu(z|fldaBNe@%RJkFRN@c1)85%c&!DD!2}D*p~FmrwucV8#jPZaNLnr#_4xGYlhC zq36(N6X?C#f~e7OPG0OQ5id+NfU8bt0^E#;;No34Q?m+AOP@=?W%rFliu+fVLixA~ zu|6O+r1JoA_NjmN^-Ma`SPprn3D~%)Y-6ScELgHbL+Knk7qFj~ZO!A#;AdK)=}a5C z4TArpFg$9KLnseID1Q)dtE6rZtI=5Ow91v2ZB`h+-#D)Kj*bfi~#1IDq;wymoY79{^AcokzEIgtB zN_J+41Zp0j=F??>y7<3Q3jnn+hFSusO8|9g3{?q}UC;8cHy)dyz8Cs7-s_(~ZZ)*PKHic94lyb3;ZIJ6~lI~Fdhy4II-o&nY=G1eTq3RqXiSuL@O>V<~K+cgx;9p=r7jxGvk z_5yigrL|Rg_o7fiNjCTfDhVvnnVHP2Wy~yQc5HE7xe#szi-ggz=8ApC7Q@V3=JR!Y z8>TZe51(b`qpi3f_A*gsAx=Z%a0Y%2t!5fC)tQD^%`9hDFe{linBMq0vx-^GtifxU zb&P>o&%DEIVBW=r%qHeN=-AKU0=$jc%1pqY;_b|KW(Skc>_ius-S|G^X7-`m%mH)+ z)ZK<#VlAG@9A%E-G0X{Qp6AoIX$9RtQ)n03gf6ECX>(Wwb)+Hc04L0#vuS;LobI6S z(z|pa9Yg=17wBc0PxsJC^cMY^UZ=m)9`p%lqi$j%uC z)jR}GdgVn+D^w1NnDu2m!uprN>7y>PP1+4w!xeChV z(2W2dtA2D-RS(WwWv)TuU#Fi-n1$RwncXh0AUd!-KE5*1<2CpvlwSFmgt>(xYw#HG z*n8lOnc%Srj2rxL46MF_SqB=A0c(|l{`p|3sbHHeV2K@I(Y2LI$SNpE`~if5lcN+K zLBOo9P{)_43N<`H=v3aepj>|3lLxDgPUTtQ(ok6l9>IYsE^1K4by59)BmV2Kzgsgd z2-8^MN?23jg<*5()+*C|m@Vgg%pwY3l|>XHiY#XuLd5rmxQs$f&4*Z84AHhWmN<%9 zXyj7xUyFZrVw@HiD(Y0xHU!!p^y4bpoxKyCR4l_3jZtJ7K8s(2Mz{hZIkU>L|E3V$ zu4q+-+#ZmN=-w*ieZ2rVoI5Oz+X+RMG6v|PCPAF9tqK!GhN2squE?Z^=qC^*hvWKZ zq4eHa;j$40@SwCZG!(s1WHDU}&khF3569xaRV_9ZeW7cMKh#XzKLABuM-@;EcEB?X z4W#2yNXvf@llUC@_b`D>ejpYG0%_$lQG7A-@RVJx`Ts=rnRGH+n>|!W; zaf6JK9lMFy$;^lHbO6f0H&9CcfHY6Y_;-U>=A#yytI(%F@-=`pZX)@<%$65qar9{@ zvIC9 z|^G^ zMD;E@0*}5f!z6GWriU(2^xuYw<98_gDRk{awvN|$#c8nh*~%LK1JGWPZ4J-cM`o7% z*N|^v$oG{)uECHW^qXq0j?n{(BLxB>r0w2jT~^^FK6YRcHdMsnqliNcpR* zX?9jY~;rG#;|{HQNxezsnf`PoLY`OiV4v9=!=zbn+Cc=d$t zi*3rxUMlxqvD(2lk2hJ3q2(zAQMbXj7TT)i@VN?Fph7f`IST(bhGQ+vFllHT9FJvI zLi%sRW8rVRJVG8Pw_tF`ICKFQ#;(Gz%sTiDMniLUKpqdjZ-YDl9;k#nfn!q)L&njf z+b~56Fki`8B|!0+168X5RLKT#O$$@M7OpgazZ`hpB*1YF+}Qw*a$<9lJVG8Pw_rJN zZw(k#RQc;3_)Q-DE>v83yxdw{kMV4PO56bIv3yPbYe3VW$%>n1l583$B$R_seB8>xD4XH4Z>7F z;mriP>Og)P68E@NM3m$NI_mFyero9tWcDt0xyhF#09 zi~YUBZh-HN>?Za-b~F1v9Dg8T*iTbSSR-Mrgmn_uOV}V`UcyERnSWh}e-B)! z8xsp&SAhGn>eQ_hm+~wOtVh|SAn*kVyJGDV`we?(8GDKS7PXK!iD3IT2R3Qs@Aw!H zFTo26B@V9wQUmz}cJ|oo%;$@%9QE^qC%0s;%l?p2??T2ELWr$| ztmzCnauae2mN%$?IT~A-425ORDhNVop&0|}3(J>&uq?`F=Ai+2E$RvRTMP>xH|m8l zp*O0)X^?ksK-LvNx3C_TPWNH&FuuQdL|&>xrtXF{a|QGbU0`oe4Z%7Fnwk^{*WnPP z$03BjfvnQP?qPrW2<#%J!Omd~*llbBE&5>CT?|7wcZ8k98FUNmKrW}_VApX61UUoy zi>Dzeu0u=P0H%eU*z#x=WVO7onF3AyACMMuyFUr`D(}N?r2`t@w_(RJA9gW&z|LeL zECK4l&gN0*@0vsRbQiKV6S|vQ&?b+EJ@GM&sI&yksA7MV@vkh$b}GLO7K=92~FMe-7PnJgr) zkXOlTWD!|RmXM`n8F`&7Co9NG@&OV*LM$$Ih**+AYU8_6c}9@$LZ zCtJt|WGnfQY?Ck)3Q@wT60RoUMpO899BkCX6t2~!D65}qL8i4vY9;b$Z~8NAOQ;+ycD z_{+S=NBEQc1U`d*g1^XjV1Ks8Yv)C68X$b?#uhw>FvF@6yh1iIf)Fib@8fi@0kW7*V z$rgr08VRW}7efDa2=UGE_RtAOLqwzB<)PvowPS;f6|$xvq|44{g(8HN~O}MbSi@?O;uM_U)4~R zu4*HP1S9+P3=&-)E>2<_NfEvG<7|719iGOL)~57N1dwQ~i^)JxRM)XUYI)SJ~?)LYft)ce)P)IX@Ns_$tu8lA?VF>1`3`kIECbWIaYQ%!SC zOHHOGOVd-6qv@l`)r2)An$eo4G&3|aHM2EyHS;vnrpV^po_H^;7k4>R0L4=-27j>o@2( z>bK~(>UZl8>JRI`)PJo%qd#ZB28Dqblm?YSW6&Agh7?0JLqkKlp`D?Fp_AbWLy@7x zP--YML=7VhqYUE=)bOlfwqdSekzt8pnPItMk71wTfZ>qg6T=b1F~eEIdBa7+CBrW~ z=Jhl*7Ddm3|$eT@B#1B`== zA!CuT#5mG8!8pk{$N0SQ1>*waX5$v)R^v9~cH_s!UB=_a3&!il8^&LZw@g-(-Q+a6 zO(`a?$#1G|s$*(yYH4b1YHJFchMEdYg{ERt#Pp3t>XH4fz7fjbo*Uc)k)oeFA&2Doma~pFza|d%L^AqN-=5FRb=6>d3 z=HccdbBXzR^9$w$=9kP1&99mlnU|Q?nb(`QnYWuiHt#ZDHeWGcGha8~F#lq{WxkWl zC!3OmWM6V1Sxj!9+%dUxa+l?B~ML$A$dXaOUVn9wRarGwoz-A9TFq9A)n;{AT~?1(u==b4t7xret!{nPTFd&FwT`u(wShI=+Q-_@ zI>0)}8nWhE!`2bjQPw5aRn~W{o2;9yTdZ5H+pOEIA6s`>KeL{+erf&Mdd7Ou`m^pdH1^VtG6(N@h?-S()hmhCZH9a}wH16w0oW834lX107=xlOW7v^`^+Vw-B4W}9J~ zX`5x+Y};bnYTIV}$hO0_)3)2T$9COz!}g2qmhF!1uI+c*J==XdYuDKgcDp@b7wy&T z)$NbkYuO*Or`wy^^XE8u|IEr!M?!0-TtwCmwk_Y zpZ$RSko^<;5&KE|Ir}C1clOKnEA~I^e>#wZaj*`Z!|Jd*d=9@O=xFF@;b`yZ=*V>R zb@X=(bPRS3apXCkbIfwgaXjys=a}z!(ebilq2n#bamQzlla5o4uNqN4XOgpyv!1hovyrp0^KoZ0XA5U5XM1NiXTEcobGWm}S>h~pmN}!& z5zbN0G0w5han5DV<<6DPH=V1TYn{lun&NuaHQn``Yo=?VYnN+}YoF_Y>yYac z*Adq-*9q4t*9F%%u4``A&AF4@YPZ&{ck^zOJK1e@+ucsL+uh9F!rjW<#@)`{!QIK- z)!ofq>MnCf-6Pzi++*Bh-BaApy5DiX>)zzv?B3$u>fYww?*7>QiTkAcl>37FlKVUN zWe?+d)Kkmzn5T}XuBX1Ip(owb*wfe3-!srN*fYeF=gIdJdWt>MJTp8qJ+nP?J@Y*C zJ+FH9c=mY?cn*0Edp`9X^&Iz{@Z9sqGG)rlb(ki7* zO1qSfDP2=~rSwh-rR1gLrwmJpraYZ8A!WLdELa7*;1t|Kir^LeLQqH*9uaB?HHF$j znow7$FEkX=g(gB%p}EjfXf3oA+6x_p&O#RJn6c|yK0 zOc*W{2_-_QP$oo$5yB{8j4)Oh2h0Bn!X#m`Fjbf)%n)V@vxT|BJYl}@qVTfts<1*h zEu0n33m1h;!gs=D;fiogxGvlfei3d7cZ9pb@4`Ldz88BHUgA}HRbGu(=QVhZ-ej-G zo9)f<_Vo_%4)*4H^SuS$B5%Z7=B@CK@;>Dq=asyZyi>f>yw7=Od!P5t_rBzP#k6$#Cyzp!h70#)_dOjgZHZUNADf)UGMKc*2nphd`4f2&+Du1 zd(>CU*VxzG*V&il>*?#`8{*6J<@*YKCBBiqalU7K&-v#2Ui2;TE%UARt@XX_d*8Rk z_n~i(Z?Erw@3{XJ|7-rm{-yrc{VV)$_}}uc_OJE7?SIGru78t%vww?!tACq+yZ>YV zF8?0?KK}v#A^#`-BmQIl6aLTrU--ZDf9*fxKj**T|Hl8V|9k%r{;U2U{XhAC_TTj1 z_W$bt&Hso0&j1QA0XDz|k^<_0HlPpi0aGA3U=7#<&VW0R67UB6fnXpt@JOIWpk|@ND3})<8XO)h4weSXgCl~YgJXl^ zgA;C4MEI z7SD?3#f#!4@jLOdctyM>UKekOzlgWQJK|mOck!NhKNY7cQc0>ZRh6nq)ukFzjj85T zOR6o^k?KnIqzb9N)Ih43S}ip#wN7fi)TXJ;Qd_2WO6{E5HMLi2KNR~1FJQ#}akb;$ JiO + +void OSXCopyToClipboard(const char *text) +{ + NSString *str; + NSPasteboard *board; + + if (text != NULL && strlen(text) > 0) + { + str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding]; + board = [NSPasteboard generalPasteboard]; + [board declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:NSApp]; + [board setString:str forType:NSStringPboardType]; + } +} + +char* OSXCopyFromClipboard() +{ + NSString *str; + NSPasteboard *board; + char *result; + + result = NULL; + board = [NSPasteboard generalPasteboard]; + str = [board stringForType:NSStringPboardType]; + if (str != nil) result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding]; + return (result); +} diff --git a/src/dep/src/irrlicht/Makefile b/src/dep/src/irrlicht/Makefile new file mode 100644 index 0000000..ad593c9 --- /dev/null +++ b/src/dep/src/irrlicht/Makefile @@ -0,0 +1,134 @@ +VERSION = 1.4 +# Irrlicht Engine 1.4 +# Makefile for Linux +# +# To use, just run: +# +# make +# +# This will compile Irrlicht, create a static lib (libIrrlicht.a), and copy it +# into the subdirectory lib/Linux. That's all. +# +# If you want Irrlicht to be compiled as shared lib (libIrrlicht.so.versionnumber), then run: +# +# make sharedlib +# make install +# +# Please note that Irrlicht as shared lib is just experimental and +# probably not tested. +# + +#List of object files, separated based on engine architecture +IRRMESHLOADER = CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o CBSPMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CMD3MeshFileLoader.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMY3DMeshFileLoader.o COCTLoader.o CXMeshFileLoader.o CIrrMeshFileLoader.o CSTLMeshFileLoader.o +IRRMESHWRITER = CColladaMeshWriter.o CIrrMeshWriter.o CSTLMeshWriter.o +IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \ + CSkinnedMesh.o CBoneSceneNode.o CMeshSceneNode.o \ + CAnimatedMeshSceneNode.o CAnimatedMeshMD2.o CAnimatedMeshMD3.o \ + CQ3LevelMesh.o CQuake3ShaderSceneNode.o +IRROBJ = CBillboardSceneNode.o CCameraFPSSceneNode.o CCameraMayaSceneNode.o CCameraSceneNode.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CMeshManipulator.o CMetaTriangleSelector.o COctTreeSceneNode.o COctTreeTriangleSelector.o CSceneCollisionManager.o CSceneManager.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o +IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o +IRRANIMOBJ = CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o +IRRDRVROBJ = CNullDriver.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D8Driver.o CD3D8NormalMapRenderer.o CD3D8ParallaxMapRenderer.o CD3D8ShaderMaterialRenderer.o CD3D8Texture.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o +IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderTGA.o CImageLoaderPPM.o\ + CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o +IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ) +IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o +IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryReadFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o irrXML.o CAttributes.o +IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceStub.o CIrrDeviceWin32.o CLogger.o COSOperator.o Irrlicht.o os.o +IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o +ZLIBOBJ = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o +JPEGLIBOBJ = jpeglib/jcapimin.o jpeglib/jcapistd.o jpeglib/jccoefct.o jpeglib/jccolor.o jpeglib/jcdctmgr.o jpeglib/jchuff.o jpeglib/jcinit.o jpeglib/jcmainct.o jpeglib/jcmarker.o jpeglib/jcmaster.o jpeglib/jcomapi.o jpeglib/jcparam.o jpeglib/jcphuff.o jpeglib/jcprepct.o jpeglib/jcsample.o jpeglib/jctrans.o jpeglib/jdapimin.o jpeglib/jdapistd.o jpeglib/jdatadst.o jpeglib/jdatasrc.o jpeglib/jdcoefct.o jpeglib/jdcolor.o jpeglib/jddctmgr.o jpeglib/jdhuff.o jpeglib/jdinput.o jpeglib/jdmainct.o jpeglib/jdmarker.o jpeglib/jdmaster.o jpeglib/jdmerge.o jpeglib/jdphuff.o jpeglib/jdpostct.o jpeglib/jdsample.o jpeglib/jdtrans.o jpeglib/jerror.o jpeglib/jfdctflt.o jpeglib/jfdctfst.o jpeglib/jfdctint.o jpeglib/jidctflt.o jpeglib/jidctfst.o jpeglib/jidctint.o jpeglib/jidctred.o jpeglib/jmemmgr.o jpeglib/jmemnobs.o jpeglib/jquant1.o jpeglib/jquant2.o jpeglib/jutils.o +LIBPNGOBJ = libpng/png.o libpng/pngerror.o libpng/pngget.o libpng/pngmem.o libpng/pngpread.o libpng/pngread.o libpng/pngrio.o libpng/pngrtran.o libpng/pngrutil.o libpng/pngset.o libpng/pngtrans.o libpng/pngwio.o libpng/pngwrite.o libpng/pngwtran.o libpng/pngwutil.o +# Next variable is for additional scene nodes etc. of customized Irrlicht versions +EXTRAOBJ = +LINKOBJ := $(IRRMESHOBJ) $(IRROBJ) $(IRRPARTICLEOBJ) $(IRRANIMOBJ) \ + $(IRRVIDEOOBJ) $(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) \ + $(IRRGUIOBJ) $(ZLIBOBJ) $(JPEGLIBOBJ) $(LIBPNGOBJ) $(EXTRAOBJ) + +############### +#Compiler flags +CXXINCS = -I../../include -Izlib -Ijpeglib -Ilibpng +CPPFLAGS = $(CXXINCS) -DIRRLICHT_EXPORTS=1 +CXXFLAGS = -Wall +ifndef NDEBUG +CXXFLAGS += -g -D_DEBUG +else +CXXFLAGS += -fexpensive-optimizations -O3 +endif +ifdef PROFILE +CXXFLAGS += -pg +endif +CFLAGS := -fexpensive-optimizations -O3 -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES + +#Linux specific options +STATIC_LIB = libIrrlicht.a +SHARED_LIB = libIrrlicht.so +IRRLICHT_DLL := ../../bin/Win32-gcc/Irrlicht.dll +LIB_PATH = ../../lib/$(SYSTEM) +INSTALL_DIR = /usr/local/lib +staticlib sharedlib install: SYSTEM = Linux +staticlib sharedlib : LDFLAGS = --no-export-all-symbols --add-stdcall-alias +sharedlib : LDFLAGS += -L/usr/X11R6/lib -lGL -lXxf86vm +staticlib sharedlib : CXXINCS += -I/usr/X11R6/include + +#Windows specific options +sharedlib_win32 staticlib_win32: SYSTEM = Win32-gcc +sharedlib_win32: LDFLAGS = -lgdi32 -lopengl32 -ld3dx9d -lSDL +sharedlib_win32 staticlib_win32: CPPFLAGS += -DIRR_COMPILE_WITH_DX9_DEV_PACK -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL +staticlib_win32: CPPFLAGS += -D_IRR_STATIC_LIB_ + +#################### +# All target, builds Irrlicht as static lib (libIrrlicht.a) and copies it into /lib/Linux +all linux: staticlib + +# Builds Irrlicht as shared lib (libIrrlicht.so.versionNumber) and copies it into /lib/Linux +sharedlib: $(LINKOBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,$(SHARED_LIB).1 -fPIC -o $(SHARED_LIB).$(VERSION) $^ $(LDFLAGS) + cp $(SHARED_LIB).$(VERSION) $(LIB_PATH) + +# Builds Irrlicht as static lib (libIrrlicht.a) +$(STATIC_LIB): $(LINKOBJ) + $(AR) rs $@ $^ + +# Copies static lib into /lib/Linux +staticlib: $(STATIC_LIB) + cp $^ $(LIB_PATH) + +# Builds Irrlicht as dll (Irrlicht.dll) into ../../bin/Win32-gcc +all_win32 win32: sharedlib_win32 +sharedlib_win32: $(IRRLICHT_DLL) +../../bin/Win32-gcc/Irrlicht.dll: $(LINKOBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -o $@ $^ $(LDFLAGS) -Wl,--out-implib,../../lib/Win32-gcc/$(STATIC_LIB) +# Copies static lib into /lib/Win32-gcc +staticlib_win32: $(STATIC_LIB) + cp $^ $(LIB_PATH) + +# Installs Irrlicht if it was created as shared lib +install: + cp $(LIB_PATH)/$(SHARED_LIB).$(VERSION) $(INSTALL_DIR) + cd $(INSTALL_DIR) && ln -s libIrrlicht.so.$(VERSION) $(SHARED_LIB) + ldconfig -n $(INSTALL_DIR) + +# Create dependency files for automatic recompilation +%.d:%.cpp + $(CXX) $(CPPFLAGS) -MM -MF $@ $< + +-include $(LINKOBJ:.o=.d) + +help: + @echo "Available targets for Irrlicht" + @echo " sharedlib: Build shared library Irrlicht.so for Linux" + @echo " staticlib: Build static library Irrlicht.a for Linux" + @echo " install: Copy shared library to /usr/lib" + @echo "" + @echo " sharedlib_win32: Build shared library Irrlicht.dll for Windows" + @echo " staticlib_win32: Build static library Irrlicht.a for Windows" + @echo "" + @echo " clean: Clean up directory" + +# Cleans all temporary files and compilation results. +clean: + $(RM) $(LINKOBJ) $(SHARED_LIB).$(VERSION) $(STATIC_LIB) $(LINKOBJ:.o=.d) + +.PHONY: all sharedlib staticlib sharedlib_win32 staticlib_win32 help install clean + diff --git a/src/dep/src/irrlicht/OctTree.h b/src/dep/src/irrlicht/OctTree.h new file mode 100644 index 0000000..1085f94 --- /dev/null +++ b/src/dep/src/irrlicht/OctTree.h @@ -0,0 +1,381 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCT_TREE_H_INCLUDED__ +#define __C_OCT_TREE_H_INCLUDED__ + +#include "SViewFrustum.h" +#include "S3DVertex.h" +#include "aabbox3d.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ + +//! template octtree. T must be a vertex type which has a member +//! called .Pos, which is a core::vertex3df position. +template +class OctTree +{ +public: + + u32 nodeCount; + + struct SMeshChunk + { + core::array Vertices; + core::array Indices; + s32 MaterialId; + }; + + struct SIndexChunk + { + core::array Indices; + s32 MaterialId; + }; + + struct SIndexData + { + u16* Indices; + s32 CurrentSize; + s32 MaxSize; + }; + + + + //! constructor + OctTree(const core::array& meshes, s32 minimalPolysPerNode=128) + { + nodeCount = 0; + + IndexDataCount = meshes.size(); + IndexData = new SIndexData[IndexDataCount]; + + // construct array of all indices + + core::array* indexChunks = new core::array; + SIndexChunk ic; + + for (u32 i=0; ipush_back(ic); + + SIndexChunk& tic = (*indexChunks)[i]; + + for (u32 t=0; t& box) + { + for (u32 i=0; igetPolys(box, IndexData, 0); + } + + //! returns all ids of polygons partially or fully enclosed + //! by a view frustum. + void calculatePolys(const scene::SViewFrustum& frustum) + { + for (u32 i=0; igetPolys(frustum, IndexData, 0); + } + + + SIndexData* getIndexData() + { + return IndexData; + } + + u32 getIndexDataCount() + { + return IndexDataCount; + } + + // for debug purposes only, renders the bounding boxes of the tree + void renderBoundingBoxes(const core::aabbox3d& box, + core::array< core::aabbox3d >&outBoxes) + { + Root->renderBoundingBoxes(box, outBoxes); + } + + //! destructor + ~OctTree() + { + for (u32 i=0; i& allmeshdata, + core::array* indices, + s32 minimalPolysPerNode) : IndexData(0), + Depth(currentdepth+1) + { + ++nodeCount; + + u32 i; // new ISO for scoping problem with different compilers + + for (i=0; i<8; ++i) + Children[i] = 0; + + if (indices->empty()) + { + delete indices; + return; + } + + bool found = false; + + // find first point for bounding box + + for (i=0; isize(); ++i) + { + if (!(*indices)[i].Indices.empty()) + { + Box.reset(allmeshdata[i].Vertices[(*indices)[i].Indices[0]].Pos); + found = true; + break; + } + } + + if (!found) + { + delete indices; + return; + } + + s32 totalPrimitives = 0; + + // now lets calculate our bounding box + for (i=0; isize(); ++i) + { + totalPrimitives += (*indices)[i].Indices.size(); + for (u32 j=0; j<(*indices)[i].Indices.size(); ++j) + Box.addInternalPoint(allmeshdata[i].Vertices[(*indices)[i].Indices[j]].Pos); + } + + core::vector3df middle = Box.getCenter(); + core::vector3df edges[8]; + Box.getEdges(edges); + + // calculate all children + core::aabbox3d box; + core::array keepIndices; + + if (totalPrimitives > minimalPolysPerNode && !Box.isEmpty()) + for (s32 ch=0; ch<8; ++ch) + { + box.reset(middle); + box.addInternalPoint(edges[ch]); + + // create indices for child + core::array* cindexChunks = new core::array; + + bool added = false; + + for (i=0; ipush_back(ic); + + SIndexChunk& tic = (*cindexChunks)[i]; + + for (u32 t=0; t<(*indices)[i].Indices.size(); t+=3) + { + if (box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t]].Pos) && + box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t+1]].Pos) && + box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t+2]].Pos)) + { + tic.Indices.push_back((*indices)[i].Indices[t]); + tic.Indices.push_back((*indices)[i].Indices[t+1]); + tic.Indices.push_back((*indices)[i].Indices[t+2]); + + added = true; + } + else + { + keepIndices.push_back((*indices)[i].Indices[t]); + keepIndices.push_back((*indices)[i].Indices[t+1]); + keepIndices.push_back((*indices)[i].Indices[t+2]); + } + } + + memcpy( (*indices)[i].Indices.pointer(), keepIndices.pointer(), keepIndices.size()*sizeof(u16)); + (*indices)[i].Indices.set_used(keepIndices.size()); + keepIndices.set_used(0); + } + + if (added) + Children[ch] = new OctTreeNode(nodeCount, Depth, + allmeshdata, cindexChunks, minimalPolysPerNode); + else + delete cindexChunks; + + } // end for all possible children + + IndexData = indices; + } + + + + // destructor + ~OctTreeNode() + { + delete IndexData; + + for (u32 i=0; i<8; ++i) + delete Children[i]; + } + + + + // returns all ids of polygons partially or full enclosed + // by this bounding box. + void getPolys(const core::aabbox3d& box, SIndexData* idxdata, u32 parentTest ) const + { + // if not full inside + if ( parentTest != 2 ) + { + // partially inside ? + parentTest = (u32) Box.intersectsWithBox(box); + if ( 0 == parentTest ) + return; + + // fully inside ? + parentTest+= Box.isFullInside(box); + } + + //if (Box.intersectsWithBox(box)) + { + u32 cnt = IndexData->size(); + u32 i; // new ISO for scoping problem in some compilers + + for (i=0; igetPolys(box, idxdata,parentTest); + } + } + + + + // returns all ids of polygons partially or full enclosed + // by the view frustum. + void getPolys(const scene::SViewFrustum& frustum, SIndexData* idxdata,u32 parentTest) const + { + s32 i; // new ISO for scoping problem in some compilers + + // not fully inside + //if ( parentTest != 2 ) + { + core::vector3df edges[8]; + Box.getEdges(edges); + + for (i=0; isize(); + + for (i=0; igetPolys(frustum, idxdata,parentTest); + } + + + + void renderBoundingBoxes(const core::aabbox3d& box, + core::array< core::aabbox3d >&outBoxes) + { + if (Box.intersectsWithBox(box)) + { + outBoxes.push_back(Box); + + for (u32 i=0; i<8; ++i) + if (Children[i]) + Children[i]->renderBoundingBoxes(box, outBoxes); + } + } + + private: + + core::aabbox3df Box; + core::array* IndexData; + OctTreeNode* Children[8]; + u32 Depth; + }; + + OctTreeNode* Root; + SIndexData* IndexData; + u32 IndexDataCount; +}; + +} // end namespace + +#endif + diff --git a/src/dep/src/irrlicht/S2DVertex.h b/src/dep/src/irrlicht/S2DVertex.h new file mode 100644 index 0000000..9127ff2 --- /dev/null +++ b/src/dep/src/irrlicht/S2DVertex.h @@ -0,0 +1,30 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_K_2D_VERTEX_H_INCLUDED__ +#define __S_K_2D_VERTEX_H_INCLUDED__ + +#include "vector2d.h" + +typedef signed short TZBufferType; + +namespace irr +{ +namespace video +{ + + struct S2DVertex + { + core::vector2d Pos; // position + core::vector2d TCoords; // texture coordinates + TZBufferType ZValue; // zvalue + u16 Color; + }; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/dep/src/irrlicht/S4DVertex.h b/src/dep/src/irrlicht/S4DVertex.h new file mode 100644 index 0000000..f1e2862 --- /dev/null +++ b/src/dep/src/irrlicht/S4DVertex.h @@ -0,0 +1,501 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + + +#ifndef __S_4D_VERTEX_H_INCLUDED__ +#define __S_4D_VERTEX_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "SoftwareDriver2_helper.h" +#include "irrAllocator.h" + +namespace irr +{ + +namespace video +{ + +struct sVec2 +{ + f32 x; + f32 y; + + sVec2 () {} + + sVec2 ( f32 _x, f32 _y ) + : x ( _x ), y ( _y ) {} + + void set ( f32 _x, f32 _y ) + { + x = _x; + y = _y; + } + + // f = a * t + b * ( 1 - t ) + void interpolate(const sVec2& a, const sVec2& b, const f32 t) + { + x = b.x + ( ( a.x - b.x ) * t ); + y = b.y + ( ( a.y - b.y ) * t ); + } + + sVec2 operator-(const sVec2& other) const + { + return sVec2(x - other.x, y - other.y); + } + + sVec2 operator+(const sVec2& other) const + { + return sVec2(x + other.x, y + other.y); + } + + void operator+=(const sVec2& other) + { + x += other.x; + y += other.y; + } + + sVec2 operator*(const f32 s) const + { + return sVec2(x * s , y * s); + } + + void operator*=( const f32 s) + { + x *= s; + y *= s; + } + + void operator=(const sVec2& other) + { + x = other.x; + y = other.y; + } + +}; + +// A8R8G8B8 +struct sVec4; +struct sCompressedVec4 +{ + u32 argb; + + void setA8R8G8B8 ( u32 value ) + { + argb = value; + } + + void setColorf ( const video::SColorf & color ) + { + argb = core::floor32 ( color.a * 255.f ) << 24 | + core::floor32 ( color.r * 255.f ) << 16 | + core::floor32 ( color.g * 255.f ) << 8 | + core::floor32 ( color.b * 255.f ); + } + + void setVec4 ( const sVec4 & v ); + + // f = a * t + b * ( 1 - t ) + void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t) + { + argb = PixelBlend32 ( b.argb, a.argb, core::floor32 ( t * 256.f ) ); + } + + +}; + + +struct sVec4 +{ + f32 x, y, z, w; + + sVec4 () {} + + sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w ) + : x ( _x ), y ( _y ), z( _z ), w ( _w ){} + + void set ( f32 _x, f32 _y, f32 _z, f32 _w ) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + + void setA8R8G8B8 ( u32 argb ) + { + x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f ); + y = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f ); + z = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f ); + w = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f ); + } + + + void setColorf ( const video::SColorf & color ) + { + x = color.a; + y = color.r; + z = color.g; + w = color.b; + } + + void saturate () + { + x = core::clamp ( x, 0.f, 1.f ); + y = core::clamp ( y, 0.f, 1.f ); + z = core::clamp ( z, 0.f, 1.f ); + w = core::clamp ( w, 0.f, 1.f ); + } + + // f = a * t + b * ( 1 - t ) + void interpolate(const sVec4& a, const sVec4& b, const f32 t) + { + x = b.x + ( ( a.x - b.x ) * t ); + y = b.y + ( ( a.y - b.y ) * t ); + z = b.z + ( ( a.z - b.z ) * t ); + w = b.w + ( ( a.w - b.w ) * t ); + } + + + f32 dotProduct(const sVec4& other) const + { + return x*other.x + y*other.y + z*other.z + w*other.w; + } + + f32 dot_xyz( const sVec4& other) const + { + return x*other.x + y*other.y + z*other.z; + } + + f32 get_length_xyz () const + { + return sqrtf ( x * x + y * y + z * z ); + } + + f32 get_inverse_length_xyz () const + { + return core::reciprocal_squareroot ( x * x + y * y + z * z ); + } + + + void normalize_xyz () + { + const f32 l = core::reciprocal_squareroot ( x * x + y * y + z * z ); + + x *= l; + y *= l; + z *= l; + } + + void project_xyz () + { + w = core::reciprocal ( w ); + x *= w; + y *= w; + z *= w; + } + + sVec4 operator-(const sVec4& other) const + { + return sVec4(x - other.x, y - other.y, z - other.z,w - other.w); + } + + sVec4 operator+(const sVec4& other) const + { + return sVec4(x + other.x, y + other.y, z + other.z,w + other.w); + } + + void operator+=(const sVec4& other) + { + x += other.x; + y += other.y; + z += other.z; + w += other.w; + } + + sVec4 operator*(f32 s) const + { + return sVec4(x * s , y * s, z * s,w * s); + } + + sVec4 operator*(const sVec4 &other) const + { + return sVec4(x * other.x , y * other.y, z * other.z,w * other.w); + } + + void operator*=(f32 s) + { + x *= s; + y *= s; + z *= s; + w *= s; + } + + void operator*=(const sVec4 &other) + { + x *= other.x; + y *= other.y; + z *= other.z; + w *= other.w; + } + + void operator=(const sVec4& other) + { + x = other.x; + y = other.y; + z = other.z; + w = other.w; + } +}; + +inline void sCompressedVec4::setVec4 ( const sVec4 & v ) +{ + argb = core::floor32 ( v.x * 255.f ) << 24 | + core::floor32 ( v.y * 255.f ) << 16 | + core::floor32 ( v.z * 255.f ) << 8 | + core::floor32 ( v.w * 255.f ); +} + + +enum e4DVertexFlag +{ + VERTEX4D_INSIDE = 0x0000003F, + VERTEX4D_CLIPMASK = 0x0000003F, + VERTEX4D_PROJECTED = 0x00000100, + + VERTEX4D_FORMAT_MASK = 0xFFFF0000, + VERTEX4D_FORMAT_0 = 0x00010000, + VERTEX4D_FORMAT_1 = VERTEX4D_FORMAT_0 | 0x00020000, + VERTEX4D_FORMAT_2 = VERTEX4D_FORMAT_1 | 0x00040000 +}; + +// dummy Vertex +struct __s4DVertex +{ + sVec4 Pos; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 Color[1]; +#endif + + sVec2 Tex[2]; + u32 flag; +}; + +#define SIZEOF_SVERTEX 64 +#define SIZEOF_SVERTEX_LOG2 6 + +struct s4DVertex +{ + sVec4 Pos; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 Color[1]; +#endif + + sVec2 Tex[2]; + + u32 flag; + + u8 fill [ SIZEOF_SVERTEX - sizeof (__s4DVertex) ]; + + // f = a * t + b * ( 1 - t ) + void interpolate(const s4DVertex& b, const s4DVertex& a, const f32 t) + { + Pos.interpolate ( a.Pos, b.Pos, t ); + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + Color[0].interpolate ( a.Color[0], b.Color[0], t ); +#endif + + Tex[0].interpolate ( a.Tex[0], b.Tex[0], t ); + + if ( (flag & VERTEX4D_FORMAT_1 ) == VERTEX4D_FORMAT_1 ) + { + Tex[1].interpolate ( a.Tex[1], b.Tex[1], t ); + } + + + } +}; + +// ----------------- Vertex Cache --------------------------- + +struct SAlignedVertex +{ + SAlignedVertex ( u32 element, u32 aligned ) + : ElementSize ( element ) + { + u32 byteSize = (ElementSize << SIZEOF_SVERTEX_LOG2 ) + aligned; + mem = new u8 [ byteSize ]; + //data = (s4DVertex*) ((PointerAsValue ( mem ) + (aligned-1) ) & ~ ( aligned - 1 ) ); + data = (s4DVertex*) mem; + } + + virtual ~SAlignedVertex () + { + delete [] mem; + } + + s4DVertex *data; + u8 *mem; + u32 ElementSize; +}; + + +// hold info for different Vertex Types +struct SVSize +{ + u32 Format; + u32 Pitch; + u32 TexSize; +}; + + +// a cache info +struct SCacheInfo +{ + u32 index; + u32 hit; +}; + +#define VERTEXCACHE_ELEMENT 16 +#define VERTEXCACHE_MISS 0xFFFFFFFF +struct SVertexCache +{ + SVertexCache (): mem ( VERTEXCACHE_ELEMENT * 2, 128 ) {} + + SCacheInfo info[VERTEXCACHE_ELEMENT]; + + + // Transformed and lite, clipping state + // + Clipped, Projected + SAlignedVertex mem; + + // source + const void* vertices; + u32 vertexCount; + + const u16* indices; + u32 indexCount; + u32 indicesIndex; + + u32 indicesRun; + + // primitives consist of x vertices + u32 primitivePitch; + + u32 vType; //E_VERTEX_TYPE + u32 pType; //scene::E_PRIMITIVE_TYPE + +}; + + +// swap 2 pointer +inline void swapVertexPointer(const s4DVertex** v1, const s4DVertex** v2) +{ + const s4DVertex* b = *v1; + *v1 = *v2; + *v2 = b; +} + + +// ------------------------ Internal Scanline Rasterizer ----------------------------- + + +// internal scan convert +struct sScanConvertData +{ + s32 left; // major edge left/right + s32 right; // !left + + f32 invDeltaY[3]; // inverse edge delta y + + f32 x[2]; // x coordinate + f32 slopeX[2]; // x slope along edges + +#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) + f32 w[2]; // w coordinate + fp24 slopeW[2]; // w slope along edges +#else + f32 z[2]; // z coordinate + f32 slopeZ[2]; // z slope along edges +#endif + + sVec4 c[2]; // color + sVec4 slopeC[2]; // color slope along edges + + sVec2 t0[2]; // texture + sVec2 slopeT0[2]; // texture slope along edges + + sVec2 t1[2]; // texture + sVec2 slopeT1[2]; // texture slope along edges + +}; + +// passed to scan Line +struct sScanLineData +{ + s32 y; // y position of scanline + f32 x[2]; // x start, x end of scanline + +#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) + f32 w[2]; // w start, w end of scanline +#else + f32 z[2]; // z start, z end of scanline +#endif + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 c[2]; // color start, color end of scanline +#endif + + sVec2 t0[2]; // texture start, texture end of scanline + sVec2 t1[2]; // texture start, texture end of scanline +}; + + +/* + load a color value +*/ +inline void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v + ) +{ + r = f32_to_fixPoint ( v.y ); + g = f32_to_fixPoint ( v.z ); + b = f32_to_fixPoint ( v.w ); +} + +/* + load a color value +*/ +inline void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v + ) +{ + a = f32_to_fixPoint ( v.x ); + r = f32_to_fixPoint ( v.y, COLOR_MAX * FIX_POINT_F32_MUL); + g = f32_to_fixPoint ( v.z, COLOR_MAX * FIX_POINT_F32_MUL); + b = f32_to_fixPoint ( v.w, COLOR_MAX * FIX_POINT_F32_MUL); +} + +/* + load a color value +*/ +inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v + ) +{ + r = f32_to_fixPoint ( v.y, COLOR_MAX * FIX_POINT_F32_MUL); + g = f32_to_fixPoint ( v.z, COLOR_MAX * FIX_POINT_F32_MUL); + b = f32_to_fixPoint ( v.w, COLOR_MAX * FIX_POINT_F32_MUL); +} + + + +} + +} + +#endif + diff --git a/src/dep/src/irrlicht/SoftwareDriver2_compile_config.h b/src/dep/src/irrlicht/SoftwareDriver2_compile_config.h new file mode 100644 index 0000000..87729c0 --- /dev/null +++ b/src/dep/src/irrlicht/SoftwareDriver2_compile_config.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ +#define __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + + +// Generic Render Flags for burning's video rasterizer +// defined now in irrlicht compile config + + +#ifdef 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_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER + #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + #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_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER +#endif + +#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST + #define BURNINGVIDEO_RENDERER_FAST + + //#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_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + //#define SOFTWARE_DRIVER_2_USE_WBUFFER +#endif + +// Derivate flags + +// texture format +#ifdef SOFTWARE_DRIVER_2_32BIT + #define ECF_SOFTWARE2 ECF_A8R8G8B8 +#else + #define ECF_SOFTWARE2 ECF_A1R5G5B5 +#endif + +// mip mapping +#ifdef SOFTWARE_DRIVER_2_MIPMAPPING + #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS -1 + #else + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS -1 + #endif +#else + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0 +#endif + + + +#ifndef REALINLINE + #ifdef _MSC_VER + #define REALINLINE __forceinline + #else + #define REALINLINE inline + #endif +#endif + +#endif diff --git a/src/dep/src/irrlicht/SoftwareDriver2_helper.h b/src/dep/src/irrlicht/SoftwareDriver2_helper.h new file mode 100644 index 0000000..525eaea --- /dev/null +++ b/src/dep/src/irrlicht/SoftwareDriver2_helper.h @@ -0,0 +1,886 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +/* + History: + - changed behaviour for log2 textures ( replaced multiplies by shift ) +*/ + +#ifndef __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__ +#define __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "irrMath.h" +#include "CSoftwareTexture2.h" + + + +namespace irr +{ + +// supporting different packed pixel needs many defines... + +#ifdef SOFTWARE_DRIVER_2_32BIT + typedef u32 tVideoSample; + + #define MASK_A 0xFF000000 + #define MASK_R 0x00FF0000 + #define MASK_G 0x0000FF00 + #define MASK_B 0x000000FF + + #define SHIFT_A 24 + #define SHIFT_R 16 + #define SHIFT_G 8 + #define SHIFT_B 0 + + #define COLOR_MAX 0xFF + #define COLOR_BRIGHT_WHITE 0xFFFFFFFF + + #define VIDEO_SAMPLE_GRANULARITY 2 + +#else + typedef u16 tVideoSample; + + #define MASK_A 0x8000 + #define MASK_R 0x7C00 + #define MASK_G 0x03E0 + #define MASK_B 0x001F + + #define SHIFT_A 15 + #define SHIFT_R 10 + #define SHIFT_G 5 + #define SHIFT_B 0 + + #define COLOR_MAX 0x1F + #define COLOR_BRIGHT_WHITE 0xFFFF + #define VIDEO_SAMPLE_GRANULARITY 1 + +#endif + + + + +// ----------------------- Generic ---------------------------------- + +//! a more useful memset for pixel +inline void memset32 ( void * dest, const u32 value, u32 bytesize ) +{ + u32 * d = (u32*) dest; + + u32 i; + + i = bytesize >> ( 2 + 3 ); + while( i ) + { + d[0] = value; + d[1] = value; + d[2] = value; + d[3] = value; + + d[4] = value; + d[5] = value; + d[6] = value; + d[7] = value; + + d += 8; + i -= 1; + } + + i = (bytesize >> 2 ) & 7; + while( i ) + { + d[0] = value; + d += 1; + i -= 1; + } + +} + +/* + use biased loop counter + --> 0 byte copy is forbidden +*/ +REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize ) +{ + u32 c = bytesize >> 2; + + do + { + ((u32*) dest ) [ c + -1 ] = ((u32*) source) [ c + -1 ]; + } while ( --c ); + +} + + + +// integer log2 of a float ieee 754. TODO: non ieee floating point +static inline s32 s32_log2_f32( f32 f) +{ + u32 x = IR ( f ); + + return ((x & 0x7F800000) >> 23) - 127; +} + +static inline s32 s32_log2_s32(u32 x) +{ + return s32_log2_f32( (f32) x); +} + +static inline s32 s32_abs(s32 x) +{ + s32 b = x >> 31; + return (x ^ b ) - b; +} + + +// TODO: don't stick on 32 Bit Pointer +#define PointerAsValue(x) ( (u32) (u32*) (x) ) + + +//! conditional set based on mask and arithmetic shift +REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b ) +{ + return ( mask & ( a ^ b ) ) ^ b; +} + +inline void setbits ( u32 &state, s32 condition, u32 mask ) +{ + state ^= ( ( -condition >> 31 ) ^ state ) & mask; +} + + +// ------------------ Video--------------------------------------- +/*! + Pixel = dest * ( 1 - alpha ) + source * alpha + alpha [0;256] +*/ +REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha ) +{ + u32 srcRB = c1 & 0x00FF00FF; + u32 srcXG = c1 & 0x0000FF00; + + u32 dstRB = c2 & 0x00FF00FF; + u32 dstXG = c2 & 0x0000FF00; + + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 8; + xg >>= 8; + + rb += dstRB; + xg += dstXG; + + rb &= 0x00FF00FF; + xg &= 0x0000FF00; + + return rb | xg; +} + +/*! + Pixel = dest * ( 1 - alpha ) + source * alpha + alpha [0;32] +*/ +inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u32 alpha ) +{ + u32 srcRB = c1 & 0x7C1F; + u32 srcXG = c1 & 0x03E0; + + u32 dstRB = c2 & 0x7C1F; + u32 dstXG = c2 & 0x03E0; + + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 5; + xg >>= 5; + + rb += dstRB; + xg += dstXG; + + rb &= 0x7C1F; + xg &= 0x03E0; + + return rb | xg; +} + +/*! + Scale Color by (1/value) + value 0 - 256 ( alpha ) +*/ +inline u32 PixelLerp32 ( const u32 source, const u32 value ) +{ + u32 srcRB = source & 0x00FF00FF; + u32 srcXG = (source & 0xFF00FF00) >> 8; + + srcRB *= value; + srcXG *= value; + + srcRB >>= 8; + //srcXG >>= 8; + + srcXG &= 0xFF00FF00; + srcRB &= 0x00FF00FF; + + return srcRB | srcXG; +} + +/* + return alpha in [0;256] Granularity + add highbit alpha ( alpha > 127 ? + 1 ) +*/ +inline u32 extractAlpha ( const u32 c ) +{ + return ( c >> 24 ) + ( c >> 31 ); +} + +/* + Pixel = c0 * (c1/31). c0 Alpha retain +*/ +inline u16 PixelMul16 ( const u16 c0, const u16 c1) +{ + return ((( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 ) | + (( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 ) | + (( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 ) | + (c0 & 0x8000)); +} + +/* + Pixel = c0 * (c1/31). +*/ +inline u16 PixelMul16_2 ( u16 c0, u16 c1) +{ + return ( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 | + ( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 | + ( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 | + ( c0 & c1 & 0x8000); +} + +/* + Pixel = c0 * (c1/255). c0 Alpha Retain +*/ +REALINLINE u32 PixelMul32 ( const u32 c0, const u32 c1) +{ + return (c0 & 0xFF000000) | + (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | + (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | + (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); +} + +/* + Pixel = c0 * (c1/255). +*/ +REALINLINE u32 PixelMul32_2 ( const u32 c0, const u32 c1) +{ + return (( ( (c0 & 0xFF000000) >> 16 ) * ( (c1 & 0xFF000000) >> 16 ) ) & 0xFF000000 ) | + (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | + (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | + (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); +} + +/* + Pixel = clamp ( c0 + c1, 0, 255 ) +*/ +REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1) +{ + u32 sum = ( c2 & 0x00FFFFFF ) + ( c1 & 0x00FFFFFF ); + u32 low_bits = ( c2 ^ c1 ) & 0x00010101; + s32 carries = ( sum - low_bits ) & 0x01010100; + u32 modulo = sum - carries; + u32 clamp = carries - ( carries >> 8 ); + return modulo | clamp; +} + + + +// 1 - Bit Alpha Blending +inline u16 PixelBlend16 ( const u16 c2, const u16 c1 ) +{ + u16 c = c1 & 0x8000; + + c >>= 15; + c += 0x7fff; + + c &= c2; + c |= c1; + + return c; +} + +// 1 - Bit Alpha Blending 16Bit SIMD +inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 ) +{ + u32 c = c1 & 0x80008000; + + c >>= 15; + c += 0x7fff7fff; + + c &= c2; + c |= c1; + + return c; +} + + +/*! + Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha +*/ +inline u32 PixelBlend32 ( const u32 c2, const u32 c1 ) +{ + // alpha test + u32 alpha = c1 & 0xFF000000; + + if ( 0 == alpha ) + return c2; + + if ( 0xFF000000 == alpha ) + { + return c1; + } + + alpha >>= 24; + + // add highbit alpha, if ( alpha > 127 ) alpha += 1; + alpha += ( alpha >> 7); + + u32 srcRB = c1 & 0x00FF00FF; + u32 srcXG = c1 & 0x0000FF00; + + u32 dstRB = c2 & 0x00FF00FF; + u32 dstXG = c2 & 0x0000FF00; + + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 8; + xg >>= 8; + + rb += dstRB; + xg += dstXG; + + rb &= 0x00FF00FF; + xg &= 0x0000FF00; + + return rb | xg; +} + + + +// ------------------ Fix Point ---------------------------------- + +typedef s32 tFixPoint; +typedef u32 tFixPointu; + +// Fix Point 9 +#if 1 + #define FIX_POINT_PRE 9 + #define FIX_POINT_FRACT_MASK 0x1FF + #define FIX_POINT_SIGNED_MASK 0xFFFFFE00 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 + #define FIX_POINT_ONE 0x200 + #define FIX_POINT_ZERO_DOT_FIVE 0x100 + #define FIX_POINT_F32_MUL 512.f +#endif + +// Fix Point 7 +#if 0 + #define FIX_POINT_PRE 7 + #define FIX_POINT_FRACT_MASK 0x7F + #define FIX_POINT_SIGNED_MASK 0xFFFFFF80 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80 + #define FIX_POINT_ONE 0x80 + #define FIX_POINT_ZERO_DOT_FIVE 0x40 + #define FIX_POINT_F32_MUL 128.f +#endif + +#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE ) + + +/* + convert signed integer to fixpoint +*/ +inline tFixPoint s32_to_fixPoint (const s32 x) +{ + return x << FIX_POINT_PRE; +} + +inline tFixPointu u32_to_fixPoint (const u32 x) +{ + return x << FIX_POINT_PRE; +} + +inline u32 fixPointu_to_u32 (const tFixPointu x) +{ + return x >> FIX_POINT_PRE; +} + + +// 1/x * FIX_POINT +REALINLINE f32 fix_inverse32 ( const f32 x ) +{ + return FIX_POINT_F32_MUL / x; +} + + +/* + convert float to fixpoint + fast convert (fistp on x86) HAS to be used.. + hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different + others should use their favourite assembler.. +*/ +static inline int f_round2(f32 f) +{ + f += (3<<22); + return *((int*)&f) - 0x4b400000; +} + +/* + convert f32 to Fix Point. + multiply is needed anyway, so scale mulby +*/ +REALINLINE tFixPoint f32_to_fixPoint (const f32 x, const f32 mulby = FIX_POINT_F32_MUL ) +{ + return (tFixPoint) (x * mulby); +} + + +/* + Fix Point , Fix Point Multiply +*/ +REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y) +{ + return (x * y) >> (tFixPointu) FIX_POINT_PRE; +} + +/* + Fix Point , Fix Point Multiply +*/ +REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y) +{ + return ( x * y) >> ( FIX_POINT_PRE ); +} + +/* + Multiply x * y * 1 +*/ +REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) +{ + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 1 ); +} + +/* + Multiply x * y * 2 +*/ +REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y) +{ + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 ); +} + +/* + Multiply x * y * 4 +*/ +REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y) +{ +#ifdef SOFTWARE_DRIVER_2_32BIT + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 ); +#else + return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) ); +#endif +} + +/*! + clamp FixPoint to maxcolor in FixPoint, min(a,31) +*/ +REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a) +{ + tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31; + return (a & c) | ( FIXPOINT_COLOR_MAX & ~c); +} + +/*! + clamp FixPoint to 0 in FixPoint, max(a,0) +*/ +inline tFixPoint clampfix_mincolor ( const tFixPoint a) +{ + return a - ( a & ( a >> 31 ) ); +} + + +// rount fixpoint to int +inline s32 roundFix ( const tFixPoint x ) +{ + return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE; +} + + + +// x in [0;1[ +inline s32 f32_to_23Bits(const f32 x) +{ + f32 y = x + 1.f; + return ((u32&)y) & 0x7FFFFF; // last 23 bits +} + +/*! + return VideoSample from fixpoint +*/ +REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b ) +{ +#ifdef __BIG_ENDIAN__ + return ( r & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - 8) | + ( g & FIXPOINT_COLOR_MAX) << ( 16 - FIX_POINT_PRE ) | + //( g & FIXPOINT_COLOR_MAX) << ( SHIFT_G - FIX_POINT_PRE ) | + ( b & FIXPOINT_COLOR_MAX) << ( 24 - FIX_POINT_PRE ); +#else + return ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) | + ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) | + //( g & FIXPOINT_COLOR_MAX) << ( SHIFT_G - FIX_POINT_PRE ) | + ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B ); +#endif +} + + +/*! + return fixpoint from VideoSample +*/ +inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +{ + r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE ); + //g = (t00 & MASK_G) >> ( SHIFT_G - FIX_POINT_PRE ); + g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); +} + + +// ----- FP24 ---- floating point z-buffer + +#if 1 +typedef f32 fp24; +#else +struct fp24 +{ + u32 v; + + fp24() {} + + fp24 ( const f32 f ) + { + f32 y = f + 1.f; + v = ((u32&)y) & 0x7FFFFF; // last 23 bits + } + + void operator=(const f32 f ) + { + f32 y = f + 1.f; + v = ((u32&)y) & 0x7FFFFF; // last 23 bits + } + + void operator+=(const fp24 &other ) + { + v += other.v; + } + + operator f32 () const + { + f32 r = FR ( v ); + return r + 1.f; + } + +}; +#endif + + +// ------------------------ Internal Texture ----------------------------- + +struct sInternalTexture +{ + u32 textureXMask; + u32 textureYMask; + + u32 pitchlog2; + void *data; + + video::CSoftwareTexture2 *Texture; + s32 lodLevel; +}; + + + +// get video sample plain +inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + return *((tVideoSample*)( (u8*) t->data + ofs )); +} + +// get video sample to fix +inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + +} + + +inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty, + const u32 x, const u32 y + ) +{ + static const tFixPointu dithermask[] = + { + 0x00,0x80,0x20,0xa0, + 0xc0,0x40,0xe0,0x60, + 0x30,0xb0,0x10,0x90, + 0xf0,0x70,0xd0,0x50 + }; + + const u32 index = (y & 3 ) << 2 | (x & 3); + + const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask; + const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask; + + u32 ofs; + ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + +} + +/* + load a sample from internal texture at position tx,ty to fixpoint +*/ +#ifndef SOFTWARE_DRIVER_2_BILINEAR + +// get Sample linear == getSample_fixpoint + +inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + +} + + +#else + +// get sample linear +REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + r = (t00 & MASK_R) >> SHIFT_R; + g = (t00 & MASK_G) >> SHIFT_G; + b = (t00 & MASK_B); +} + +// get Sample bilinear +REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + + tFixPointu r00,g00,b00; + tFixPointu r01,g01,b01; + tFixPointu r10,g10,b10; + tFixPointu r11,g11,b11; + + getSample_linear ( r00, g00, b00, t, tx,ty ); + getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty ); + getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE ); + getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE ); + + const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK; + const tFixPointu txFractInv = FIX_POINT_ONE - txFract; + + const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK; + const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract; + + const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv ); + const tFixPointu w10 = imulFixu ( txFract , tyFractInv ); + const tFixPointu w01 = imulFixu ( txFractInv, tyFract ); + const tFixPointu w11 = imulFixu ( txFract , tyFract ); + + r = (r00 * w00 ) + + (r01 * w01 ) + + (r10 * w10 ) + + (r11 * w11 ); + + g = (g00 * w00 ) + + (g01 * w01 ) + + (g10 * w10 ) + + (g11 * w11 ); + + b = (b00 * w00 ) + + (b01 * w01 ) + + (b10 * w10 ) + + (b11 * w11 ); + +} + + +// get sample linear +REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + a = (t00 & MASK_A) >> SHIFT_A; + r = (t00 & MASK_R) >> SHIFT_R; + g = (t00 & MASK_G) >> SHIFT_G; + b = (t00 & MASK_B); +} + +// get Sample bilinear +REALINLINE void getSample_texture ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + + tFixPointu a00, r00,g00,b00; + tFixPointu a01, r01,g01,b01; + tFixPointu a10, r10,g10,b10; + tFixPointu a11, r11,g11,b11; + + getSample_linear ( a00, r00, g00, b00, t, tx,ty ); + getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty ); + getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE ); + getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE ); + + const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK; + const tFixPointu txFractInv = FIX_POINT_ONE - txFract; + + const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK; + const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract; + + const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv ); + const tFixPointu w10 = imulFixu ( txFract , tyFractInv ); + const tFixPointu w01 = imulFixu ( txFractInv, tyFract ); + const tFixPointu w11 = imulFixu ( txFract , tyFract ); + + a = (a00 * w00 ) + + (a01 * w01 ) + + (a10 * w10 ) + + (a11 * w11 ); + + r = (r00 * w00 ) + + (r01 * w01 ) + + (r10 * w10 ) + + (r11 * w11 ); + + g = (g00 * w00 ) + + (g01 * w01 ) + + (g10 * w10 ) + + (g11 * w11 ); + + b = (b00 * w00 ) + + (b01 * w01 ) + + (b10 * w10 ) + + (b11 * w11 ); + +} + + +#endif + +// some 2D Defines +struct AbsRectangle +{ + s32 x0; + s32 y0; + s32 x1; + s32 y1; +}; + +inline void intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRectangle& b) +{ + dest.x0 = core::s32_max( a.x0, b.x0 ); + dest.y0 = core::s32_max( a.y0, b.y0 ); + dest.x1 = core::s32_min( a.x1, b.x1 ); + dest.y1 = core::s32_min( a.y1, b.y1 ); +} + +inline bool isValid (const AbsRectangle& a) +{ + return a.x0 < a.x1 && a.y0 < a.y1; +} + +// some 1D defines +struct sIntervall +{ + s32 start; + s32 end; +}; + +// returning intersection width +inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b) +{ + return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start ); +} + + +} // namespace + +#endif + diff --git a/src/dep/src/irrlicht/builtInFont.bmp b/src/dep/src/irrlicht/builtInFont.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7001c12311a1662abac377e3f61e58e490806bba GIT binary patch literal 8266 zcmeI0O^zHl3`Qr0v&zn^EZsG|$Tou^ zM^X}7Q+ECF`{$?7@ASX${x#npo<1^zK0iJE`BT3?!umFSd3yTtGw&DLm#5`_`j79x zr{%;7e3wrTE``GQU~xPMUp|iUf%o;_z!yQ^5&t}vQSZPniT}#}jd$$d>+ACQ=>scy zj6S}8cnmmEk7vHTEYAyFzYiv1*;>Dj{lZNq)y-U18z+;EY>c6FS++^DU+vF}&vLGF zX;ZRvb-))ojBXK@R1EQWAo1(G&CzKSqn4yMU@#*SY!U$cpaBAA4zNHm${Z$|N(_CN zuQ3rwKwzfXzz;9(km4f-MUJvSb+W=qAZqb5zOj=-;)f$CM{@De34Z6&I;aV$3&kZE zY@pRp0WC#vgKKirU{CHp2JXQXkQ8CvGbQ|B!U ztH^3R@%9r2{?Jmc$Yv?e8PZg;!#%`aElaUEEc}s`XY+7D%bQchp%14}*Fe4^tc58XcVo|E1MK2eBm`~wmH zJ1D4a{lw0C&yg4(J$|Y;YxS4}T}03>XP%!1q$osk3*rL1T{?0N-3%Mw_wO@x>eJI|K z&SL9wO|~$*T8jrmk+{V&J<#hAwl1n~sKPB#S6l3`f<599(b_hE?jqAEfQA?Z=?y$7 zjEfcYdUU(u$)vbpkN5&fI#_*!u;~5ckH8V%94>A8A#A$o4UXBtJ%$RWOfFQNr#}u? z(u9`way~z^4}IUh6a@@(URqXNy2rw`#@9lQr>l}(PR9#)cR!=q)wbMiGSl}EEBijW zvE}|X9vn)&wWab<;@W#&>#=c-Q2Chd1~<0IVAmQ?FaB*H$Ew9TJPtc#djZlw2R8(qQWj|?U@PlFFi^)_6 zJlW)fTvJS%VAdIWsN=h8nHV#VS%K{c8)%xNF}}kJoOtBhmPD<|kw#39vYQ+=O2PJp zYR%Ht+f@Zjqz=qcwRR2`@~qOX)$i=B;{JR%-OTFS!uq!QAGO)|X;q%bUCrI6{IbD% zx(l51BpxUTCy(Ms>A>#(_!bZGs~(LH+L|@~Bl(-TPz%4pyr;87?`^Y?`)W--Bu!yUFbmU?+}JVa5PBWmudB%!A4O5!5V@JqQS&u?_$Qbcs6C@3w-p7(bMZO_)J?i@zK)7SXU;|$nHBra*G$bU~skQu76IQ5{mxo zJ%3~5uYTxJx83jakB_xWD40vCOMw~aFFEu=S`@*R^|c^)Q@U2&Cz{}ta(rn7|YJWQbRMTDj~VIY6^!Ti~l{NA+=K4aE4kd2vv*f%`P zeT3&db)nABf&;VrR_OnnSj#$P+YFxO|0A5bcCA*XyCLPP%rD@!LbNy9r*rrGupBq@ zP6A&*c)Ky=3d2=yGI!n?XUIu#1ZbT$XFN`P9t{SdRiR%8@nH~GQ4&U+c;qT2rxfyZ zCLY5K%(z8^aDvd{#* tileNum;//! +{ +public: + + /**Basic Constructor*/ + StringList() + { + } + + /**Constructor based on file loading. + Look at LoadFromFile specifications.*/ + StringList(io::IReadFile* file) + { + LoadFromFile(file); + } + + /**Basic destructor.*/ + ~StringList() + { + clear(); + } + + //Adds a String to StringList + /** Add a string to this StringList.*/ + void Add(String str/*getSize(); + char* buf = new char[sz+1]; + file->read(buf, sz); + buf[sz] = 0; + char* p = buf; + char* start = p; + + while(*p) + { + if (*p == '\n') + { + core::stringc str(start, p - start - 1); + str.trim(); + Add(str); + start = p+1; + } + + ++p; + } + + if (p - start > 1) + { + core::stringc str(start, p - start - 1); + str.trim(); + Add(str); + } + + delete [] buf; + } +}; + + //This function subdivides a string in a list of strings +/** This function subdivides strings divided by divider in a list of strings. +\return A StringList made of all strings divided by divider.*/ +StringList SubdivideString(String str, String divider) +{ + StringList strings; //returned StringList + strings.clear(); //clear returned stringlist + + int c=0; + int l=str.size(); + + //process entire string + while(c= 0.91 + temp=SubdivideString(RawFile[0],String(";"));//file info + + if ( temp[0] != String("DeleD Map File") ) + return false;//not a deled file + + temp.clear(); + temp=SubdivideString(RawFile[1],String(" "));//get version + temp1=SubdivideString(temp[1],String(";")); + + if (atof(temp1[0].c_str()) < 0.91) + return false;//not correct version + + //end checking + temp.clear(); + temp1.clear(); + + for(int i=0;i=9) + { + temp1=SubdivideString(temp[temp.size() - 1],","); + materials[i].lightmapFlag=atoi(temp1[0].c_str()); + if(!use_material_dirs) + { + temp2=SubdivideString(temp1[1],"\\"); + sprintf(materials[i].lightmapName,"%s",temp2[temp2.size() - 1].c_str()); + } + else + sprintf(materials[i].lightmapName,"%s",temp1[1].c_str()); + } + else + { + materials[i].lightmapFlag=1; + materials[i].lightmapName[0]=0; + } + temp1.clear(); + temp2.clear(); + } + return true; +} + + +/**This function extract an array of dmfMaterial from a DMF file considering 1st an 2nd layer for water plains. +You must give in input a StringList representing a DMF file loaded with LoadFromFile. +\return true if function succeed or false on fail.*/ +bool GetDMFWaterMaterials(StringList RawFile /**= 0.91 + temp=SubdivideString(RawFile[0],String(";"));//file info + + if ( temp[0] != String("DeleD Map File") ) + return false;//not a deled file + + temp.clear(); + temp=SubdivideString(RawFile[1],String(" "));//get version + temp1=SubdivideString(temp[1],String(";")); + + if (atof(temp1[0].c_str()) < 0.91) + return false;//not correct version + + //end checking + temp.clear(); + temp1.clear(); + + for(int i=0;i= 0.91 + temp=SubdivideString(RawFile[0],String(";"));//file info + + if ( temp[0] != String("DeleD Map File") ) + return false;//not a deled file + + temp.clear(); + temp=SubdivideString(RawFile[1],String(" "));//get version + temp1=SubdivideString(temp[1],String(";")); + + if (atof(temp1[0].c_str()) < 0.91) + return false;//not correct version + //end checking + + temp.clear(); + temp1.clear(); + offs=offs + atoi(RawFile[offs].c_str()); + offs++; + + s32 objs = atoi(RawFile[offs].c_str()); + s32 fac=0, vert=0, tmp_sz=0, vert_cnt=0, face_cnt=0; + offs++; + + for (int i=0; i= 0.91 + temp=SubdivideString(RawFile[0],String(";"));//file info + + if ( temp[0] != String("DeleD Map File") ) + return false;//not a deled file + + temp.clear(); + temp=SubdivideString(RawFile[1],String(" "));//get version + temp1=SubdivideString(temp[1],String(";")); + + if (atof(temp1[0].c_str()) < 0.91) + return false;//not correct version + + //end checking + + temp.clear(); + temp1.clear(); + offs=offs + atoi(RawFile[offs].c_str()); + offs++; + s32 objs = atoi(RawFile[offs].c_str()); + s32 lit=0; + s32 d_lit=0; + offs++; + + //let's get position of lights in file + int i; + for(i=0;i= 0.91 + temp=SubdivideString(RawFile[0],String(";"));//file info + + if ( temp[0] != String("DeleD Map File") ) + return false;//not a deled file + + temp.clear(); + temp=SubdivideString(RawFile[1],String(" "));//get version + temp1=SubdivideString(temp[1],String(";")); + + if (atof(temp1[0].c_str()) < 0.91) + return false;//not correct version + + //end checking + + temp.clear(); + temp1.clear(); + offs=offs+atoi(RawFile[offs].c_str()); + offs++; + s32 objs=atoi(RawFile[offs].c_str()); + s32 fac=0,vert=0,tmp_sz=0,vert_cnt=0,face_cnt=0,wat_id=0; + core::dimension2d tilenum(40,40); + f32 waveheight=3.0f; + f32 wavespeed=300.0f; + f32 wavelength=80.0f; + offs++; + + for(int i=0;i +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glext.h last updated 2007/02/12 */ +/* Current version at http://www.opengl.org/registry/ */ +#define GL_GLEXT_VERSION 39 + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#endif + +#ifndef GL_VERSION_2_0 +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + +#ifndef GL_VERSION_2_1 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_env_add +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_window_pos +#endif + +#ifndef GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + +#ifndef GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#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_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_compression_vtc +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_NV_vertex_program1_1 +#endif + +#ifndef GL_EXT_shadow_funcs +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_NV_vertex_program2 +#endif + +#ifndef GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + +#ifndef GL_NV_fragment_program_option +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + +#ifndef GL_NV_vertex_program2_option +/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ +/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ +#endif + +#ifndef GL_NV_vertex_program3 +/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#endif + +#ifndef GL_GREMEDY_string_marker +#endif + +#ifndef GL_EXT_packed_depth_stencil +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif + +#ifndef GL_EXT_timer_query +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_gpu_program_parameters +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ +/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ +/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ +/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +/* reuse GL_LINES_ADJACENCY_EXT */ +/* reuse GL_LINE_STRIP_ADJACENCY_EXT */ +/* reuse GL_TRIANGLES_ADJACENCY_EXT */ +/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +/* reuse GL_PROGRAM_POINT_SIZE_EXT */ +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#endif + +#ifndef GL_EXT_draw_instanced +#endif + +#ifndef GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_NV_fragment_program4 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_NV_geometry_shader4 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#endif + +#ifndef GL_EXT_draw_buffers2 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#endif + +#ifndef GL_EXT_texture_integer +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#endif + + +/*************************************************************/ + +#include +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; /* native character */ +#endif + +#ifndef GL_VERSION_1_5 +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for handling shader object handles and program/shader text */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ +#endif + +/* GL types for "half" precision (s10e5) float data in host memory */ +#ifndef GL_ARB_half_float_pixel +typedef unsigned short GLhalfARB; +#endif + +#ifndef GL_NV_half_float +typedef unsigned short GLhalfNV; +#endif + +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) +#include +#if defined(__STDC__) +#if defined(__arch64__) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include /* Fallback option */ +#endif +#endif + +#ifndef GL_EXT_timer_query +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +GLAPI void APIENTRY glBlendEquation (GLenum); +GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogram (GLenum); +GLAPI void APIENTRY glResetMinmax (GLenum); +GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum); +GLAPI void APIENTRY glClientActiveTexture (GLenum); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); +GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glFogCoordf (GLfloat); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *); +GLAPI void APIENTRY glFogCoordd (GLdouble); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); +GLAPI void APIENTRY glPointParameteri (GLenum, GLint); +GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); +GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos2i (GLint, GLint); +GLAPI void APIENTRY glWindowPos2iv (const GLint *); +GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *); +GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); +GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); +GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3iv (const GLint *); +GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsQuery (GLuint); +GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); +GLAPI void APIENTRY glEndQuery (GLenum); +GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); +GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); +GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint); +GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); +GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); +GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); +GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum); +GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *); +GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint); +GLAPI void APIENTRY glAttachShader (GLuint, GLuint); +GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); +GLAPI void APIENTRY glCompileShader (GLuint); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum); +GLAPI void APIENTRY glDeleteProgram (GLuint); +GLAPI void APIENTRY glDeleteShader (GLuint); +GLAPI void APIENTRY glDetachShader (GLuint, GLuint); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint); +GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); +GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); +GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); +GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgram (GLuint); +GLAPI GLboolean APIENTRY glIsShader (GLuint); +GLAPI void APIENTRY glLinkProgram (GLuint); +GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); +GLAPI void APIENTRY glUseProgram (GLuint); +GLAPI void APIENTRY glUniform1f (GLint, GLfloat); +GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform1i (GLint, GLint); +GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint); +GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glValidateProgram (GLuint); +GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); +GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); +GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); +GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); +GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); +GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexBlendARB (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); +GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); +GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); +GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); +GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); +GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); +GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); +GLAPI void APIENTRY glEndQueryARB (GLenum); +GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); +GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); +GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); +GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); +GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); +GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); +GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); +GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); +GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); +GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); +GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); +GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); +GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glUniform1iARB (GLint, GLint); +GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); +GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); +GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); +GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); +GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); +GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); +GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); +GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); +GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); +GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClampColorARB (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +#endif + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +GLAPI void APIENTRY glResetHistogramEXT (GLenum); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint); +GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +GLAPI void APIENTRY glDeformSGIX (GLbitfield); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum); +GLAPI void APIENTRY glTextureLightEXT (GLenum); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); +GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); +GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); +GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *); +GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); +GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); +GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); +GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); +GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +GLAPI void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); +GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFinishFenceNV (GLuint); +GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); +GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); +GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); +GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); +GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); +GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); +GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); +GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); +GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); +GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); +GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); +GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); +GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); +GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); +GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); +GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); +GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); +GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); +GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); +GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); +GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#endif + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, GLuint *); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +/* This is really a WGL extension, but defines some associated GL enums. + * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. + */ +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#endif + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#endif + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#endif + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint); +GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); +GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); +GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); +GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint); +GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint); +GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); +GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); +GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); +GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); +GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGenerateMipmapEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#endif + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); +#endif + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *); +GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); +#endif + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *); +GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *); +GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); +GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *); +GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *); +GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); +GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *); +GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint); +GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint); +GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *); +GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *); +GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *); +GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint); +GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint); +GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble); +GLAPI void APIENTRY glClearDepthdNV (GLdouble); +GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#endif + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#endif + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *); +GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint); +GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint); +GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum); +GLAPI void APIENTRY glEndTransformFeedbackNV (void); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum); +GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr); +GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint); +GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum); +GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *); +GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *); +GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint); +GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint); +GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *); +GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *); +GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dep/src/irrlicht/glxext.h b/src/dep/src/irrlicht/glxext.h new file mode 100644 index 0000000..2f757e9 --- /dev/null +++ b/src/dep/src/irrlicht/glxext.h @@ -0,0 +1,785 @@ +#ifndef __glxext_h_ +#define __glxext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glxext.h last updated 2007/04/21 */ +/* Current version at http://www.opengl.org/registry/ */ +#define GLX_GLXEXT_VERSION 19 + +#ifndef GLX_VERSION_1_3 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#endif + +#ifndef GLX_VERSION_1_4 +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#endif + +#ifndef GLX_ARB_get_proc_address +#endif + +#ifndef GLX_ARB_multisample +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif + +#ifndef GLX_SGIS_multisample +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +#ifndef GLX_SGI_swap_control +#endif + +#ifndef GLX_SGI_video_sync +#endif + +#ifndef GLX_SGI_make_current_read +#endif + +#ifndef GLX_SGIX_video_source +#endif + +#ifndef GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* reuse GLX_NONE_EXT */ +#endif + +#ifndef GLX_EXT_import_context +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +/* reuse GLX_SCREEN_EXT */ +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#endif + +#ifndef GLX_SGI_cushion +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#endif + +#ifndef GLX_SGIX_dmbuffer +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +#endif + +#ifndef GLX_SGIX_swap_group +#endif + +#ifndef GLX_SGIX_swap_barrier +#endif + +#ifndef GLX_SGIS_blended_overlay +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +#ifndef GLX_SGIS_shared_multisample +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +#ifndef GLX_SUN_get_transparent_index +#endif + +#ifndef GLX_3DFX_multisample +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#endif + +#ifndef GLX_MESA_pixmap_colormap +#endif + +#ifndef GLX_MESA_release_buffers +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#endif + +#ifndef GLX_SGIX_visual_select_group +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif + +#ifndef GLX_OML_swap_method +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif + +#ifndef GLX_OML_sync_control +#endif + +#ifndef GLX_NV_float_buffer +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +#endif + +#ifndef GLX_MESA_agp_offset +#endif + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#endif + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 +#endif + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT +#define GLX_BACK_EXT GLX_BACK_LEFT_EXT +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB +#endif + + +/*************************************************************/ + +#ifndef GLX_ARB_get_proc_address +typedef void (*__GLXextFuncPtr)(void); +#endif + +#ifndef GLX_SGIX_video_source +typedef XID GLXVideoSourceSGIX; +#endif + +#ifndef GLX_SGIX_fbconfig +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#endif + +#ifndef GLX_SGIX_pbuffer +typedef XID GLXPbufferSGIX; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +#endif + +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include /* Fallback option */ +#endif +#endif + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXFBConfig * glXGetFBConfigs (Display *, int, int *); +extern GLXFBConfig * glXChooseFBConfig (Display *, int, const int *, int *); +extern int glXGetFBConfigAttrib (Display *, GLXFBConfig, int, int *); +extern XVisualInfo * glXGetVisualFromFBConfig (Display *, GLXFBConfig); +extern GLXWindow glXCreateWindow (Display *, GLXFBConfig, Window, const int *); +extern void glXDestroyWindow (Display *, GLXWindow); +extern GLXPixmap glXCreatePixmap (Display *, GLXFBConfig, Pixmap, const int *); +extern void glXDestroyPixmap (Display *, GLXPixmap); +extern GLXPbuffer glXCreatePbuffer (Display *, GLXFBConfig, const int *); +extern void glXDestroyPbuffer (Display *, GLXPbuffer); +extern void glXQueryDrawable (Display *, GLXDrawable, int, unsigned int *); +extern GLXContext glXCreateNewContext (Display *, GLXFBConfig, int, GLXContext, Bool); +extern Bool glXMakeContextCurrent (Display *, GLXDrawable, GLXDrawable, GLXContext); +extern GLXDrawable glXGetCurrentReadDrawable (void); +extern Display * glXGetCurrentDisplay (void); +extern int glXQueryContext (Display *, GLXContext, int, int *); +extern void glXSelectEvent (Display *, GLXDrawable, unsigned long); +extern void glXGetSelectedEvent (Display *, GLXDrawable, unsigned long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXFBConfig * ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef Display * ( * PFNGLXGETCURRENTDISPLAYPROC) (void); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +#endif + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern __GLXextFuncPtr glXGetProcAddress (const GLubyte *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName); +#endif + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); +#endif + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 +#endif + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 +#endif + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXSwapIntervalSGI (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); +#endif + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetVideoSyncSGI (unsigned int *); +extern int glXWaitVideoSyncSGI (int, int, unsigned int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); +#endif + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXMakeCurrentReadSGI (Display *, GLXDrawable, GLXDrawable, GLXContext); +extern GLXDrawable glXGetCurrentReadDrawableSGI (void); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +#endif + +#ifndef GLX_SGIX_video_source +#define GLX_SGIX_video_source 1 +#ifdef _VL_H +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *, int, VLServer, VLPath, int, VLNode); +extern void glXDestroyGLXVideoSourceSGIX (Display *, GLXVideoSourceSGIX); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); +typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); +#endif /* _VL_H */ +#endif + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 +#endif + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Display * glXGetCurrentDisplayEXT (void); +extern int glXQueryContextInfoEXT (Display *, GLXContext, int, int *); +extern GLXContextID glXGetContextIDEXT (const GLXContext); +extern GLXContext glXImportContextEXT (Display *, GLXContextID); +extern void glXFreeContextEXT (Display *, GLXContext); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetFBConfigAttribSGIX (Display *, GLXFBConfigSGIX, int, int *); +extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *, int, int *, int *); +extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *, GLXFBConfigSGIX, Pixmap); +extern GLXContext glXCreateContextWithConfigSGIX (Display *, GLXFBConfigSGIX, int, GLXContext, Bool); +extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *, GLXFBConfigSGIX); +extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *, XVisualInfo *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); +typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); +extern void glXDestroyGLXPbufferSGIX (Display *, GLXPbufferSGIX); +extern int glXQueryGLXPbufferSGIX (Display *, GLXPbufferSGIX, int, unsigned int *); +extern void glXSelectEventSGIX (Display *, GLXDrawable, unsigned long); +extern void glXGetSelectedEventSGIX (Display *, GLXDrawable, unsigned long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); +typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCushionSGI (Display *, Window, float); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXBindChannelToWindowSGIX (Display *, int, int, Window); +extern int glXChannelRectSGIX (Display *, int, int, int, int, int, int); +extern int glXQueryChannelRectSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXQueryChannelDeltasSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXChannelRectSyncSGIX (Display *, int, int, GLenum); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); +#endif + +#ifndef GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer 1 +#ifdef _DM_BUFFER_H_ +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXAssociateDMPbufferSGIX (Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif /* _DM_BUFFER_H_ */ +#endif + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXBindSwapBarrierSGIX (Display *, GLXDrawable, int); +extern Bool glXQueryMaxSwapBarriersSGIX (Display *, int, int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); +#endif + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Status glXGetTransparentIndexSUN (Display *, Window, Window, long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCopySubBufferMESA (Display *, GLXDrawable, int, int, int, int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); +#endif + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPixmap glXCreateGLXPixmapMESA (Display *, XVisualInfo *, Pixmap, Colormap); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); +#endif + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXReleaseBuffersMESA (Display *, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXSet3DfxModeMESA (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode); +#endif + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 +#endif + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 +#endif + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXGetSyncValuesOML (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *); +extern Bool glXGetMscRateOML (Display *, GLXDrawable, int32_t *, int32_t *); +extern int64_t glXSwapBuffersMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t); +extern Bool glXWaitForMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *); +extern Bool glXWaitForSbcOML (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); +#endif + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int + participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; +} GLXPipeRect; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin, YOrigin, maxHeight, maxWidth; +} GLXPipeRectLimits; + +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXHyperpipeNetworkSGIX * glXQueryHyperpipeNetworkSGIX (Display *, int *); +extern int glXHyperpipeConfigSGIX (Display *, int, int, GLXHyperpipeConfigSGIX *, int *); +extern GLXHyperpipeConfigSGIX * glXQueryHyperpipeConfigSGIX (Display *, int, int *); +extern int glXDestroyHyperpipeConfigSGIX (Display *, int); +extern int glXBindHyperpipeSGIX (Display *, int); +extern int glXQueryHyperpipeBestAttribSGIX (Display *, int, int, int, void *, void *); +extern int glXHyperpipeAttribSGIX (Display *, int, int, int, void *); +extern int glXQueryHyperpipeAttribSGIX (Display *, int, int, int, void *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +#endif + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern unsigned int glXGetAGPOffsetMESA (const void *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer); +#endif + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 +#endif + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 +#endif + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXBindTexImageEXT (Display *, GLXDrawable, int, const int *); +extern void glXReleaseTexImageEXT (Display *, GLXDrawable, int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dep/src/irrlicht/irrXML.cpp b/src/dep/src/irrlicht/irrXML.cpp new file mode 100644 index 0000000..05cea70 --- /dev/null +++ b/src/dep/src/irrlicht/irrXML.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" +#include "fast_atof.h" +#include "CXMLReaderImpl.h" + +namespace irr +{ +namespace io +{ + +//! Implementation of the file read callback for ordinary files +class CFileReadCallBack : public IFileReadCallBack +{ +public: + + //! construct from filename + CFileReadCallBack(const char* filename) + : File(0), Size(0), Close(true) + { + // open file + File = fopen(filename, "rb"); + + if (File) + getFileSize(); + } + + //! construct from FILE pointer + CFileReadCallBack(FILE* file) + : File(file), Size(0), Close(false) + { + if (File) + getFileSize(); + } + + //! destructor + virtual ~CFileReadCallBack() + { + if (Close && File) + fclose(File); + } + + //! Reads an amount of bytes from the file. + virtual int read(void* buffer, int sizeToRead) + { + if (!File) + return 0; + + return (int)fread(buffer, 1, sizeToRead, File); + } + + //! Returns size of file in bytes + virtual long getSize() const + { + return Size; + } + +private: + + //! retrieves the file size of the open file + void getFileSize() + { + fseek(File, 0, SEEK_END); + Size = ftell(File); + fseek(File, 0, SEEK_SET); + } + + FILE* File; + long Size; + bool Close; + +}; // end class CFileReadCallBack + + + +// FACTORY FUNCTIONS: + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +//! Creates an instance of an UTF-16 xml parser. +IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UTF-16 xml parser. +IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UTF-16 xml parser. +IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +//! Creates an instance of an UTF-32 xml parser. +IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UTF-32 xml parser. +IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UTF-32 xml parser. +IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +} // end namespace io +} // end namespace irr diff --git a/src/dep/src/irrlicht/jpeglib/README b/src/dep/src/irrlicht/jpeglib/README new file mode 100644 index 0000000..911d0e8 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/README @@ -0,0 +1,385 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6b of 27-Mar-1998 +==================================== + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, +Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, +Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG +Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1998, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The Unix configuration script "configure" was produced with GNU Autoconf. +It is copyright by the Free Software Foundation but is freely distributable. +The same holds for its supporting scripts (config.guess, config.sub, +ltconfig, ltmain.sh). Another support script, install-sh, is copyright +by M.I.T. but is also freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +The IJG distribution formerly included code to read and write GIF files. +To avoid entanglement with the Unisys LZW patent, GIF reading support has +been removed altogether, and the GIF writer has been simplified to produce +"uncompressed GIFs". This technique does not use the LZW algorithm; the +resulting GIF files are larger than usual, but are readable by all standard +GIF decoders. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article is +available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and IEEE, +and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides +good explanations and example C code for a multitude of compression methods +including JPEG. It is an excellent source if you are comfortable reading C +code but don't know much about data compression in general. The book's JPEG +sample code is far from industrial-strength, but when you are ready to look +at a full implementation, you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Some extensions to the original JPEG standard are defined in JPEG Part 3, +a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG +currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available by FTP at +ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text +version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing +the figures. + +The TIFF 6.0 file format specification can be obtained by FTP from +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or +from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision +of the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from ftp://ftp.sgi.com/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have +direct Internet access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or +on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 +"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net +release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ +and other news.answers archive sites, including the official news.answers +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS software, which provides many useful operations on PPM-format image +files. In particular, it can convert PPM images to and from a wide range of +other formats, thus making cjpeg/djpeg considerably more useful. The latest +version is distributed by the NetPBM group, and is available from numerous +sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; +you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from ftp://havefun.stanford.edu/pub/jpeg/. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. (On the other hand, it doesn't do progressive JPEG.) + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +The major thrust for v7 will probably be improvement of visual quality. +The current method for scaling the quantization tables is known not to be +very good at low Q values. We also intend to investigate block boundary +smoothing, "poor man's variable quantization", and other means of improving +quality-vs-file-size performance without sacrificing compatibility. + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +As always, speeding things up is of great interest. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/src/dep/src/irrlicht/jpeglib/Tcdjpeg.c b/src/dep/src/irrlicht/jpeglib/Tcdjpeg.c new file mode 100644 index 0000000..d8667ef --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/Tcdjpeg.c @@ -0,0 +1,182 @@ +#line 1 "cdjpeg.c" +/* + * cdjpeg.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common support routines used by the IJG application + * programs (cjpeg, djpeg, jpegtran). + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include /* to declare isupper(), tolower() */ +#ifdef NEED_SIGNAL_CATCHER +#include /* to declare signal() */ +#endif +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + + +/* + * Signal catcher to ensure that temporary files are removed before aborting. + * NB: for Amiga Manx C this is actually a global routine named _abort(); + * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... + */ + +#ifdef NEED_SIGNAL_CATCHER + +static j_common_ptr sig_cinfo; + +void /* must be global for Manx C */ +signal_catcher (signum) int signum; +{ + if (sig_cinfo != NULL) { + if (sig_cinfo->err != NULL) /* turn off trace output */ + sig_cinfo->err->trace_level = 0; + jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ + } + exit(EXIT_FAILURE); +} + + +GLOBAL(void) +enable_signal_catcher (cinfo) j_common_ptr cinfo; +{ + sig_cinfo = cinfo; +#ifdef SIGINT /* not all systems have SIGINT */ + signal(SIGINT, signal_catcher); +#endif +#ifdef SIGTERM /* not all systems have SIGTERM */ + signal(SIGTERM, signal_catcher); +#endif +} + +#endif + + +/* + * Optional progress monitor: display a percent-done figure on stderr. + */ + +#ifdef PROGRESS_REPORT + +METHODDEF(void) +progress_monitor (cinfo) j_common_ptr cinfo; +{ + cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; + int total_passes = prog->pub.total_passes + prog->total_extra_passes; + int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); + + if (percent_done != prog->percent_done) { + prog->percent_done = percent_done; + if (total_passes > 1) { + fprintf(stderr, "\rPass %d/%d: %3d%% ", + prog->pub.completed_passes + prog->completed_extra_passes + 1, + total_passes, percent_done); + } else { + fprintf(stderr, "\r %3d%% ", percent_done); + } + fflush(stderr); + } +} + + +GLOBAL(void) +start_progress_monitor (cinfo, progress) j_common_ptr cinfo; cd_progress_ptr progress; +{ + /* Enable progress display, unless trace output is on */ + if (cinfo->err->trace_level == 0) { + progress->pub.progress_monitor = progress_monitor; + progress->completed_extra_passes = 0; + progress->total_extra_passes = 0; + progress->percent_done = -1; + cinfo->progress = &progress->pub; + } +} + + +GLOBAL(void) +end_progress_monitor (cinfo) j_common_ptr cinfo; +{ + /* Clear away progress display */ + if (cinfo->err->trace_level == 0) { + fprintf(stderr, "\r \r"); + fflush(stderr); + } +} + +#endif + + +/* + * Case-insensitive matching of possibly-abbreviated keyword switches. + * keyword is the constant keyword (must be lower case already), + * minchars is length of minimum legal abbreviation. + */ + +GLOBAL(boolean) +keymatch (arg, keyword, minchars) char * arg; const char * keyword; int minchars; +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return FALSE; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return FALSE; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return FALSE; + return TRUE; /* A-OK */ +} + + +/* + * Routines to establish binary I/O mode for stdin and stdout. + * Non-Unix systems often require some hacking to get out of text mode. + */ + +GLOBAL(FILE *) +read_stdin () +{ + FILE * input_file = stdin; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdin\n"); + exit(EXIT_FAILURE); + } +#endif + return input_file; +} + + +GLOBAL(FILE *) +write_stdout () +{ + FILE * output_file = stdout; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdout), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdout\n"); + exit(EXIT_FAILURE); + } +#endif + return output_file; +} diff --git a/src/dep/src/irrlicht/jpeglib/ansi2knr b/src/dep/src/irrlicht/jpeglib/ansi2knr new file mode 100644 index 0000000000000000000000000000000000000000..6ae639edff003d29b0a4a504891a4d65b33433a4 GIT binary patch literal 15546 zcmd^meRx#IdGG9=Bkh6&D}fepzzk-NsIAhZ>CIv`yrXoA}M2Np|}pY5Tvad1`pC1l$pwqbR-SwG81S_Gf`$Djk1f{Kody+SS17#>kH(P zUXAkOpd&p6#B)g0OS%);1E48UU4ZtATT zv&2^9r%T{PfIkNRVypgxfGZIn^DVd$@I1heA*ZZCq@{qrW5FAcuLt~y#ZT|H0{)&w z-;exGz(29zQ^@0hKd|6ykUw2w&mDk|g8ryQk0B3#&bEKLXaoEZ=zdGzBY^G8hXVcg zDCqPH?G=cJ5aZw`kulPt{=>+^Dbo;vK*%`U9|`n`-oA*D5s6?to(hTH{&Xy9^pZIl zO7x4~P&}21uu>$Q7QF-Mm=O_?!I&X>Q~i;o2(;`B^qWRV7Qhut2Fy$(4DnPP$QZ%2 z5l94MNk}%KrZ*jlfY_HvB`sn=Y;A4X)D&3ZUtTP+mz}@%(~205V@9u2=5U3KLu8^l z7DL!*;t2~^C1I!da}sfV6}~QqV;B=<2nxnR83LYtP=)~RNA7|^gE>?TGDlz@WsX1} zW{!bzoH+);1I#fv9%7C`bBZ}S;q%N9*nh+v7Cp)wf&CbB44@~NV*qvKewrO~7iyvM zR3VRhp%+qKIXk{O3XbvGIPSE2yq1VRReeb_uhk(RRWc zB+M2^_Y!W9Fk2qoPuM46dLYUMU919(TrB^WyK?`Sedkj9?vChY#C-G#49s17qVfB5 zcVQoxE}uFDe|5GO$i45_+56^U0?2L#aN>;N93RPdfBeeXQ^gCs?d`*#dIpMw>3`gf z=`>$;;x%L5$)~TUgzOppD@2aJR-~Du=gY|Nc;#&F1JvKOEAQP87`3i>hIOE*Dmzvg zC9?3}5C8JR?76DkSoc}*etJ(QDEaP6G$A|Wc6_EW-=q&WE;Ac)=f4w0d!9khijQ-D z^ZuWDzVM>w;WLddn(px(?(A88bXs;yAJ6E~G}uN5QQK+E!(B6cR5pAH%BKEmeEem7 zF^w3FKF;{fHII#c644XQqtZU2D#IvVTBkc*?w#yR_uZGMdodS*U^$vN48%W>P|-@FqAtFHk9Z z?Aq*=Bj!>F7gG2iLwNQa+XBwft-o&b=t;cLlo7 z?&-|$UR;@PU0ju4{WLmkc&!+`(er{c_kM3)-%=}lLiD25a~$6zr5Y6An{2#U7+za% z-Z;Fz`UbQ1WX)~EYi}^i0o5Bbz;4W7tsBhC#F+1bKKfX0WZzw9PeG?Uzj?8~W+XFX zxN(}{9&Vg!Xy=7*!W=yJTGXpC40e5OGaUd@z1%pW#n`g9^=?J`=Dro zYAJtxo!Mj2j&m%Ws~T=xV!9-4blbOmm_L?$m>U|)ds)Ohu{`&q(#Eu`+c9R=$dDM@ z(@{A73p-Yy$GFeWJn@?OgM8Pe+=$(|oZ;k5vh?NV0@t{gn=i02`DTpwOJIG_xhdCm z31+>Y@4mzdr@8Pq7qs@mFFq<6{I{y1e86|W5k14%cZt^iHmMgrgLeyrr@?nB|+_S<^g{c`@HLlKVvV zMLpLwk{x9dL9OuHjfayB)SPQK<3t?9f}nm?;O%oB8IqHnbPwYSeFMjq#IB z zj(ZU2`R0+_9I4Vxl_A;meAn3cio(z@>E_(|XST!0XEC6$roC*hX>b>owN;j<^!CC| z$qh;QcK69m96xK$nl<^MF}7{Y-7$W1;mcqFKHu$L*L}&D11!Q6o@+1s;fLen9Erf2 zh3rt3Fm40sfD=(2WmNwu=rAh(3Gkqqp5s%{(ZlPe8SwB_b4H1zR&aueGl1tfAI3-D z%$sA`^ZGh-By(qe{-}yArS>{YEj{O*)P>fh@j54s@54vgg1+W_rp7kvAdRY4sIO=pMwyfq8!?Ww|(kSCwCFm=f1?`6vl1=GQFUq*B# z(~(fBFB!Wh682>VVn!&s)>oUEDh5PTFquplK5iO(*neO%;OmXWBa&K5izO$K7GWbB z@h$f)tj#Q(DuS7W2%1Jpgo4LIh2a=76%j5 z3`BW96buC8kSLa{6H9$!iO)w=I24Cl5W>qES90<&%4}pb_!)q$9zDK7;rLe46~7t~=4WzlrfRJkb3R>BmSHkba6Ziu4}R zM@ZvH8iK7HX)2NjX%5nLNSl#rk(MH@L|Tiq35jz;JJRh)woXpIOx)-5ksjM2!RLEU z9d*aB??SF;p$GXnz-$-;mU~%lXuL?g7;j;;g{xve63;An7BL%X738v9gPi+b9}=Qf zo>O2tOT7d67(yx9foFo$bAVC&y)M+3`xHB8WuDR4LSBRJe?oc>$%#Gq45WofE08uJ zbs+U1rI9|1^f1zwk!1a?O-*ZkbvT|`;#=uo;j7ybOor3JgArdVPjY-~{0+n}Tb>9X z#2Lr`7u-wX7^nCV!hn&YVupRo7-B5F0pBem!MYYBcZy{oDgJ$kF~-)n*dI0%@&%HQ z2+IBr5>GKo4lhW09cWcaXUs@tRQLrz+YqUXkUN~~L2*0Vw9CkyI|w;pk=}|zCsG*; z4pH6+gLIdRQ;}ZgHi7&HoFV91v-UMmv@PUiMfVp`_!9(#Tc4}F2o3r?VnEUcp;NzB zG3ugx9D@O(8o=`nn7LTLLGw}Mjg~0w8<3(ewfHqBWi7iy%5rPhv$9{&Dm4!|>lIX` z&7+XJ^ZbyYqUgt5^)SI*)p&|Mvr3~m1py%kF+ADNkn}yb1qU}2sq-(uw zbGs!~tH42wzDv<6wdEAoq4ZY?=g*{;JG2CuZnw3#_ke33P(D4ZJ;@po+v3OBzFx)X z)@n)XQ<^HZ77B?fs7kwqHpLWFqj6f&52$)`v_ZðVzfZ|MVQCSS?-5;g z+qC`Yi?VHmrtN@p%UV7{QIwl>v`e3Y)-cK7)kHaWX^wK|YM|U@+chsq&6Z5<7a*41 zMt#mju>1}XE6e9=D`0E+JVNaIc34+_ZIy%&yZ!8mGUt7OtI8KC-UWn;ybBetTapf2b6rQ)C&f$3#I-H(fm-f)3{;orFxcImQSeL= z(|;y~G|T+qyI}n^R%B)%CM5@)3(E0*D(bx)_wq+T%T1?ofaXKRnSuHUPAXNs6qMV z0p*ufXx44e=w@R-fSSdw4O%VQ>H6GHfuV~p6FQ|JT^l3xc_qrNy-V}{NI{j_i>U8< zR6$kRf1!C_{H8R$MuwN`ODbgMXwS1DUs0Xmg9(2RT{B+8t(<4T4tIr4dn$Blt{wtH0I1LzVN-tyVVK(1NX&NJXK*xC z$Z=K0uDCijenUi5v!(KeihEF}ioG^b5!lZGF_XRLkYNVQlK?7o`oVn}#m_^8+x0cg zLudV&nx}>KbwXcfU^1#@96v>FCnhRg!$4t|)o|Ss&N_fg%U5Y<&=ut?o|jxg)+t{} zHrA=!Dw$SKlT7twn#O;XPz?m(<+9*@r2}Pa74&`s20DFoytjhI1t}88z~^*%TcFCh zknG;KNnG?0i7R2Q?(#lNt82eVj2}g}%X=+(u0Ku8FHm%sc^^gDx%@?9PD8(=-1`y& z!ns1~JB(rLT=_PMJos>yd3RIfDq7&JW0P0Y@!khXyh&QImhu{@!FwNVTSN8UI{IQ= z9VEl;M7+lupZc#XHdEv+hgfW&>RV;;2duo|7_sAY-A0Lh1+a6IEOJ(KHgUQ4ZlIZ) zrCg12x7w@D)ywe-aD7YhiLljCs4tCy@M^9&E?p=(INHEM(fJ9b7*@X0AKlhcCdFG z>dF@dS^NPQT-%<7CN*DpS3rbo`}ZV*Q-!w?H&^SAC4w`B_aj#68j}c4ecoOo?)W!} z;0)(=LzU~U>4=pIy$1IxKW=Ig;!;#i&|bh+NiL$j6{zb9HcP~I+^hEErmC@2O(sa> z{ObK76uWxvmb{!py%q3?>wkV$A~>0No4{PYnp2T?4%>S(hp!h%OeoT+tKj$v7sYA)0G59$muiw-2GsDL2d!Tzp~4EEy~pgx*PMC$u`{P+(v7_U$F zC+atKwX|-o@8jQ?%U1YT_*d75GN!-=&9|}Bhd(P<_}4V}8~n>x3&*gMdX1F&Xa8wZ z9o3Gi@)@{m)8|gFojwz7an5u&W>!?Jtyl*@n!W2_EyF}Nt30?T3AF7I0c0UOWbS=S4M_8tBMS_Ryxr%tZ{f$ zoa?T2&qQop1+9j|ouVFhhvS#ir{XT(`EcOmCuaCV;1_;>edcf`9O=*0o5|Q9fkSvx z0vqf4o|uuT=Xp=YAN^feGoffCTx69pj3`cJ!kMCqeuYq?Enu>SflwyVlc^uz306^- zZDC*1tPgAr;9#pa)>ov)03WLF<6YtE%}iRp?a>zs;dPIm`q=8mo0cW4V*~X9$TG^p zu|a(-8H$_XNIf>WIM-4FL;~$~ibc3z<+yqy(O(}5t=`fQjx_o+bPJ-&$uk@6oN&xv zI)DDB=Q~}f1}t~u+DahTI?EM?+hlF7#TE`PUAk=Td?)^@ciaXs|B=GZRW0}Iy?H_* zH}Kj52WmT%WbWj(ISvcv*$~fSKs@TM)b$4t0&pC5*(+BB_=bZKOGIQLJrFn;OY*IR za4;NBOWXvTbSkRFj6iP)^&o<7mRvX&3>}npG7*YQ$76|`R)J*oYan47kwMA2wP|PD zoAr0$!G-c^2ksDzBgl4u^kf_2*!*UPR(tN zTe@0X13SBRtJar922SJENK*|&2pf@JlkrF&$dPCVZBH&Q&e32EhO{vN1MQ4o(c_v?+tlEOC2(sMtHw_W`_bl|n}xE}EB0hSV@h zV4BE8(uZUil(uFf%6j9$KE{k{4)7?4Qi&e?XToA>rHSdSWTp!wQei7}4e2P1Y)og? zJQz?oYs6sUlN|<^Ky)UGB_|NYYJ-15ptK}j;EaB2ZpciU#1P7INXTVR%2L7HyrX^h z?Ey8gY!_zwV@ZyX61JAkK#w>Y72c6vsWgBzZ{_k&s&_Cq!dhY z6BBHoHPq$W%a{PO^zsDWpa28iF)@#q4z0<9CW-L_cFVS{Z96-fm1Uh16GU$?V^}Ux zi*+g<3vqUrBMv#IPUR`3NR2@*!uC>AGB3)td2)v<{=~#nPs#jO?8A^f0+ie31jmKV zTF~JoKBr9ha&jn0Ps-tCErT#wiV*(H;RODoL~f*2j&M^Y8QT5AkH3N={*9YjmKni5 z;g1G0QQ;3CPNJg9jkNIN+0}mtPf1wYCIJD^(vdj%RiQs_2tVgH;pgNf{Jj7`O39Jn zSNBL1&oEr2SudEtf4%;Yk-{^WKdiC?c%Jh2rBJ;m11zS|1moWyj`Wy)0YqG~FG6k! z_M1JNH;b@*w6j@z@GtEln-f7yowAl~fCS(YK34yZ*Ie-7@fMHI*1PA(u~RBur19d@ zJhs1*Prf4#f)B8LVY@A_<+yVzMS1)WwhnxcqHNQdGu@1Yy`ALaf3xSnw*g6R!z>;? zhu?~%S$zC2R|go|A?s#NRQ7`|4eGYteDBF68XWEU#|7}_3f4A>|uL0#! zy#PfB3HyIphyVT7K#&ixEsr^lHAEcA=Hq|Gt3c?t_}D(1kAJq%RvuAsXY&LIb5OP~ z^6_F_o9{XBJqN-iNl`cQF&#m&`S{(zX*A&TG{m~9to#^qn~(df&3IRMp3Q{Z)_cFj zN5AX`-+u7%SjxV9R^fBViH6(Mw+8rg{5Z?j<+JifklTF6@n80F@Y%Y^Vwb;!GJQgM z{Lh=;D0~-X_6INW(a&E+vgPrmlJ*%2545~&d3?9i=GzOty}yO;uS@v&&h38i*)k~5 zE`Pg(kM9VC!MBYJ)$Y5}FIR614c) z0wJ!HAnf8y6zno}U08(nvS3}dpM4fzgN45gzHCW6Qw9^lL&cuOH?T~I8%q?}MdplU z`?|amK15J00HP6zdf7iz!9KIEr`I4JOAxj^n_impI~~I6>mT$9<}n2;&7A)ftORnN zQ?P0^=Q9PXXt&=T!GEJf%lS#sIrGAAm=6>zGx=_cf|a8OOzM*b0=U@Te^$jJ{BxA}qH`EI?dLqC+wF0B zL^%dxTMpk-0Y3xw&j4)4Up3-yE?}-(99h-)Vr(Jc((k!=n43oZCgiNY4teSKUE2ZM z<7WoGQriW%^n0%m;JNS@mxQT&nLDz;}ZF6N}yf*dD*t_}e53 zI1ak~{n;Sk=Su7y0?fDdZGSxs_$c@pXKeph0Q27zyZ`6-=m!aY`3Qh?Rk~3 zb@`D0^eXr=;73tE51O2f_#BTzduDu$M-iK@c*zH2B9t~VhS}Q-QXtTT1J*!mOXu!D z0MO=1Q1iCHmX3`(ngg4fx3;uNhTEEo-2MIrygZudk4Fp~=r2d@a4OIjPxWBqEw==L zpgD-|)$o`fun*s)w&u3Y6UuBrDY7A|vC9)u<$gm-wOspGnyVD)MZy zCmu{5#L2|w+uJtoXlWAIPzRy|_7{2^HrSudH3%b;F_sH{UssBi=RDSTeWiG8SFx=^ z1^gL+gQHRsF!;=`6r(=UQ{M=d;^o(TrHIVISbwHJ7~;2r^3%amBF;cE8B3J>81UCV z4=m;8hRtHe3$obCsgDpRSeDB#5GP=GFQQI8tgjI#k+!z(+=SDCom;kaHt!DX-ngl? zIUv77oWx}vo~dslODXa@#|Z=iW%A2{>YK<32HBM*Ex7Gapu>9exG5gYWUy((UcL1D MM>q^0W|m6$cYaE6VE_OC literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/jpeglib/ansi2knr.1 b/src/dep/src/irrlicht/jpeglib/ansi2knr.1 new file mode 100644 index 0000000..60b33cf --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/ansi2knr.1 @@ -0,0 +1,36 @@ +.TH ANSI2KNR 1 "19 Jan 1996" +.SH NAME +ansi2knr \- convert ANSI C to Kernighan & Ritchie C +.SH SYNOPSIS +.I ansi2knr +[--varargs] input_file [output_file] +.SH DESCRIPTION +If no output_file is supplied, output goes to stdout. +.br +There are no error messages. +.sp +.I ansi2knr +recognizes function definitions by seeing a non-keyword identifier at the left +margin, followed by a left parenthesis, with a right parenthesis as the last +character on the line, and with a left brace as the first token on the +following line (ignoring possible intervening comments). It will recognize a +multi-line header provided that no intervening line ends with a left or right +brace or a semicolon. These algorithms ignore whitespace and comments, except +that the function name must be the first thing on the line. +.sp +The following constructs will confuse it: +.br + - Any other construct that starts at the left margin and follows the +above syntax (such as a macro or function call). +.br + - Some macros that tinker with the syntax of the function header. +.sp +The --varargs switch is obsolete, and is recognized only for +backwards compatibility. The present version of +.I ansi2knr +will always attempt to convert a ... argument to va_alist and va_dcl. +.SH AUTHOR +L. Peter Deutsch wrote the original ansi2knr and +continues to maintain the current version; most of the code in the current +version is his work. ansi2knr also includes contributions by Francois +Pinard and Jim Avera . diff --git a/src/dep/src/irrlicht/jpeglib/ansi2knr.c b/src/dep/src/irrlicht/jpeglib/ansi2knr.c new file mode 100644 index 0000000..0e3ab13 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/ansi2knr.c @@ -0,0 +1,693 @@ +/* ansi2knr.c */ +/* Convert ANSI C function definitions to K&R ("traditional C") syntax */ + +/* +ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY. No author or distributor accepts responsibility to anyone for the +consequences of using it or for whether it serves any particular purpose or +works at all, unless he says so in writing. Refer to the GNU General Public +License (the "GPL") for full details. + +Everyone is granted permission to copy, modify and redistribute ansi2knr, +but only under the conditions described in the GPL. A copy of this license +is supposed to have been given to you along with ansi2knr so you can know +your rights and responsibilities. It should be in a file named COPYLEFT. +[In the IJG distribution, the GPL appears below, not in a separate file.] +Among other things, the copyright notice and this notice must be preserved +on all copies. + +We explicitly state here what we believe is already implied by the GPL: if +the ansi2knr program is distributed as a separate set of sources and a +separate executable file which are aggregated on a storage medium together +with another program, this in itself does not bring the other program under +the GPL, nor does the mere fact that such a program or the procedures for +constructing it invoke the ansi2knr executable bring any other part of the +program under the GPL. +*/ + +/* +---------- Here is the GNU GPL file COPYLEFT, referred to above ---------- +----- These terms do NOT apply to the JPEG software itself; see README ------ + + GHOSTSCRIPT GENERAL PUBLIC LICENSE + (Clarified 11 Feb 1988) + + Copyright (C) 1988 Richard M. Stallman + Everyone is permitted to copy and distribute verbatim copies of this + license, but changing it is not allowed. You can also use this wording + to make the terms for other programs. + + The license agreements of most software companies keep you at the +mercy of those companies. By contrast, our general public license is +intended to give everyone the right to share Ghostscript. To make sure +that you get the rights we want you to have, we need to make +restrictions that forbid anyone to deny you these rights or to ask you +to surrender the rights. Hence this license agreement. + + Specifically, we want to make sure that you have the right to give +away copies of Ghostscript, that you receive source code or else can get +it if you want it, that you can change Ghostscript or use pieces of it +in new free programs, and that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute +copies of Ghostscript, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + Also, for our own protection, we must make certain that everyone finds +out that there is no warranty for Ghostscript. If Ghostscript is +modified by someone else and passed on, we want its recipients to know +that what they have is not what we distributed, so that any problems +introduced by others will not reflect on our reputation. + + Therefore we (Richard M. Stallman and the Free Software Foundation, +Inc.) make the following terms which say what you must do to be allowed +to distribute or change Ghostscript. + + + COPYING POLICIES + + 1. You may copy and distribute verbatim copies of Ghostscript source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy a valid copyright and license +notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved. +Distributed by Free Software Foundation, Inc." (or with whatever year is +appropriate); keep intact the notices on all files that refer to this +License Agreement and to the absence of any warranty; and give any other +recipients of the Ghostscript program a copy of this License Agreement +along with the program. You may charge a distribution fee for the +physical act of transferring a copy. + + 2. You may modify your copy or copies of Ghostscript or any portion of +it, and copy and distribute such modifications under the terms of +Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of Ghostscript + or any part thereof, to be licensed at no charge to all third + parties on terms identical to those contained in this License + Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute Ghostscript (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the +terms of Paragraphs 1 and 2 above provided that you also do one of the +following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. + + 4. You may not copy, sublicense, distribute or transfer Ghostscript +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer Ghostscript is +void and your rights to use the program under this License agreement +shall be automatically terminated. However, parties who have received +computer software programs from you with this License Agreement will not +have their licenses terminated so long as such parties remain in full +compliance. + + 5. If you wish to incorporate parts of Ghostscript into other free +programs whose distribution conditions are different, write to the Free +Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not +yet worked out a simple rule that can be stated here, but we will often +permit this. We will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the +sharing and reuse of software. + +Your comments and suggestions about our licensing policies and our +software are welcome! Please contact the Free Software Foundation, +Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296. + + NO WARRANTY + + BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD +M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES +PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH +YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. +STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN +ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE +GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING +ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU +HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM +BY ANY OTHER PARTY. + +-------------------- End of file COPYLEFT ------------------------------ +*/ + +/* + * Usage: + ansi2knr input_file [output_file] + * If no output_file is supplied, output goes to stdout. + * There are no error messages. + * + * ansi2knr recognizes function definitions by seeing a non-keyword + * identifier at the left margin, followed by a left parenthesis, + * with a right parenthesis as the last character on the line, + * and with a left brace as the first token on the following line + * (ignoring possible intervening comments). + * It will recognize a multi-line header provided that no intervening + * line ends with a left or right brace or a semicolon. + * These algorithms ignore whitespace and comments, except that + * the function name must be the first thing on the line. + * The following constructs will confuse it: + * - Any other construct that starts at the left margin and + * follows the above syntax (such as a macro or function call). + * - Some macros that tinker with the syntax of the function header. + */ + +/* + * The original and principal author of ansi2knr is L. Peter Deutsch + * . Other authors are noted in the change history + * that follows (in reverse chronological order): + lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with + compilers that don't understand void, as suggested by + Tom Lane + lpd 96-01-15 changed to require that the first non-comment token + on the line following a function header be a left brace, + to reduce sensitivity to macros, as suggested by Tom Lane + + lpd 95-06-22 removed #ifndefs whose sole purpose was to define + undefined preprocessor symbols as 0; changed all #ifdefs + for configuration symbols to #ifs + lpd 95-04-05 changed copyright notice to make it clear that + including ansi2knr in a program does not bring the entire + program under the GPL + lpd 94-12-18 added conditionals for systems where ctype macros + don't handle 8-bit characters properly, suggested by + Francois Pinard ; + removed --varargs switch (this is now the default) + lpd 94-10-10 removed CONFIG_BROKETS conditional + lpd 94-07-16 added some conditionals to help GNU `configure', + suggested by Francois Pinard ; + properly erase prototype args in function parameters, + contributed by Jim Avera ; + correct error in writeblanks (it shouldn't erase EOLs) + lpd 89-xx-xx original version + */ + +/* Most of the conditionals here are to make ansi2knr work with */ +/* or without the GNU configure machinery. */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include + +#if HAVE_CONFIG_H + +/* + For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h). + This will define HAVE_CONFIG_H and so, activate the following lines. + */ + +# if STDC_HEADERS || HAVE_STRING_H +# include +# else +# include +# endif + +#else /* not HAVE_CONFIG_H */ + +/* Otherwise do it the hard way */ + +# ifdef BSD +# include +# else +# ifdef VMS + extern int strlen(), strncmp(); +# else +# include +# endif +# endif + +#endif /* not HAVE_CONFIG_H */ + +#if STDC_HEADERS +# include +#else +/* + malloc and free should be declared in stdlib.h, + but if you've got a K&R compiler, they probably aren't. + */ +# ifdef MSDOS +# include +# else +# ifdef VMS + extern char *malloc(); + extern void free(); +# else + extern char *malloc(); + extern int free(); +# endif +# endif + +#endif + +/* + * The ctype macros don't always handle 8-bit characters correctly. + * Compensate for this here. + */ +#ifdef isascii +# undef HAVE_ISASCII /* just in case */ +# define HAVE_ISASCII 1 +#else +#endif +#if STDC_HEADERS || !HAVE_ISASCII +# define is_ascii(c) 1 +#else +# define is_ascii(c) isascii(c) +#endif + +#define is_space(c) (is_ascii(c) && isspace(c)) +#define is_alpha(c) (is_ascii(c) && isalpha(c)) +#define is_alnum(c) (is_ascii(c) && isalnum(c)) + +/* Scanning macros */ +#define isidchar(ch) (is_alnum(ch) || (ch) == '_') +#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') + +/* Forward references */ +char *skipspace(); +int writeblanks(); +int test1(); +int convert1(); + +/* The main program */ +int +main(argc, argv) + int argc; + char *argv[]; +{ FILE *in, *out; +#define bufsize 5000 /* arbitrary size */ + char *buf; + char *line; + char *more; + /* + * In previous versions, ansi2knr recognized a --varargs switch. + * If this switch was supplied, ansi2knr would attempt to convert + * a ... argument to va_alist and va_dcl; if this switch was not + * supplied, ansi2knr would simply drop any such arguments. + * Now, ansi2knr always does this conversion, and we only + * check for this switch for backward compatibility. + */ + int convert_varargs = 1; + + if ( argc > 1 && argv[1][0] == '-' ) + { if ( !strcmp(argv[1], "--varargs") ) + { convert_varargs = 1; + argc--; + argv++; + } + else + { fprintf(stderr, "Unrecognized switch: %s\n", argv[1]); + exit(1); + } + } + switch ( argc ) + { + default: + printf("Usage: ansi2knr input_file [output_file]\n"); + exit(0); + case 2: + out = stdout; + break; + case 3: + out = fopen(argv[2], "w"); + if ( out == NULL ) + { fprintf(stderr, "Cannot open output file %s\n", argv[2]); + exit(1); + } + } + in = fopen(argv[1], "r"); + if ( in == NULL ) + { fprintf(stderr, "Cannot open input file %s\n", argv[1]); + exit(1); + } + fprintf(out, "#line 1 \"%s\"\n", argv[1]); + buf = malloc(bufsize); + line = buf; + while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) + { +test: line += strlen(line); + switch ( test1(buf) ) + { + case 2: /* a function header */ + convert1(buf, out, 1, convert_varargs); + break; + case 1: /* a function */ + /* Check for a { at the start of the next line. */ + more = ++line; +f: if ( line >= buf + (bufsize - 1) ) /* overflow check */ + goto wl; + if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) + goto wl; + switch ( *skipspace(more, 1) ) + { + case '{': + /* Definitely a function header. */ + convert1(buf, out, 0, convert_varargs); + fputs(more, out); + break; + case 0: + /* The next line was blank or a comment: */ + /* keep scanning for a non-comment. */ + line += strlen(line); + goto f; + default: + /* buf isn't a function header, but */ + /* more might be. */ + fputs(buf, out); + strcpy(buf, more); + line = buf; + goto test; + } + break; + case -1: /* maybe the start of a function */ + if ( line != buf + (bufsize - 1) ) /* overflow check */ + continue; + /* falls through */ + default: /* not a function */ +wl: fputs(buf, out); + break; + } + line = buf; + } + if ( line != buf ) + fputs(buf, out); + free(buf); + fclose(out); + fclose(in); + return 0; +} + +/* Skip over space and comments, in either direction. */ +char * +skipspace(p, dir) + register char *p; + register int dir; /* 1 for forward, -1 for backward */ +{ for ( ; ; ) + { while ( is_space(*p) ) + p += dir; + if ( !(*p == '/' && p[dir] == '*') ) + break; + p += dir; p += dir; + while ( !(*p == '*' && p[dir] == '/') ) + { if ( *p == 0 ) + return p; /* multi-line comment?? */ + p += dir; + } + p += dir; p += dir; + } + return p; +} + +/* + * Write blanks over part of a string. + * Don't overwrite end-of-line characters. + */ +int +writeblanks(start, end) + char *start; + char *end; +{ char *p; + for ( p = start; p < end; p++ ) + if ( *p != '\r' && *p != '\n' ) + *p = ' '; + return 0; +} + +/* + * Test whether the string in buf is a function definition. + * The string may contain and/or end with a newline. + * Return as follows: + * 0 - definitely not a function definition; + * 1 - definitely a function definition; + * 2 - definitely a function prototype (NOT USED); + * -1 - may be the beginning of a function definition, + * append another line and look again. + * The reason we don't attempt to convert function prototypes is that + * Ghostscript's declaration-generating macros look too much like + * prototypes, and confuse the algorithms. + */ +int +test1(buf) + char *buf; +{ register char *p = buf; + char *bend; + char *endfn; + int contin; + + if ( !isidfirstchar(*p) ) + return 0; /* no name at left margin */ + bend = skipspace(buf + strlen(buf) - 1, -1); + switch ( *bend ) + { + case ';': contin = 0 /*2*/; break; + case ')': contin = 1; break; + case '{': return 0; /* not a function */ + case '}': return 0; /* not a function */ + default: contin = -1; + } + while ( isidchar(*p) ) + p++; + endfn = p; + p = skipspace(p, 1); + if ( *p++ != '(' ) + return 0; /* not a function */ + p = skipspace(p, 1); + if ( *p == ')' ) + return 0; /* no parameters */ + /* Check that the apparent function name isn't a keyword. */ + /* We only need to check for keywords that could be followed */ + /* by a left parenthesis (which, unfortunately, is most of them). */ + { static char *words[] = + { "asm", "auto", "case", "char", "const", "double", + "extern", "float", "for", "if", "int", "long", + "register", "return", "short", "signed", "sizeof", + "static", "switch", "typedef", "unsigned", + "void", "volatile", "while", 0 + }; + char **key = words; + char *kp; + int len = endfn - buf; + + while ( (kp = *key) != 0 ) + { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) + return 0; /* name is a keyword */ + key++; + } + } + return contin; +} + +/* Convert a recognized function definition or header to K&R syntax. */ +int +convert1(buf, out, header, convert_varargs) + char *buf; + FILE *out; + int header; /* Boolean */ + int convert_varargs; /* Boolean */ +{ char *endfn; + register char *p; + char **breaks; + unsigned num_breaks = 2; /* for testing */ + char **btop; + char **bp; + char **ap; + char *vararg = 0; + + /* Pre-ANSI implementations don't agree on whether strchr */ + /* is called strchr or index, so we open-code it here. */ + for ( endfn = buf; *(endfn++) != '('; ) + ; +top: p = endfn; + breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); + if ( breaks == 0 ) + { /* Couldn't allocate break table, give up */ + fprintf(stderr, "Unable to allocate break table!\n"); + fputs(buf, out); + return -1; + } + btop = breaks + num_breaks * 2 - 2; + bp = breaks; + /* Parse the argument list */ + do + { int level = 0; + char *lp = NULL; + char *rp; + char *end = NULL; + + if ( bp >= btop ) + { /* Filled up break table. */ + /* Allocate a bigger one and start over. */ + free((char *)breaks); + num_breaks <<= 1; + goto top; + } + *bp++ = p; + /* Find the end of the argument */ + for ( ; end == NULL; p++ ) + { switch(*p) + { + case ',': + if ( !level ) end = p; + break; + case '(': + if ( !level ) lp = p; + level++; + break; + case ')': + if ( --level < 0 ) end = p; + else rp = p; + break; + case '/': + p = skipspace(p, 1) - 1; + break; + default: + ; + } + } + /* Erase any embedded prototype parameters. */ + if ( lp ) + writeblanks(lp + 1, rp); + p--; /* back up over terminator */ + /* Find the name being declared. */ + /* This is complicated because of procedure and */ + /* array modifiers. */ + for ( ; ; ) + { p = skipspace(p - 1, -1); + switch ( *p ) + { + case ']': /* skip array dimension(s) */ + case ')': /* skip procedure args OR name */ + { int level = 1; + while ( level ) + switch ( *--p ) + { + case ']': case ')': level++; break; + case '[': case '(': level--; break; + case '/': p = skipspace(p, -1) + 1; break; + default: ; + } + } + if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) + { /* We found the name being declared */ + while ( !isidfirstchar(*p) ) + p = skipspace(p, 1) + 1; + goto found; + } + break; + default: + goto found; + } + } +found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) + { if ( convert_varargs ) + { *bp++ = "va_alist"; + vararg = p-2; + } + else + { p++; + if ( bp == breaks + 1 ) /* sole argument */ + writeblanks(breaks[0], p); + else + writeblanks(bp[-1] - 1, p); + bp--; + } + } + else + { while ( isidchar(*p) ) p--; + *bp++ = p+1; + } + p = end; + } + while ( *p++ == ',' ); + *bp = p; + /* Make a special check for 'void' arglist */ + if ( bp == breaks+2 ) + { p = skipspace(breaks[0], 1); + if ( !strncmp(p, "void", 4) ) + { p = skipspace(p+4, 1); + if ( p == breaks[2] - 1 ) + { bp = breaks; /* yup, pretend arglist is empty */ + writeblanks(breaks[0], p + 1); + } + } + } + /* Put out the function name and left parenthesis. */ + p = buf; + while ( p != endfn ) putc(*p, out), p++; + /* Put out the declaration. */ + if ( header ) + { fputs(");", out); + for ( p = breaks[0]; *p; p++ ) + if ( *p == '\r' || *p == '\n' ) + putc(*p, out); + } + else + { for ( ap = breaks+1; ap < bp; ap += 2 ) + { p = *ap; + while ( isidchar(*p) ) + putc(*p, out), p++; + if ( ap < bp - 1 ) + fputs(", ", out); + } + fputs(") ", out); + /* Put out the argument declarations */ + for ( ap = breaks+2; ap <= bp; ap += 2 ) + (*ap)[-1] = ';'; + if ( vararg != 0 ) + { *vararg = 0; + fputs(breaks[0], out); /* any prior args */ + fputs("va_dcl", out); /* the final arg */ + fputs(bp[0], out); + } + else + fputs(breaks[0], out); + } + free((char *)breaks); + return 0; +} diff --git a/src/dep/src/irrlicht/jpeglib/cderror.h b/src/dep/src/irrlicht/jpeglib/cderror.h new file mode 100644 index 0000000..c19d38f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/cderror.h @@ -0,0 +1,132 @@ +/* + * cderror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the cjpeg/djpeg + * applications. These strings are not needed as part of the JPEG library + * proper. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef CDERROR_H +#define CDERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* CDERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */ + +#ifdef BMP_SUPPORTED +JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format") +JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported") +JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length") +JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1") +JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB") +JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported") +JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM") +JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image") +JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image") +JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image") +JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image") +#endif /* BMP_SUPPORTED */ + +#ifdef GIF_SUPPORTED +JMESSAGE(JERR_GIF_BUG, "GIF output got confused") +JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d") +JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB") +JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file") +JMESSAGE(JERR_GIF_NOT, "Not a GIF file") +JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image") +JMESSAGE(JTRC_GIF_BADVERSION, + "Warning: unexpected GIF version number '%c%c%c'") +JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x") +JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input") +JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file") +JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring") +JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image") +JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits") +#endif /* GIF_SUPPORTED */ + +#ifdef PPM_SUPPORTED +JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") +JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") +JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file") +JMESSAGE(JTRC_PGM, "%ux%u PGM image") +JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") +JMESSAGE(JTRC_PPM, "%ux%u PPM image") +JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image") +#endif /* PPM_SUPPORTED */ + +#ifdef RLE_SUPPORTED +JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library") +JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB") +JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE") +JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file") +JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header") +JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header") +JMESSAGE(JERR_RLE_NOT, "Not an RLE file") +JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE") +JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup") +JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file") +JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d") +JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file") +JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d") +JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d") +#endif /* RLE_SUPPORTED */ + +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format") +JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file") +JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB") +JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image") +JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image") +JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image") +#else +JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled") +#endif /* TARGA_SUPPORTED */ + +JMESSAGE(JERR_BAD_CMAP_FILE, + "Color map file is invalid or of unsupported format") +JMESSAGE(JERR_TOO_MANY_COLORS, + "Output file format cannot handle %d colormap entries") +JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed") +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_UNKNOWN_FORMAT, + "Unrecognized input file format --- perhaps you need -targa") +#else +JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format") +#endif +JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTADDONCODE +} ADDON_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE diff --git a/src/dep/src/irrlicht/jpeglib/cdjpeg.c b/src/dep/src/irrlicht/jpeglib/cdjpeg.c new file mode 100644 index 0000000..89fe633 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/cdjpeg.c @@ -0,0 +1,181 @@ +/* + * cdjpeg.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common support routines used by the IJG application + * programs (cjpeg, djpeg, jpegtran). + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include /* to declare isupper(), tolower() */ +#ifdef NEED_SIGNAL_CATCHER +#include /* to declare signal() */ +#endif +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + + +/* + * Signal catcher to ensure that temporary files are removed before aborting. + * NB: for Amiga Manx C this is actually a global routine named _abort(); + * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... + */ + +#ifdef NEED_SIGNAL_CATCHER + +static j_common_ptr sig_cinfo; + +void /* must be global for Manx C */ +signal_catcher (int signum) +{ + if (sig_cinfo != NULL) { + if (sig_cinfo->err != NULL) /* turn off trace output */ + sig_cinfo->err->trace_level = 0; + jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ + } + exit(EXIT_FAILURE); +} + + +GLOBAL(void) +enable_signal_catcher (j_common_ptr cinfo) +{ + sig_cinfo = cinfo; +#ifdef SIGINT /* not all systems have SIGINT */ + signal(SIGINT, signal_catcher); +#endif +#ifdef SIGTERM /* not all systems have SIGTERM */ + signal(SIGTERM, signal_catcher); +#endif +} + +#endif + + +/* + * Optional progress monitor: display a percent-done figure on stderr. + */ + +#ifdef PROGRESS_REPORT + +METHODDEF(void) +progress_monitor (j_common_ptr cinfo) +{ + cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; + int total_passes = prog->pub.total_passes + prog->total_extra_passes; + int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); + + if (percent_done != prog->percent_done) { + prog->percent_done = percent_done; + if (total_passes > 1) { + fprintf(stderr, "\rPass %d/%d: %3d%% ", + prog->pub.completed_passes + prog->completed_extra_passes + 1, + total_passes, percent_done); + } else { + fprintf(stderr, "\r %3d%% ", percent_done); + } + fflush(stderr); + } +} + + +GLOBAL(void) +start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) +{ + /* Enable progress display, unless trace output is on */ + if (cinfo->err->trace_level == 0) { + progress->pub.progress_monitor = progress_monitor; + progress->completed_extra_passes = 0; + progress->total_extra_passes = 0; + progress->percent_done = -1; + cinfo->progress = &progress->pub; + } +} + + +GLOBAL(void) +end_progress_monitor (j_common_ptr cinfo) +{ + /* Clear away progress display */ + if (cinfo->err->trace_level == 0) { + fprintf(stderr, "\r \r"); + fflush(stderr); + } +} + +#endif + + +/* + * Case-insensitive matching of possibly-abbreviated keyword switches. + * keyword is the constant keyword (must be lower case already), + * minchars is length of minimum legal abbreviation. + */ + +GLOBAL(boolean) +keymatch (char * arg, const char * keyword, int minchars) +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return FALSE; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return FALSE; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return FALSE; + return TRUE; /* A-OK */ +} + + +/* + * Routines to establish binary I/O mode for stdin and stdout. + * Non-Unix systems often require some hacking to get out of text mode. + */ + +GLOBAL(FILE *) +read_stdin (void) +{ + FILE * input_file = stdin; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdin\n"); + exit(EXIT_FAILURE); + } +#endif + return input_file; +} + + +GLOBAL(FILE *) +write_stdout (void) +{ + FILE * output_file = stdout; + +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdout), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { + fprintf(stderr, "Cannot reopen stdout\n"); + exit(EXIT_FAILURE); + } +#endif + return output_file; +} diff --git a/src/dep/src/irrlicht/jpeglib/cdjpeg.h b/src/dep/src/irrlicht/jpeglib/cdjpeg.h new file mode 100644 index 0000000..1574e0b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/cdjpeg.h @@ -0,0 +1,184 @@ +/* + * cdjpeg.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common declarations for the sample applications + * cjpeg and djpeg. It is NOT used by the core JPEG library. + */ + +#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */ +#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + + +/* + * Object interface for cjpeg's source file decoding modules + */ + +typedef struct cjpeg_source_struct * cjpeg_source_ptr; + +struct cjpeg_source_struct { + JMETHOD(void, start_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(void, finish_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + + FILE *input_file; + + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * Object interface for djpeg's output file encoding modules + */ + +typedef struct djpeg_dest_struct * djpeg_dest_ptr; + +struct djpeg_dest_struct { + /* start_output is called after jpeg_start_decompress finishes. + * The color map will be ready at this time, if one is needed. + */ + JMETHOD(void, start_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + /* Emit the specified number of pixel rows from the buffer. */ + JMETHOD(void, put_pixel_rows, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied)); + /* Finish up at the end of the image. */ + JMETHOD(void, finish_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + + /* Target file spec; filled in by djpeg.c after object is created. */ + FILE * output_file; + + /* Output pixel-row buffer. Created by module init or start_output. + * Width is cinfo->output_width * cinfo->output_components; + * height is buffer_height. + */ + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * cjpeg/djpeg may need to perform extra passes to convert to or from + * the source/destination file format. The JPEG library does not know + * about these passes, but we'd like them to be counted by the progress + * monitor. We use an expanded progress monitor object to hold the + * additional pass count. + */ + +struct cdjpeg_progress_mgr { + struct jpeg_progress_mgr pub; /* fields known to JPEG library */ + int completed_extra_passes; /* extra passes completed */ + int total_extra_passes; /* total extra */ + /* last printed percentage stored here to avoid multiple printouts */ + int percent_done; +}; + +typedef struct cdjpeg_progress_mgr * cd_progress_ptr; + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_read_bmp jIRdBMP +#define jinit_write_bmp jIWrBMP +#define jinit_read_gif jIRdGIF +#define jinit_write_gif jIWrGIF +#define jinit_read_ppm jIRdPPM +#define jinit_write_ppm jIWrPPM +#define jinit_read_rle jIRdRLE +#define jinit_write_rle jIWrRLE +#define jinit_read_targa jIRdTarga +#define jinit_write_targa jIWrTarga +#define read_quant_tables RdQTables +#define read_scan_script RdScnScript +#define set_quant_slots SetQSlots +#define set_sample_factors SetSFacts +#define read_color_map RdCMap +#define enable_signal_catcher EnSigCatcher +#define start_progress_monitor StProgMon +#define end_progress_monitor EnProgMon +#define read_stdin RdStdin +#define write_stdout WrStdout +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Module selection routines for I/O modules. */ + +EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo, + boolean is_os2)); +EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo)); + +/* cjpeg support routines (in rdswitch.c) */ + +EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename, + int scale_factor, boolean force_baseline)); +EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename)); +EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg)); +EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg)); + +/* djpeg support routines (in rdcolmap.c) */ + +EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* common support routines (in cdjpeg.c) */ + +EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo)); +EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo, + cd_progress_ptr progress)); +EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo)); +EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars)); +EXTERN(FILE *) read_stdin JPP((void)); +EXTERN(FILE *) write_stdout JPP((void)); + +/* miscellaneous useful macros */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define WRITE_BINARY "w" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define WRITE_BINARY "wb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define WRITE_BINARY "wb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif +#ifndef EXIT_WARNING +#ifdef VMS +#define EXIT_WARNING 1 /* VMS is very nonstandard */ +#else +#define EXIT_WARNING 2 +#endif +#endif diff --git a/src/dep/src/irrlicht/jpeglib/change.log b/src/dep/src/irrlicht/jpeglib/change.log new file mode 100644 index 0000000..953680c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/change.log @@ -0,0 +1,217 @@ +CHANGE LOG for Independent JPEG Group's JPEG software + + +Version 6b 27-Mar-1998 +----------------------- + +jpegtran has new features for lossless image transformations (rotation +and flipping) as well as "lossless" reduction to grayscale. + +jpegtran now copies comments by default; it has a -copy switch to enable +copying all APPn blocks as well, or to suppress comments. (Formerly it +always suppressed comments and APPn blocks.) jpegtran now also preserves +JFIF version and resolution information. + +New decompressor library feature: COM and APPn markers found in the input +file can be saved in memory for later use by the application. (Before, +you had to code this up yourself with a custom marker processor.) + +There is an unused field "void * client_data" now in compress and decompress +parameter structs; this may be useful in some applications. + +JFIF version number information is now saved by the decoder and accepted by +the encoder. jpegtran uses this to copy the source file's version number, +to ensure "jpegtran -copy all" won't create bogus files that contain JFXX +extensions but claim to be version 1.01. Applications that generate their +own JFXX extension markers also (finally) have a supported way to cause the +encoder to emit JFIF version number 1.02. + +djpeg's trace mode reports JFIF 1.02 thumbnail images as such, rather +than as unknown APP0 markers. + +In -verbose mode, djpeg and rdjpgcom will try to print the contents of +APP12 markers as text. Some digital cameras store useful text information +in APP12 markers. + +Handling of truncated data streams is more robust: blocks beyond the one in +which the error occurs will be output as uniform gray, or left unchanged +if decoding a progressive JPEG. The appearance no longer depends on the +Huffman tables being used. + +Huffman tables are checked for validity much more carefully than before. + +To avoid the Unisys LZW patent, djpeg's GIF output capability has been +changed to produce "uncompressed GIFs", and cjpeg's GIF input capability +has been removed altogether. We're not happy about it either, but there +seems to be no good alternative. + +The configure script now supports building libjpeg as a shared library +on many flavors of Unix (all the ones that GNU libtool knows how to +build shared libraries for). Use "./configure --enable-shared" to +try this out. + +New jconfig file and makefiles for Microsoft Visual C++ and Developer Studio. +Also, a jconfig file and a build script for Metrowerks CodeWarrior +on Apple Macintosh. makefile.dj has been updated for DJGPP v2, and there +are miscellaneous other minor improvements in the makefiles. + +jmemmac.c now knows how to create temporary files following Mac System 7 +conventions. + +djpeg's -map switch is now able to read raw-format PPM files reliably. + +cjpeg -progressive -restart no longer generates any unnecessary DRI markers. + +Multiple calls to jpeg_simple_progression for a single JPEG object +no longer leak memory. + + +Version 6a 7-Feb-96 +-------------------- + +Library initialization sequence modified to detect version mismatches +and struct field packing mismatches between library and calling application. +This change requires applications to be recompiled, but does not require +any application source code change. + +All routine declarations changed to the style "GLOBAL(type) name ...", +that is, GLOBAL, LOCAL, METHODDEF, EXTERN are now macros taking the +routine's return type as an argument. This makes it possible to add +Microsoft-style linkage keywords to all the routines by changing just +these macros. Note that any application code that was using these macros +will have to be changed. + +DCT coefficient quantization tables are now stored in normal array order +rather than zigzag order. Application code that calls jpeg_add_quant_table, +or otherwise manipulates quantization tables directly, will need to be +changed. If you need to make such code work with either older or newer +versions of the library, a test like "#if JPEG_LIB_VERSION >= 61" is +recommended. + +djpeg's trace capability now dumps DQT tables in natural order, not zigzag +order. This allows the trace output to be made into a "-qtables" file +more easily. + +New system-dependent memory manager module for use on Apple Macintosh. + +Fix bug in cjpeg's -smooth option: last one or two scanlines would be +duplicates of the prior line unless the image height mod 16 was 1 or 2. + +Repair minor problems in VMS, BCC, MC6 makefiles. + +New configure script based on latest GNU Autoconf. + +Correct the list of include files needed by MetroWerks C for ccommand(). + +Numerous small documentation updates. + + +Version 6 2-Aug-95 +------------------- + +Progressive JPEG support: library can read and write full progressive JPEG +files. A "buffered image" mode supports incremental decoding for on-the-fly +display of progressive images. Simply recompiling an existing IJG-v5-based +decoder with v6 should allow it to read progressive files, though of course +without any special progressive display. + +New "jpegtran" application performs lossless transcoding between different +JPEG formats; primarily, it can be used to convert baseline to progressive +JPEG and vice versa. In support of jpegtran, the library now allows lossless +reading and writing of JPEG files as DCT coefficient arrays. This ability +may be of use in other applications. + +Notes for programmers: +* We changed jpeg_start_decompress() to be able to suspend; this makes all +decoding modes available to suspending-input applications. However, +existing applications that use suspending input will need to be changed +to check the return value from jpeg_start_decompress(). You don't need to +do anything if you don't use a suspending data source. +* We changed the interface to the virtual array routines: access_virt_array +routines now take a count of the number of rows to access this time. The +last parameter to request_virt_array routines is now interpreted as the +maximum number of rows that may be accessed at once, but not necessarily +the height of every access. + + +Version 5b 15-Mar-95 +--------------------- + +Correct bugs with grayscale images having v_samp_factor > 1. + +jpeg_write_raw_data() now supports output suspension. + +Correct bugs in "configure" script for case of compiling in +a directory other than the one containing the source files. + +Repair bug in jquant1.c: sometimes didn't use as many colors as it could. + +Borland C makefile and jconfig file work under either MS-DOS or OS/2. + +Miscellaneous improvements to documentation. + + +Version 5a 7-Dec-94 +-------------------- + +Changed color conversion roundoff behavior so that grayscale values are +represented exactly. (This causes test image files to change.) + +Make ordered dither use 16x16 instead of 4x4 pattern for a small quality +improvement. + +New configure script based on latest GNU Autoconf. +Fix configure script to handle CFLAGS correctly. +Rename *.auto files to *.cfg, so that configure script still works if +file names have been truncated for DOS. + +Fix bug in rdbmp.c: didn't allow for extra data between header and image. + +Modify rdppm.c/wrppm.c to handle 2-byte raw PPM/PGM formats for 12-bit data. + +Fix several bugs in rdrle.c. + +NEED_SHORT_EXTERNAL_NAMES option was broken. + +Revise jerror.h/jerror.c for more flexibility in message table. + +Repair oversight in jmemname.c NO_MKTEMP case: file could be there +but unreadable. + + +Version 5 24-Sep-94 +-------------------- + +Version 5 represents a nearly complete redesign and rewrite of the IJG +software. Major user-visible changes include: + * Automatic configuration simplifies installation for most Unix systems. + * A range of speed vs. image quality tradeoffs are supported. + This includes resizing of an image during decompression: scaling down + by a factor of 1/2, 1/4, or 1/8 is handled very efficiently. + * New programs rdjpgcom and wrjpgcom allow insertion and extraction + of text comments in a JPEG file. + +The application programmer's interface to the library has changed completely. +Notable improvements include: + * We have eliminated the use of callback routines for handling the + uncompressed image data. The application now sees the library as a + set of routines that it calls to read or write image data on a + scanline-by-scanline basis. + * The application image data is represented in a conventional interleaved- + pixel format, rather than as a separate array for each color channel. + This can save a copying step in many programs. + * The handling of compressed data has been cleaned up: the application can + supply routines to source or sink the compressed data. It is possible to + suspend processing on source/sink buffer overrun, although this is not + supported in all operating modes. + * All static state has been eliminated from the library, so that multiple + instances of compression or decompression can be active concurrently. + * JPEG abbreviated datastream formats are supported, ie, quantization and + Huffman tables can be stored separately from the image data. + * And not only that, but the documentation of the library has improved + considerably! + + +The last widely used release before the version 5 rewrite was version 4A of +18-Feb-93. Change logs before that point have been discarded, since they +are not of much interest after the rewrite. diff --git a/src/dep/src/irrlicht/jpeglib/cjpeg.1 b/src/dep/src/irrlicht/jpeglib/cjpeg.1 new file mode 100644 index 0000000..cf6a5b2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/cjpeg.1 @@ -0,0 +1,292 @@ +.TH CJPEG 1 "20 March 1998" +.SH NAME +cjpeg \- compress an image file to a JPEG file +.SH SYNOPSIS +.B cjpeg +[ +.I options +] +[ +.I filename +] +.LP +.SH DESCRIPTION +.LP +.B cjpeg +compresses the named image file, or the standard input if no file is +named, and produces a JPEG/JFIF file on the standard output. +The currently supported input file formats are: PPM (PBMPLUS color +format), PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster +Toolkit format). (RLE is supported only if the URT library is available.) +.SH OPTIONS +All switch names may be abbreviated; for example, +.B \-grayscale +may be written +.B \-gray +or +.BR \-gr . +Most of the "basic" switches can be abbreviated to as little as one letter. +Upper and lower case are equivalent (thus +.B \-BMP +is the same as +.BR \-bmp ). +British spellings are also accepted (e.g., +.BR \-greyscale ), +though for brevity these are not mentioned below. +.PP +The basic switches are: +.TP +.BI \-quality " N" +Scale quantization tables to adjust image quality. Quality is 0 (worst) to +100 (best); default is 75. (See below for more info.) +.TP +.B \-grayscale +Create monochrome JPEG file from color input. Be sure to use this switch when +compressing a grayscale BMP file, because +.B cjpeg +isn't bright enough to notice whether a BMP file uses only shades of gray. +By saying +.BR \-grayscale , +you'll get a smaller JPEG file that takes less time to process. +.TP +.B \-optimize +Perform optimization of entropy encoding parameters. Without this, default +encoding parameters are used. +.B \-optimize +usually makes the JPEG file a little smaller, but +.B cjpeg +runs somewhat slower and needs much more memory. Image quality and speed of +decompression are unaffected by +.BR \-optimize . +.TP +.B \-progressive +Create progressive JPEG file (see below). +.TP +.B \-targa +Input file is Targa format. Targa files that contain an "identification" +field will not be automatically recognized by +.BR cjpeg ; +for such files you must specify +.B \-targa +to make +.B cjpeg +treat the input as Targa format. +For most Targa files, you won't need this switch. +.PP +The +.B \-quality +switch lets you trade off compressed file size against quality of the +reconstructed image: the higher the quality setting, the larger the JPEG file, +and the closer the output image will be to the original input. Normally you +want to use the lowest quality setting (smallest file) that decompresses into +something visually indistinguishable from the original image. For this +purpose the quality setting should be between 50 and 95; the default of 75 is +often about right. If you see defects at +.B \-quality +75, then go up 5 or 10 counts at a time until you are happy with the output +image. (The optimal setting will vary from one image to another.) +.PP +.B \-quality +100 will generate a quantization table of all 1's, minimizing loss in the +quantization step (but there is still information loss in subsampling, as well +as roundoff error). This setting is mainly of interest for experimental +purposes. Quality values above about 95 are +.B not +recommended for normal use; the compressed file size goes up dramatically for +hardly any gain in output image quality. +.PP +In the other direction, quality values below 50 will produce very small files +of low image quality. Settings around 5 to 10 might be useful in preparing an +index of a large image library, for example. Try +.B \-quality +2 (or so) for some amusing Cubist effects. (Note: quality +values below about 25 generate 2-byte quantization tables, which are +considered optional in the JPEG standard. +.B cjpeg +emits a warning message when you give such a quality value, because some +other JPEG programs may be unable to decode the resulting file. Use +.B \-baseline +if you need to ensure compatibility at low quality values.) +.PP +The +.B \-progressive +switch creates a "progressive JPEG" file. In this type of JPEG file, the data +is stored in multiple scans of increasing quality. If the file is being +transmitted over a slow communications link, the decoder can use the first +scan to display a low-quality image very quickly, and can then improve the +display with each subsequent scan. The final image is exactly equivalent to a +standard JPEG file of the same quality setting, and the total file size is +about the same --- often a little smaller. +.B Caution: +progressive JPEG is not yet widely implemented, so many decoders will be +unable to view a progressive JPEG file at all. +.PP +Switches for advanced users: +.TP +.B \-dct int +Use integer DCT method (default). +.TP +.B \-dct fast +Use fast integer DCT (less accurate). +.TP +.B \-dct float +Use floating-point DCT method. +The float method is very slightly more accurate than the int method, but is +much slower unless your machine has very fast floating-point hardware. Also +note that results of the floating-point method may vary slightly across +machines, while the integer methods should give the same results everywhere. +The fast integer method is much less accurate than the other two. +.TP +.BI \-restart " N" +Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is +attached to the number. +.B \-restart 0 +(the default) means no restart markers. +.TP +.BI \-smooth " N" +Smooth the input image to eliminate dithering noise. N, ranging from 1 to +100, indicates the strength of smoothing. 0 (the default) means no smoothing. +.TP +.BI \-maxmemory " N" +Set limit for amount of memory to use in processing large images. Value is +in thousands of bytes, or millions of bytes if "M" is attached to the +number. For example, +.B \-max 4m +selects 4000000 bytes. If more space is needed, temporary files will be used. +.TP +.BI \-outfile " name" +Send output image to the named file, not to standard output. +.TP +.B \-verbose +Enable debug printout. More +.BR \-v 's +give more output. Also, version information is printed at startup. +.TP +.B \-debug +Same as +.BR \-verbose . +.PP +The +.B \-restart +option inserts extra markers that allow a JPEG decoder to resynchronize after +a transmission error. Without restart markers, any damage to a compressed +file will usually ruin the image from the point of the error to the end of the +image; with restart markers, the damage is usually confined to the portion of +the image up to the next restart marker. Of course, the restart markers +occupy extra space. We recommend +.B \-restart 1 +for images that will be transmitted across unreliable networks such as Usenet. +.PP +The +.B \-smooth +option filters the input to eliminate fine-scale noise. This is often useful +when converting dithered images to JPEG: a moderate smoothing factor of 10 to +50 gets rid of dithering patterns in the input file, resulting in a smaller +JPEG file and a better-looking image. Too large a smoothing factor will +visibly blur the image, however. +.PP +Switches for wizards: +.TP +.B \-baseline +Force baseline-compatible quantization tables to be generated. This clamps +quantization values to 8 bits even at low quality settings. (This switch is +poorly named, since it does not ensure that the output is actually baseline +JPEG. For example, you can use +.B \-baseline +and +.B \-progressive +together.) +.TP +.BI \-qtables " file" +Use the quantization tables given in the specified text file. +.TP +.BI \-qslots " N[,...]" +Select which quantization table to use for each color component. +.TP +.BI \-sample " HxV[,...]" +Set JPEG sampling factors for each color component. +.TP +.BI \-scans " file" +Use the scan script given in the specified text file. +.PP +The "wizard" switches are intended for experimentation with JPEG. If you +don't know what you are doing, \fBdon't use them\fR. These switches are +documented further in the file wizard.doc. +.SH EXAMPLES +.LP +This example compresses the PPM file foo.ppm with a quality factor of +60 and saves the output as foo.jpg: +.IP +.B cjpeg \-quality +.I 60 foo.ppm +.B > +.I foo.jpg +.SH HINTS +Color GIF files are not the ideal input for JPEG; JPEG is really intended for +compressing full-color (24-bit) images. In particular, don't try to convert +cartoons, line drawings, and other images that have only a few distinct +colors. GIF works great on these, JPEG does not. If you want to convert a +GIF to JPEG, you should experiment with +.BR cjpeg 's +.B \-quality +and +.B \-smooth +options to get a satisfactory conversion. +.B \-smooth 10 +or so is often helpful. +.PP +Avoid running an image through a series of JPEG compression/decompression +cycles. Image quality loss will accumulate; after ten or so cycles the image +may be noticeably worse than it was after one cycle. It's best to use a +lossless format while manipulating an image, then convert to JPEG format when +you are ready to file the image away. +.PP +The +.B \-optimize +option to +.B cjpeg +is worth using when you are making a "final" version for posting or archiving. +It's also a win when you are using low quality settings to make very small +JPEG files; the percentage improvement is often a lot more than it is on +larger files. (At present, +.B \-optimize +mode is always selected when generating progressive JPEG files.) +.SH ENVIRONMENT +.TP +.B JPEGMEM +If this environment variable is set, its value is the default memory limit. +The value is specified as described for the +.B \-maxmemory +switch. +.B JPEGMEM +overrides the default value specified when the program was compiled, and +itself is overridden by an explicit +.BR \-maxmemory . +.SH SEE ALSO +.BR djpeg (1), +.BR jpegtran (1), +.BR rdjpgcom (1), +.BR wrjpgcom (1) +.br +.BR ppm (5), +.BR pgm (5) +.br +Wallace, Gregory K. "The JPEG Still Picture Compression Standard", +Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44. +.SH AUTHOR +Independent JPEG Group +.SH BUGS +Arithmetic coding is not supported for legal reasons. +.PP +GIF input files are no longer supported, to avoid the Unisys LZW patent. +Use a Unisys-licensed program if you need to read a GIF file. (Conversion +of GIF files to JPEG is usually a bad idea anyway.) +.PP +Not all variants of BMP and Targa file formats are supported. +.PP +The +.B \-targa +switch is not a bug, it's a feature. (It would be a bug if the Targa format +designers had not been clueless.) +.PP +Still not as fast as we'd like. diff --git a/src/dep/src/irrlicht/jpeglib/cjpeg.c b/src/dep/src/irrlicht/jpeglib/cjpeg.c new file mode 100644 index 0000000..b9102ee --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/cjpeg.c @@ -0,0 +1,606 @@ +/* + * cjpeg.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for the JPEG compressor. + * It should work on any system with Unix- or MS-DOS-style command lines. + * + * Two different command line styles are permitted, depending on the + * compile-time switch TWO_FILE_COMMANDLINE: + * cjpeg [options] inputfile outputfile + * cjpeg [options] [inputfile] + * In the second style, output is always to standard output, which you'd + * normally redirect to a file or pipe to some other program. Input is + * either from a named file or from standard input (typically redirected). + * The second style is convenient on Unix but is unhelpful on systems that + * don't support pipes. Also, you MUST use the first style if your system + * doesn't do binary I/O to stdin/stdout. + * To simplify script writing, the "-outfile" switch is provided. The syntax + * cjpeg [options] -outfile outputfile inputfile + * works regardless of which command line style is used. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "jversion.h" /* for version message */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* Create the add-on message string table. */ + +#define JMESSAGE(code,string) string , + +static const char * const cdjpeg_message_table[] = { +#include "cderror.h" + NULL +}; + + +/* + * This routine determines what format the input file is, + * and selects the appropriate input-reading module. + * + * To determine which family of input formats the file belongs to, + * we may look only at the first byte of the file, since C does not + * guarantee that more than one character can be pushed back with ungetc. + * Looking at additional bytes would require one of these approaches: + * 1) assume we can fseek() the input file (fails for piped input); + * 2) assume we can push back more than one character (works in + * some C implementations, but unportable); + * 3) provide our own buffering (breaks input readers that want to use + * stdio directly, such as the RLE library); + * or 4) don't put back the data, and modify the input_init methods to assume + * they start reading after the start of file (also breaks RLE library). + * #1 is attractive for MS-DOS but is untenable on Unix. + * + * The most portable solution for file types that can't be identified by their + * first byte is to make the user tell us what they are. This is also the + * only approach for "raw" file types that contain only arbitrary values. + * We presently apply this method for Targa files. Most of the time Targa + * files start with 0x00, so we recognize that case. Potentially, however, + * a Targa file could start with any byte value (byte 0 is the length of the + * seldom-used ID field), so we provide a switch to force Targa input mode. + */ + +static boolean is_targa; /* records user -targa switch */ + + +LOCAL(cjpeg_source_ptr) +select_file_type (j_compress_ptr cinfo, FILE * infile) +{ + int c; + + if (is_targa) { +#ifdef TARGA_SUPPORTED + return jinit_read_targa(cinfo); +#else + ERREXIT(cinfo, JERR_TGA_NOTCOMP); +#endif + } + + if ((c = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_INPUT_EMPTY); + if (ungetc(c, infile) == EOF) + ERREXIT(cinfo, JERR_UNGETC_FAILED); + + switch (c) { +#ifdef BMP_SUPPORTED + case 'B': + return jinit_read_bmp(cinfo); +#endif +#ifdef GIF_SUPPORTED + case 'G': + return jinit_read_gif(cinfo); +#endif +#ifdef PPM_SUPPORTED + case 'P': + return jinit_read_ppm(cinfo); +#endif +#ifdef RLE_SUPPORTED + case 'R': + return jinit_read_rle(cinfo); +#endif +#ifdef TARGA_SUPPORTED + case 0x00: + return jinit_read_targa(cinfo); +#endif + default: + ERREXIT(cinfo, JERR_UNKNOWN_FORMAT); + break; + } + + return NULL; /* suppress compiler warnings */ +} + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n"); + fprintf(stderr, " -grayscale Create monochrome JPEG file\n"); +#ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); +#endif +#ifdef C_PROGRESSIVE_SUPPORTED + fprintf(stderr, " -progressive Create progressive JPEG file\n"); +#endif +#ifdef TARGA_SUPPORTED + fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n"); +#endif + fprintf(stderr, "Switches for advanced users:\n"); +#ifdef DCT_ISLOW_SUPPORTED + fprintf(stderr, " -dct int Use integer DCT method%s\n", + (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); +#endif +#ifdef DCT_IFAST_SUPPORTED + fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", + (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); +#endif +#ifdef DCT_FLOAT_SUPPORTED + fprintf(stderr, " -dct float Use floating-point DCT method%s\n", + (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); +#endif + fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); +#ifdef INPUT_SMOOTHING_SUPPORTED + fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n"); +#endif + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + fprintf(stderr, "Switches for wizards:\n"); +#ifdef C_ARITH_CODING_SUPPORTED + fprintf(stderr, " -arithmetic Use arithmetic coding\n"); +#endif + fprintf(stderr, " -baseline Force baseline quantization tables\n"); + fprintf(stderr, " -qtables file Use quantization tables given in file\n"); + fprintf(stderr, " -qslots N[,...] Set component quantization tables\n"); + fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n"); +#ifdef C_MULTISCAN_FILES_SUPPORTED + fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); +#endif + exit(EXIT_FAILURE); +} + + +LOCAL(int) +parse_switches (j_compress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + int quality; /* -quality parameter */ + int q_scale_factor; /* scaling percentage for -qtables */ + boolean force_baseline; + boolean simple_progressive; + char * qtablefile = NULL; /* saves -qtables filename if any */ + char * qslotsarg = NULL; /* saves -qslots parm if any */ + char * samplearg = NULL; /* saves -sample parm if any */ + char * scansarg = NULL; /* saves -scans parm if any */ + + /* Set up default JPEG parameters. */ + /* Note that default -quality level need not, and does not, + * match the default scaling for an explicit -qtables argument. + */ + quality = 75; /* default -quality value */ + q_scale_factor = 100; /* default to no scaling for -qtables */ + force_baseline = FALSE; /* by default, allow 16-bit quantizers */ + simple_progressive = FALSE; + is_targa = FALSE; + outfilename = NULL; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "arithmetic", 1)) { + /* Use arithmetic coding. */ +#ifdef C_ARITH_CODING_SUPPORTED + cinfo->arith_code = TRUE; +#else + fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "baseline", 1)) { + /* Force baseline-compatible output (8-bit quantizer values). */ + force_baseline = TRUE; + + } else if (keymatch(arg, "dct", 2)) { + /* Select DCT algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "int", 1)) { + cinfo->dct_method = JDCT_ISLOW; + } else if (keymatch(argv[argn], "fast", 2)) { + cinfo->dct_method = JDCT_IFAST; + } else if (keymatch(argv[argn], "float", 2)) { + cinfo->dct_method = JDCT_FLOAT; + } else + usage(); + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { + /* Force a monochrome JPEG file to be generated. */ + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { + /* Enable entropy parm optimization. */ +#ifdef ENTROPY_OPT_SUPPORTED + cinfo->optimize_coding = TRUE; +#else + fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "progressive", 1)) { + /* Select simple progressive mode. */ +#ifdef C_PROGRESSIVE_SUPPORTED + simple_progressive = TRUE; + /* We must postpone execution until num_components is known. */ +#else + fprintf(stderr, "%s: sorry, progressive output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "quality", 1)) { + /* Quality factor (quantization table scaling factor). */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &quality) != 1) + usage(); + /* Change scale factor in case -qtables is present. */ + q_scale_factor = jpeg_quality_scaling(quality); + + } else if (keymatch(arg, "qslots", 2)) { + /* Quantization table slot numbers. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + qslotsarg = argv[argn]; + /* Must delay setting qslots until after we have processed any + * colorspace-determining switches, since jpeg_set_colorspace sets + * default quant table numbers. + */ + + } else if (keymatch(arg, "qtables", 2)) { + /* Quantization tables fetched from file. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + qtablefile = argv[argn]; + /* We postpone actually reading the file in case -quality comes later. */ + + } else if (keymatch(arg, "restart", 1)) { + /* Restart interval in MCU rows (or in MCUs with 'b'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (lval < 0 || lval > 65535L) + usage(); + if (ch == 'b' || ch == 'B') { + cinfo->restart_interval = (unsigned int) lval; + cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ + } else { + cinfo->restart_in_rows = (int) lval; + /* restart_interval will be computed during startup */ + } + + } else if (keymatch(arg, "sample", 2)) { + /* Set sampling factors. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + samplearg = argv[argn]; + /* Must delay setting sample factors until after we have processed any + * colorspace-determining switches, since jpeg_set_colorspace sets + * default sampling factors. + */ + + } else if (keymatch(arg, "scans", 2)) { + /* Set scan script. */ +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + scansarg = argv[argn]; + /* We must postpone reading the file in case -progressive appears. */ +#else + fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "smooth", 2)) { + /* Set input smoothing factor. */ + int val; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &val) != 1) + usage(); + if (val < 0 || val > 100) + usage(); + cinfo->smoothing_factor = val; + + } else if (keymatch(arg, "targa", 1)) { + /* Input file is Targa format. */ + is_targa = TRUE; + + } else { + usage(); /* bogus switch */ + } + } + + /* Post-switch-scanning cleanup */ + + if (for_real) { + + /* Set quantization tables for selected quality. */ + /* Some or all may be overridden if -qtables is present. */ + jpeg_set_quality(cinfo, quality, force_baseline); + + if (qtablefile != NULL) /* process -qtables if it was present */ + if (! read_quant_tables(cinfo, qtablefile, + q_scale_factor, force_baseline)) + usage(); + + if (qslotsarg != NULL) /* process -qslots if it was present */ + if (! set_quant_slots(cinfo, qslotsarg)) + usage(); + + if (samplearg != NULL) /* process -sample if it was present */ + if (! set_sample_factors(cinfo, samplearg)) + usage(); + +#ifdef C_PROGRESSIVE_SUPPORTED + if (simple_progressive) /* process -progressive; -scans can override */ + jpeg_simple_progression(cinfo); +#endif + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (scansarg != NULL) /* process -scans if it was present */ + if (! read_scan_script(cinfo, scansarg)) + usage(); +#endif + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + int file_index; + cjpeg_source_ptr src_mgr; + FILE * input_file; + FILE * output_file; + JDIMENSION num_scanlines; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "cjpeg"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG compression object with default error handling. */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + /* Add some application-specific error messages (from cderror.h) */ + jerr.addon_message_table = cdjpeg_message_table; + jerr.first_addon_message = JMSG_FIRSTADDONCODE; + jerr.last_addon_message = JMSG_LASTADDONCODE; + + /* Now safe to enable signal catcher. */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &cinfo); +#endif + + /* Initialize JPEG parameters. + * Much of this may be overridden later. + * In particular, we don't yet know the input file's color space, + * but we need to provide some value for jpeg_set_defaults() to work. + */ + + cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ + jpeg_set_defaults(&cinfo); + + /* Scan command line to find file names. + * It is convenient to use just one switch-parsing routine, but the switch + * values read here are ignored; we will rescan the switches after opening + * the input file. + */ + + file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &cinfo, &progress); +#endif + + /* Figure out the input file format, and set up to read it. */ + src_mgr = select_file_type(&cinfo, input_file); + src_mgr->input_file = input_file; + + /* Read the input file header to obtain file size & colorspace. */ + (*src_mgr->start_input) (&cinfo, src_mgr); + + /* Now that we know input colorspace, fix colorspace-dependent defaults */ + jpeg_default_colorspace(&cinfo); + + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ + jpeg_stdio_dest(&cinfo, output_file); + + /* Start compressor */ + jpeg_start_compress(&cinfo, TRUE); + + /* Process data */ + while (cinfo.next_scanline < cinfo.image_height) { + num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); + (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); + } + + /* Finish compression and release memory */ + (*src_mgr->finish_input) (&cinfo, src_mgr); + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &cinfo); +#endif + + /* All done. */ + exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/src/dep/src/irrlicht/jpeglib/ckconfig.c b/src/dep/src/irrlicht/jpeglib/ckconfig.c new file mode 100644 index 0000000..58e9c17 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/ckconfig.c @@ -0,0 +1,402 @@ +/* + * ckconfig.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + */ + +/* + * This program is intended to help you determine how to configure the JPEG + * software for installation on a particular system. The idea is to try to + * compile and execute this program. If your compiler fails to compile the + * program, make changes as indicated in the comments below. Once you can + * compile the program, run it, and it will produce a "jconfig.h" file for + * your system. + * + * As a general rule, each time you try to compile this program, + * pay attention only to the *first* error message you get from the compiler. + * Many C compilers will issue lots of spurious error messages once they + * have gotten confused. Go to the line indicated in the first error message, + * and read the comments preceding that line to see what to change. + * + * Almost all of the edits you may need to make to this program consist of + * changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL", + * or vice versa. This is called defining or undefining that symbol. + */ + + +/* First we must see if your system has the include files we need. + * We start out with the assumption that your system has all the ANSI-standard + * include files. If you get any error trying to include one of these files, + * undefine the corresponding HAVE_xxx symbol. + */ + +#define HAVE_STDDEF_H /* replace 'define' by 'undef' if error here */ +#ifdef HAVE_STDDEF_H /* next line will be skipped if you undef... */ +#include +#endif + +#define HAVE_STDLIB_H /* same thing for stdlib.h */ +#ifdef HAVE_STDLIB_H +#include +#endif + +#include /* If you ain't got this, you ain't got C. */ + +/* We have to see if your string functions are defined by + * strings.h (old BSD convention) or string.h (everybody else). + * We try the non-BSD convention first; define NEED_BSD_STRINGS + * if the compiler says it can't find string.h. + */ + +#undef NEED_BSD_STRINGS + +#ifdef NEED_BSD_STRINGS +#include +#else +#include +#endif + +/* On some systems (especially older Unix machines), type size_t is + * defined only in the include file . If you get a failure + * on the size_t test below, try defining NEED_SYS_TYPES_H. + */ + +#undef NEED_SYS_TYPES_H /* start by assuming we don't need it */ +#ifdef NEED_SYS_TYPES_H +#include +#endif + + +/* Usually type size_t is defined in one of the include files we've included + * above. If not, you'll get an error on the "typedef size_t my_size_t;" line. + * In that case, first try defining NEED_SYS_TYPES_H just above. + * If that doesn't work, you'll have to search through your system library + * to figure out which include file defines "size_t". Look for a line that + * says "typedef something-or-other size_t;". Then, change the line below + * that says "#include " to instead include the file + * you found size_t in, and define NEED_SPECIAL_INCLUDE. If you can't find + * type size_t anywhere, try replacing "#include " with + * "typedef unsigned int size_t;". + */ + +#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */ + +#ifdef NEED_SPECIAL_INCLUDE +#include +#endif + +typedef size_t my_size_t; /* The payoff: do we have size_t now? */ + + +/* The next question is whether your compiler supports ANSI-style function + * prototypes. You need to know this in order to choose between using + * makefile.ansi and using makefile.unix. + * The #define line below is set to assume you have ANSI function prototypes. + * If you get an error in this group of lines, undefine HAVE_PROTOTYPES. + */ + +#define HAVE_PROTOTYPES + +#ifdef HAVE_PROTOTYPES +int testfunction (int arg1, int * arg2); /* check prototypes */ + +struct methods_struct { /* check method-pointer declarations */ + int (*error_exit) (char *msgtext); + int (*trace_message) (char *msgtext); + int (*another_method) (void); +}; + +int testfunction (int arg1, int * arg2) /* check definitions */ +{ + return arg2[arg1]; +} + +int test2function (void) /* check void arg list */ +{ + return 0; +} +#endif + + +/* Now we want to find out if your compiler knows what "unsigned char" means. + * If you get an error on the "unsigned char un_char;" line, + * then undefine HAVE_UNSIGNED_CHAR. + */ + +#define HAVE_UNSIGNED_CHAR + +#ifdef HAVE_UNSIGNED_CHAR +unsigned char un_char; +#endif + + +/* Now we want to find out if your compiler knows what "unsigned short" means. + * If you get an error on the "unsigned short un_short;" line, + * then undefine HAVE_UNSIGNED_SHORT. + */ + +#define HAVE_UNSIGNED_SHORT + +#ifdef HAVE_UNSIGNED_SHORT +unsigned short un_short; +#endif + + +/* Now we want to find out if your compiler understands type "void". + * If you get an error anywhere in here, undefine HAVE_VOID. + */ + +#define HAVE_VOID + +#ifdef HAVE_VOID +/* Caution: a C++ compiler will insist on complete prototypes */ +typedef void * void_ptr; /* check void * */ +#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */ +typedef void (*void_func) (int a, int b); +#else +typedef void (*void_func) (); +#endif + +#ifdef HAVE_PROTOTYPES /* check void function result */ +void test3function (void_ptr arg1, void_func arg2) +#else +void test3function (arg1, arg2) + void_ptr arg1; + void_func arg2; +#endif +{ + char * locptr = (char *) arg1; /* check casting to and from void * */ + arg1 = (void *) locptr; + (*arg2) (1, 2); /* check call of fcn returning void */ +} +#endif + + +/* Now we want to find out if your compiler knows what "const" means. + * If you get an error here, undefine HAVE_CONST. + */ + +#define HAVE_CONST + +#ifdef HAVE_CONST +static const int carray[3] = {1, 2, 3}; + +#ifdef HAVE_PROTOTYPES +int test4function (const int arg1) +#else +int test4function (arg1) + const int arg1; +#endif +{ + return carray[arg1]; +} +#endif + + +/* If you get an error or warning about this structure definition, + * define INCOMPLETE_TYPES_BROKEN. + */ + +#undef INCOMPLETE_TYPES_BROKEN + +#ifndef INCOMPLETE_TYPES_BROKEN +typedef struct undefined_structure * undef_struct_ptr; +#endif + + +/* If you get an error about duplicate names, + * define NEED_SHORT_EXTERNAL_NAMES. + */ + +#undef NEED_SHORT_EXTERNAL_NAMES + +#ifndef NEED_SHORT_EXTERNAL_NAMES + +int possibly_duplicate_function () +{ + return 0; +} + +int possibly_dupli_function () +{ + return 1; +} + +#endif + + + +/************************************************************************ + * OK, that's it. You should not have to change anything beyond this + * point in order to compile and execute this program. (You might get + * some warnings, but you can ignore them.) + * When you run the program, it will make a couple more tests that it + * can do automatically, and then it will create jconfig.h and print out + * any additional suggestions it has. + ************************************************************************ + */ + + +#ifdef HAVE_PROTOTYPES +int is_char_signed (int arg) +#else +int is_char_signed (arg) + int arg; +#endif +{ + if (arg == 189) { /* expected result for unsigned char */ + return 0; /* type char is unsigned */ + } + else if (arg != -67) { /* expected result for signed char */ + printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n"); + printf("I fear the JPEG software will not work at all.\n\n"); + } + return 1; /* assume char is signed otherwise */ +} + + +#ifdef HAVE_PROTOTYPES +int is_shifting_signed (long arg) +#else +int is_shifting_signed (arg) + long arg; +#endif +/* See whether right-shift on a long is signed or not. */ +{ + long res = arg >> 4; + + if (res == -0x7F7E80CL) { /* expected result for signed shift */ + return 1; /* right shift is signed */ + } + /* see if unsigned-shift hack will fix it. */ + /* we can't just test exact value since it depends on width of long... */ + res |= (~0L) << (32-4); + if (res == -0x7F7E80CL) { /* expected result now? */ + return 0; /* right shift is unsigned */ + } + printf("Right shift isn't acting as I expect it to.\n"); + printf("I fear the JPEG software will not work at all.\n\n"); + return 0; /* try it with unsigned anyway */ +} + + +#ifdef HAVE_PROTOTYPES +int main (int argc, char ** argv) +#else +int main (argc, argv) + int argc; + char ** argv; +#endif +{ + char signed_char_check = (char) (-67); + FILE *outfile; + + /* Attempt to write jconfig.h */ + if ((outfile = fopen("jconfig.h", "w")) == NULL) { + printf("Failed to write jconfig.h\n"); + return 1; + } + + /* Write out all the info */ + fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n"); + fprintf(outfile, "/* see jconfig.doc for explanations */\n\n"); +#ifdef HAVE_PROTOTYPES + fprintf(outfile, "#define HAVE_PROTOTYPES\n"); +#else + fprintf(outfile, "#undef HAVE_PROTOTYPES\n"); +#endif +#ifdef HAVE_UNSIGNED_CHAR + fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n"); +#else + fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n"); +#endif +#ifdef HAVE_UNSIGNED_SHORT + fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n"); +#else + fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n"); +#endif +#ifdef HAVE_VOID + fprintf(outfile, "/* #define void char */\n"); +#else + fprintf(outfile, "#define void char\n"); +#endif +#ifdef HAVE_CONST + fprintf(outfile, "/* #define const */\n"); +#else + fprintf(outfile, "#define const\n"); +#endif + if (is_char_signed((int) signed_char_check)) + fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n"); + else + fprintf(outfile, "#define CHAR_IS_UNSIGNED\n"); +#ifdef HAVE_STDDEF_H + fprintf(outfile, "#define HAVE_STDDEF_H\n"); +#else + fprintf(outfile, "#undef HAVE_STDDEF_H\n"); +#endif +#ifdef HAVE_STDLIB_H + fprintf(outfile, "#define HAVE_STDLIB_H\n"); +#else + fprintf(outfile, "#undef HAVE_STDLIB_H\n"); +#endif +#ifdef NEED_BSD_STRINGS + fprintf(outfile, "#define NEED_BSD_STRINGS\n"); +#else + fprintf(outfile, "#undef NEED_BSD_STRINGS\n"); +#endif +#ifdef NEED_SYS_TYPES_H + fprintf(outfile, "#define NEED_SYS_TYPES_H\n"); +#else + fprintf(outfile, "#undef NEED_SYS_TYPES_H\n"); +#endif + fprintf(outfile, "#undef NEED_FAR_POINTERS\n"); +#ifdef NEED_SHORT_EXTERNAL_NAMES + fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n"); +#else + fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n"); +#endif +#ifdef INCOMPLETE_TYPES_BROKEN + fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n"); +#else + fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n"); +#endif + fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n"); + if (is_shifting_signed(-0x7F7E80B1L)) + fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n"); + else + fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n"); + fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n"); + fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n"); + fprintf(outfile, "#define BMP_SUPPORTED /* BMP image file format */\n"); + fprintf(outfile, "#define GIF_SUPPORTED /* GIF image file format */\n"); + fprintf(outfile, "#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */\n"); + fprintf(outfile, "#undef RLE_SUPPORTED /* Utah RLE image file format */\n"); + fprintf(outfile, "#define TARGA_SUPPORTED /* Targa image file format */\n\n"); + fprintf(outfile, "#undef TWO_FILE_COMMANDLINE /* You may need this on non-Unix systems */\n"); + fprintf(outfile, "#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */\n"); + fprintf(outfile, "#undef DONT_USE_B_MODE\n"); + fprintf(outfile, "/* #define PROGRESS_REPORT */ /* optional */\n"); + fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n"); + + /* Close the jconfig.h file */ + fclose(outfile); + + /* User report */ + printf("Configuration check for Independent JPEG Group's software done.\n"); + printf("\nI have written the jconfig.h file for you.\n\n"); +#ifdef HAVE_PROTOTYPES + printf("You should use makefile.ansi as the starting point for your Makefile.\n"); +#else + printf("You should use makefile.unix as the starting point for your Makefile.\n"); +#endif + +#ifdef NEED_SPECIAL_INCLUDE + printf("\nYou'll need to change jconfig.h to include the system include file\n"); + printf("that you found type size_t in, or add a direct definition of type\n"); + printf("size_t if that's what you used. Just add it to the end.\n"); +#endif + + return 0; +} diff --git a/src/dep/src/irrlicht/jpeglib/coderules.doc b/src/dep/src/irrlicht/jpeglib/coderules.doc new file mode 100644 index 0000000..2c56534 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/coderules.doc @@ -0,0 +1,118 @@ +IJG JPEG LIBRARY: CODING RULES + +Copyright (C) 1991-1996, Thomas G. Lane. +This file is part of the Independent JPEG Group's software. +For conditions of distribution and use, see the accompanying README file. + + +Since numerous people will be contributing code and bug fixes, it's important +to establish a common coding style. The goal of using similar coding styles +is much more important than the details of just what that style is. + +In general we follow the recommendations of "Recommended C Style and Coding +Standards" revision 6.1 (Cannon et al. as modified by Spencer, Keppel and +Brader). This document is available in the IJG FTP archive (see +jpeg/doc/cstyle.ms.tbl.Z, or cstyle.txt.Z for those without nroff/tbl). + +Block comments should be laid out thusly: + +/* + * Block comments in this style. + */ + +We indent statements in K&R style, e.g., + if (test) { + then-part; + } else { + else-part; + } +with two spaces per indentation level. (This indentation convention is +handled automatically by GNU Emacs and many other text editors.) + +Multi-word names should be written in lower case with underscores, e.g., +multi_word_name (not multiWordName). Preprocessor symbols and enum constants +are similar but upper case (MULTI_WORD_NAME). Names should be unique within +the first fifteen characters. (On some older systems, global names must be +unique within six characters. We accommodate this without cluttering the +source code by using macros to substitute shorter names.) + +We use function prototypes everywhere; we rely on automatic source code +transformation to feed prototype-less C compilers. Transformation is done +by the simple and portable tool 'ansi2knr.c' (courtesy of Ghostscript). +ansi2knr is not very bright, so it imposes a format requirement on function +declarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions +should be written in the following style: + +LOCAL(int *) +function_name (int a, char *b) +{ + code... +} + +Note that each function definition must begin with GLOBAL(type), LOCAL(type), +or METHODDEF(type). These macros expand to "static type" or just "type" as +appropriate. They provide a readable indication of the routine's usage and +can readily be changed for special needs. (For instance, special linkage +keywords can be inserted for use in Windows DLLs.) + +ansi2knr does not transform method declarations (function pointers in +structs). We handle these with a macro JMETHOD, defined as + #ifdef HAVE_PROTOTYPES + #define JMETHOD(type,methodname,arglist) type (*methodname) arglist + #else + #define JMETHOD(type,methodname,arglist) type (*methodname) () + #endif +which is used like this: + struct function_pointers { + JMETHOD(void, init_entropy_encoder, (int somearg, jparms *jp)); + JMETHOD(void, term_entropy_encoder, (void)); + }; +Note the set of parentheses surrounding the parameter list. + +A similar solution is used for forward and external function declarations +(see the EXTERN and JPP macros). + +If the code is to work on non-ANSI compilers, we cannot rely on a prototype +declaration to coerce actual parameters into the right types. Therefore, use +explicit casts on actual parameters whenever the actual parameter type is not +identical to the formal parameter. Beware of implicit conversions to "int". + +It seems there are some non-ANSI compilers in which the sizeof() operator +is defined to return int, yet size_t is defined as long. Needless to say, +this is brain-damaged. Always use the SIZEOF() macro in place of sizeof(), +so that the result is guaranteed to be of type size_t. + + +The JPEG library is intended to be used within larger programs. Furthermore, +we want it to be reentrant so that it can be used by applications that process +multiple images concurrently. The following rules support these requirements: + +1. Avoid direct use of file I/O, "malloc", error report printouts, etc; +pass these through the common routines provided. + +2. Minimize global namespace pollution. Functions should be declared static +wherever possible. (Note that our method-based calling conventions help this +a lot: in many modules only the initialization function will ever need to be +called directly, so only that function need be externally visible.) All +global function names should begin with "jpeg_", and should have an +abbreviated name (unique in the first six characters) substituted by macro +when NEED_SHORT_EXTERNAL_NAMES is set. + +3. Don't use global variables; anything that must be used in another module +should be in the common data structures. + +4. Don't use static variables except for read-only constant tables. Variables +that should be private to a module can be placed into private structures (see +the system architecture document, structure.doc). + +5. Source file names should begin with "j" for files that are part of the +library proper; source files that are not part of the library, such as cjpeg.c +and djpeg.c, do not begin with "j". Keep source file names to eight +characters (plus ".c" or ".h", etc) to make life easy for MS-DOSers. Keep +compression and decompression code in separate source files --- some +applications may want only one half of the library. + +Note: these rules (particularly #4) are not followed religiously in the +modules that are used in cjpeg/djpeg but are not part of the JPEG library +proper. Those modules are not really intended to be used in other +applications. diff --git a/src/dep/src/irrlicht/jpeglib/config.guess b/src/dep/src/irrlicht/jpeglib/config.guess new file mode 100644 index 0000000..f60829f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/config.guess @@ -0,0 +1,883 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo i386-pc-cygwin32 + exit 0 ;; + i*:MINGW*:*) + echo i386-pc-mingw32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin32 + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >dummy.c < +main(argc, argv) + int argc; + char *argv[]; +{ +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/src/dep/src/irrlicht/jpeglib/config.sub b/src/dep/src/irrlicht/jpeglib/config.sub new file mode 100644 index 0000000..fe5c364 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/config.sub @@ -0,0 +1,954 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 \ + | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ + | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ + | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ + | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ + | mipstx39 | mipstx39el \ + | sparc | sparclet | sparclite | sparc64 | v850) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[3456]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ + | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \ + | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ + | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mipstx39-* | mipstx39el-* \ + | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[3456]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[3456]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[3456]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[3456]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5) + basic_machine=i586-intel + ;; + pentiumpro | p6) + basic_machine=i686-intel + ;; + pentium-* | p5-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/src/dep/src/irrlicht/jpeglib/configure b/src/dep/src/irrlicht/jpeglib/configure new file mode 100644 index 0000000..d3239e7 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/configure @@ -0,0 +1,2011 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-shared build shared library using GNU libtool" +ac_help="$ac_help + --enable-static build static library using GNU libtool" +ac_help="$ac_help + --enable-maxmem[=N] enable use of temp files, set max mem usage to N MB" +ac_help="$ac_help +" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *=*) + varname=`echo "$ac_option"|sed -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $varname| sed 's/[a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $varname: invalid shell variable name" 1>&2; exit 1; } + fi + val="`echo "$ac_option"|sed 's/[^=]*=//'`" + test -n "$verbose" && echo " setting shell variable $varname to $val" + eval "$varname='$val'" + eval "export $varname" ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=jcmaster.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:538: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:567: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:615: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:649: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:654: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + test "${CFLAGS+set}" = set || CFLAGS="-O2" +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-O" +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:681: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:719: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for function prototypes""... $ac_c" 1>&6 +echo "configure:742: checking for function prototypes" >&5 +if eval "test \"`echo '$''{'ijg_cv_have_prototypes'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ijg_cv_have_prototypes=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ijg_cv_have_prototypes=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ijg_cv_have_prototypes" 1>&6 +if test $ijg_cv_have_prototypes = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_PROTOTYPES +EOF + +else + echo Your compiler does not seem to know about function prototypes. + echo Perhaps it needs a special switch to enable ANSI C mode. + echo If so, we recommend running configure like this: + echo " ./configure CC='cc -switch'" + echo where -switch is the proper switch. +fi +ac_safe=`echo "stddef.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for stddef.h""... $ac_c" 1>&6 +echo "configure:792: checking for stddef.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STDDEF_H +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6 +echo "configure:828: checking for stdlib.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_STDLIB_H +EOF + +else + echo "$ac_t""no" 1>&6 +fi + +ac_safe=`echo "string.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for string.h""... $ac_c" 1>&6 +echo "configure:864: checking for string.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:874: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define NEED_BSD_STRINGS +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:900: checking for size_t" >&5 +cat > conftest.$ac_ext < +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#ifdef NEED_BSD_STRINGS +#include +#else +#include +#endif +typedef size_t my_size_t; + +int main() { + my_size_t foovar; +; return 0; } +EOF +if { (eval echo configure:923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ijg_size_t_ok=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ijg_size_t_ok="not ANSI, perhaps it is in sys/types.h" +fi +rm -f conftest* +echo "$ac_t""$ijg_size_t_ok" 1>&6 +if test "$ijg_size_t_ok" != yes; then +ac_safe=`echo "sys/types.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for sys/types.h""... $ac_c" 1>&6 +echo "configure:937: checking for sys/types.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define NEED_SYS_TYPES_H +EOF + +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t" >/dev/null 2>&1; then + rm -rf conftest* + ijg_size_t_ok="size_t is in sys/types.h" +else + rm -rf conftest* + ijg_size_t_ok=no +fi +rm -f conftest* + +else + echo "$ac_t""no" 1>&6 +ijg_size_t_ok=no +fi + +echo "$ac_t""$ijg_size_t_ok" 1>&6 +if test "$ijg_size_t_ok" = no; then + echo Type size_t is not defined in any of the usual places. + echo Try putting '"typedef unsigned int size_t;"' in jconfig.h. +fi +fi +echo $ac_n "checking for type unsigned char""... $ac_c" 1>&6 +echo "configure:994: checking for type unsigned char" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +cat >> confdefs.h <<\EOF +#define HAVE_UNSIGNED_CHAR +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* +echo $ac_n "checking for type unsigned short""... $ac_c" 1>&6 +echo "configure:1018: checking for type unsigned short" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +cat >> confdefs.h <<\EOF +#define HAVE_UNSIGNED_SHORT +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* +echo $ac_n "checking for type void""... $ac_c" 1>&6 +echo "configure:1042: checking for type void" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define void char +EOF + +fi +rm -f conftest* + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:1088: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:1142: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:1163: checking for inline" >&5 +ijg_cv_inline="" +cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ijg_cv_inline="__inline__" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ijg_cv_inline="__inline" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ijg_cv_inline="inline" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* +echo "$ac_t""$ijg_cv_inline" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1224: checking for broken incomplete types" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""ok" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""broken" 1>&6 +cat >> confdefs.h <<\EOF +#define INCOMPLETE_TYPES_BROKEN +EOF + +fi +rm -f conftest* +echo $ac_n "checking for short external names""... $ac_c" 1>&6 +echo "configure:1248: checking for short external names" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + echo "$ac_t""ok" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""short" 1>&6 +cat >> confdefs.h <<\EOF +#define NEED_SHORT_EXTERNAL_NAMES +EOF + +fi +rm -f conftest* +echo $ac_n "checking to see if char is signed""... $ac_c" 1>&6 +echo "configure:1275: checking to see if char is signed" >&5 +if test "$cross_compiling" = yes; then + echo Assuming that char is signed on target machine. +echo If it is unsigned, this will be a little bit inefficient. + +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define CHAR_IS_UNSIGNED +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + echo "$ac_t""yes" 1>&6 +fi +rm -fr conftest* +fi + +echo $ac_n "checking to see if right shift is signed""... $ac_c" 1>&6 +echo "configure:1323: checking to see if right shift is signed" >&5 +if test "$cross_compiling" = yes; then + echo "$ac_t""Assuming that right shift is signed on target machine." 1>&6 +else + cat > conftest.$ac_ext <> 4; + + if (res == -0x7F7E80CL) { /* expected result for signed shift */ + return 1; /* right shift is signed */ + } + /* see if unsigned-shift hack will fix it. */ + /* we can't just test exact value since it depends on width of long... */ + res |= (~0L) << (32-4); + if (res == -0x7F7E80CL) { /* expected result now? */ + return 0; /* right shift is unsigned */ + } + printf("Right shift isn't acting as I expect it to.\n"); + printf("I fear the JPEG software will not work at all.\n\n"); + return 0; /* try it with unsigned anyway */ +} +main() { + exit(is_shifting_signed(-0x7F7E80B1L)); +} +EOF +if { (eval echo configure:1358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define RIGHT_SHIFT_IS_UNSIGNED +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + echo "$ac_t""yes" 1>&6 +fi +rm -fr conftest* +fi + +echo $ac_n "checking to see if fopen accepts b spec""... $ac_c" 1>&6 +echo "configure:1375: checking to see if fopen accepts b spec" >&5 +if test "$cross_compiling" = yes; then + echo "$ac_t""Assuming that it does." 1>&6 +else + cat > conftest.$ac_ext < +main() { + if (fopen("conftestdata", "wb") != NULL) + exit(0); + exit(1); +} +EOF +if { (eval echo configure:1390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define DONT_USE_B_MODE +EOF + +fi +rm -fr conftest* +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1436: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1488: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Decide whether to use libtool, +# and if so whether to build shared, static, or both flavors of library. +LTSHARED="no" +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + LTSHARED="$enableval" +fi + +LTSTATIC="no" +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + LTSTATIC="$enableval" +fi + +if test "x$LTSHARED" != xno -o "x$LTSTATIC" != xno; then + USELIBTOOL="yes" + LIBTOOL="./libtool" + O="lo" + A="la" + LN='$(LIBTOOL) --mode=link $(CC)' + INSTALL_LIB='$(LIBTOOL) --mode=install ${INSTALL}' + INSTALL_PROGRAM="\$(LIBTOOL) --mode=install $INSTALL_PROGRAM" +else + USELIBTOOL="no" + LIBTOOL="" + O="o" + A="a" + LN='$(CC)' + INSTALL_LIB="$INSTALL_DATA" +fi + + + + + + +# Configure libtool if needed. +if test $USELIBTOOL = yes; then + disable_shared= + disable_static= + if test "x$LTSHARED" = xno; then + disable_shared="--disable-shared" + fi + if test "x$LTSTATIC" = xno; then + disable_static="--disable-static" + fi + $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh +fi + +# Select memory manager depending on user input. +# If no "-enable-maxmem", use jmemnobs +MEMORYMGR='jmemnobs.$(O)' +MAXMEM="no" +# Check whether --enable-maxmem or --disable-maxmem was given. +if test "${enable_maxmem+set}" = set; then + enableval="$enable_maxmem" + MAXMEM="$enableval" +fi + +# support --with-maxmem for backwards compatibility with IJG V5. +# Check whether --with-maxmem or --without-maxmem was given. +if test "${with_maxmem+set}" = set; then + withval="$with_maxmem" + MAXMEM="$withval" +fi + +if test "x$MAXMEM" = xyes; then + MAXMEM=1 +fi +if test "x$MAXMEM" != xno; then + if test -n "`echo $MAXMEM | sed 's/[0-9]//g'`"; then + { echo "configure: error: non-numeric argument to --enable-maxmem" 1>&2; exit 1; } + fi + DEFAULTMAXMEM=`expr $MAXMEM \* 1048576` +cat >> confdefs.h <&6 +echo "configure:1596: checking for 'tmpfile()'" >&5 +cat > conftest.$ac_ext < +int main() { + FILE * tfile = tmpfile(); +; return 0; } +EOF +if { (eval echo configure:1605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +MEMORYMGR='jmemansi.$(O)' +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +MEMORYMGR='jmemname.$(O)' +cat >> confdefs.h <<\EOF +#define NEED_SIGNAL_CATCHER +EOF + +echo $ac_n "checking for 'mktemp()'""... $ac_c" 1>&6 +echo "configure:1620: checking for 'mktemp()'" >&5 +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define NO_MKTEMP +EOF + +fi +rm -f conftest* +fi +rm -f conftest* +fi + + +# Extract the library version ID from jpeglib.h. +echo $ac_n "checking libjpeg version number""... $ac_c" 1>&6 +echo "configure:1650: checking libjpeg version number" >&5 +JPEG_LIB_VERSION=`sed -e '/^#define JPEG_LIB_VERSION/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h` +echo "$ac_t""$JPEG_LIB_VERSION" 1>&6 + + +# Prepare to massage makefile.cfg correctly. +if test $ijg_cv_have_prototypes = yes; then + A2K_DEPS="" + COM_A2K="# " +else + A2K_DEPS="ansi2knr" + COM_A2K="" +fi + + +# ansi2knr needs -DBSD if string.h is missing +if test $ac_cv_header_string_h = no; then + ANSI2KNRFLAGS="-DBSD" +else + ANSI2KNRFLAGS="" +fi + +# Substitutions to enable or disable libtool-related stuff +if test $USELIBTOOL = yes -a $ijg_cv_have_prototypes = yes; then + COM_LT="" +else + COM_LT="# " +fi + +if test "x$LTSHARED" != xno; then + FORCE_INSTALL_LIB="install-lib" +else + FORCE_INSTALL_LIB="" +fi + +# Set up -I directives +if test "x$srcdir" = x.; then + INCLUDEFLAGS='-I$(srcdir)' +else + INCLUDEFLAGS='-I. -I$(srcdir)' +fi + +trap '' 1 2 15 + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile:makefile.cfg jconfig.h:jconfig.cfg" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@RANLIB@%$RANLIB%g +s%@LIBTOOL@%$LIBTOOL%g +s%@O@%$O%g +s%@A@%$A%g +s%@LN@%$LN%g +s%@INSTALL_LIB@%$INSTALL_LIB%g +s%@MEMORYMGR@%$MEMORYMGR%g +s%@JPEG_LIB_VERSION@%$JPEG_LIB_VERSION%g +s%@A2K_DEPS@%$A2K_DEPS%g +s%@COM_A2K@%$COM_A2K%g +s%@ANSI2KNRFLAGS@%$ANSI2KNRFLAGS%g +s%@COM_LT@%$COM_LT%g +s%@FORCE_INSTALL_LIB@%$FORCE_INSTALL_LIB%g +s%@INCLUDEFLAGS@%$INCLUDEFLAGS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/src/dep/src/irrlicht/jpeglib/djpeg.1 b/src/dep/src/irrlicht/jpeglib/djpeg.1 new file mode 100644 index 0000000..a1a335a --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/djpeg.1 @@ -0,0 +1,253 @@ +.TH DJPEG 1 "22 August 1997" +.SH NAME +djpeg \- decompress a JPEG file to an image file +.SH SYNOPSIS +.B djpeg +[ +.I options +] +[ +.I filename +] +.LP +.SH DESCRIPTION +.LP +.B djpeg +decompresses the named JPEG file, or the standard input if no file is named, +and produces an image file on the standard output. PBMPLUS (PPM/PGM), BMP, +GIF, Targa, or RLE (Utah Raster Toolkit) output format can be selected. +(RLE is supported only if the URT library is available.) +.SH OPTIONS +All switch names may be abbreviated; for example, +.B \-grayscale +may be written +.B \-gray +or +.BR \-gr . +Most of the "basic" switches can be abbreviated to as little as one letter. +Upper and lower case are equivalent (thus +.B \-BMP +is the same as +.BR \-bmp ). +British spellings are also accepted (e.g., +.BR \-greyscale ), +though for brevity these are not mentioned below. +.PP +The basic switches are: +.TP +.BI \-colors " N" +Reduce image to at most N colors. This reduces the number of colors used in +the output image, so that it can be displayed on a colormapped display or +stored in a colormapped file format. For example, if you have an 8-bit +display, you'd need to reduce to 256 or fewer colors. +.TP +.BI \-quantize " N" +Same as +.BR \-colors . +.B \-colors +is the recommended name, +.B \-quantize +is provided only for backwards compatibility. +.TP +.B \-fast +Select recommended processing options for fast, low quality output. (The +default options are chosen for highest quality output.) Currently, this is +equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR. +.TP +.B \-grayscale +Force gray-scale output even if JPEG file is color. Useful for viewing on +monochrome displays; also, +.B djpeg +runs noticeably faster in this mode. +.TP +.BI \-scale " M/N" +Scale the output image by a factor M/N. Currently the scale factor must be +1/1, 1/2, 1/4, or 1/8. Scaling is handy if the image is larger than your +screen; also, +.B djpeg +runs much faster when scaling down the output. +.TP +.B \-bmp +Select BMP output format (Windows flavor). 8-bit colormapped format is +emitted if +.B \-colors +or +.B \-grayscale +is specified, or if the JPEG file is gray-scale; otherwise, 24-bit full-color +format is emitted. +.TP +.B \-gif +Select GIF output format. Since GIF does not support more than 256 colors, +.B \-colors 256 +is assumed (unless you specify a smaller number of colors). +.TP +.B \-os2 +Select BMP output format (OS/2 1.x flavor). 8-bit colormapped format is +emitted if +.B \-colors +or +.B \-grayscale +is specified, or if the JPEG file is gray-scale; otherwise, 24-bit full-color +format is emitted. +.TP +.B \-pnm +Select PBMPLUS (PPM/PGM) output format (this is the default format). +PGM is emitted if the JPEG file is gray-scale or if +.B \-grayscale +is specified; otherwise PPM is emitted. +.TP +.B \-rle +Select RLE output format. (Requires URT library.) +.TP +.B \-targa +Select Targa output format. Gray-scale format is emitted if the JPEG file is +gray-scale or if +.B \-grayscale +is specified; otherwise, colormapped format is emitted if +.B \-colors +is specified; otherwise, 24-bit full-color format is emitted. +.PP +Switches for advanced users: +.TP +.B \-dct int +Use integer DCT method (default). +.TP +.B \-dct fast +Use fast integer DCT (less accurate). +.TP +.B \-dct float +Use floating-point DCT method. +The float method is very slightly more accurate than the int method, but is +much slower unless your machine has very fast floating-point hardware. Also +note that results of the floating-point method may vary slightly across +machines, while the integer methods should give the same results everywhere. +The fast integer method is much less accurate than the other two. +.TP +.B \-dither fs +Use Floyd-Steinberg dithering in color quantization. +.TP +.B \-dither ordered +Use ordered dithering in color quantization. +.TP +.B \-dither none +Do not use dithering in color quantization. +By default, Floyd-Steinberg dithering is applied when quantizing colors; this +is slow but usually produces the best results. Ordered dither is a compromise +between speed and quality; no dithering is fast but usually looks awful. Note +that these switches have no effect unless color quantization is being done. +Ordered dither is only available in +.B \-onepass +mode. +.TP +.BI \-map " file" +Quantize to the colors used in the specified image file. This is useful for +producing multiple files with identical color maps, or for forcing a +predefined set of colors to be used. The +.I file +must be a GIF or PPM file. This option overrides +.B \-colors +and +.BR \-onepass . +.TP +.B \-nosmooth +Use a faster, lower-quality upsampling routine. +.TP +.B \-onepass +Use one-pass instead of two-pass color quantization. The one-pass method is +faster and needs less memory, but it produces a lower-quality image. +.B \-onepass +is ignored unless you also say +.B \-colors +.IR N . +Also, the one-pass method is always used for gray-scale output (the two-pass +method is no improvement then). +.TP +.BI \-maxmemory " N" +Set limit for amount of memory to use in processing large images. Value is +in thousands of bytes, or millions of bytes if "M" is attached to the +number. For example, +.B \-max 4m +selects 4000000 bytes. If more space is needed, temporary files will be used. +.TP +.BI \-outfile " name" +Send output image to the named file, not to standard output. +.TP +.B \-verbose +Enable debug printout. More +.BR \-v 's +give more output. Also, version information is printed at startup. +.TP +.B \-debug +Same as +.BR \-verbose . +.SH EXAMPLES +.LP +This example decompresses the JPEG file foo.jpg, quantizes it to +256 colors, and saves the output in 8-bit BMP format in foo.bmp: +.IP +.B djpeg \-colors 256 \-bmp +.I foo.jpg +.B > +.I foo.bmp +.SH HINTS +To get a quick preview of an image, use the +.B \-grayscale +and/or +.B \-scale +switches. +.B \-grayscale \-scale 1/8 +is the fastest case. +.PP +Several options are available that trade off image quality to gain speed. +.B \-fast +turns on the recommended settings. +.PP +.B \-dct fast +and/or +.B \-nosmooth +gain speed at a small sacrifice in quality. +When producing a color-quantized image, +.B \-onepass \-dither ordered +is fast but much lower quality than the default behavior. +.B \-dither none +may give acceptable results in two-pass mode, but is seldom tolerable in +one-pass mode. +.PP +If you are fortunate enough to have very fast floating point hardware, +\fB\-dct float\fR may be even faster than \fB\-dct fast\fR. But on most +machines \fB\-dct float\fR is slower than \fB\-dct int\fR; in this case it is +not worth using, because its theoretical accuracy advantage is too small to be +significant in practice. +.SH ENVIRONMENT +.TP +.B JPEGMEM +If this environment variable is set, its value is the default memory limit. +The value is specified as described for the +.B \-maxmemory +switch. +.B JPEGMEM +overrides the default value specified when the program was compiled, and +itself is overridden by an explicit +.BR \-maxmemory . +.SH SEE ALSO +.BR cjpeg (1), +.BR jpegtran (1), +.BR rdjpgcom (1), +.BR wrjpgcom (1) +.br +.BR ppm (5), +.BR pgm (5) +.br +Wallace, Gregory K. "The JPEG Still Picture Compression Standard", +Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44. +.SH AUTHOR +Independent JPEG Group +.SH BUGS +Arithmetic coding is not supported for legal reasons. +.PP +To avoid the Unisys LZW patent, +.B djpeg +produces uncompressed GIF files. These are larger than they should be, but +are readable by standard GIF decoders. +.PP +Still not as fast as we'd like. diff --git a/src/dep/src/irrlicht/jpeglib/djpeg.c b/src/dep/src/irrlicht/jpeglib/djpeg.c new file mode 100644 index 0000000..a63523c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/djpeg.c @@ -0,0 +1,616 @@ +/* + * djpeg.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for the JPEG decompressor. + * It should work on any system with Unix- or MS-DOS-style command lines. + * + * Two different command line styles are permitted, depending on the + * compile-time switch TWO_FILE_COMMANDLINE: + * djpeg [options] inputfile outputfile + * djpeg [options] [inputfile] + * In the second style, output is always to standard output, which you'd + * normally redirect to a file or pipe to some other program. Input is + * either from a named file or from standard input (typically redirected). + * The second style is convenient on Unix but is unhelpful on systems that + * don't support pipes. Also, you MUST use the first style if your system + * doesn't do binary I/O to stdin/stdout. + * To simplify script writing, the "-outfile" switch is provided. The syntax + * djpeg [options] -outfile outputfile inputfile + * works regardless of which command line style is used. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "jversion.h" /* for version message */ + +#include /* to declare isprint() */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* Create the add-on message string table. */ + +#define JMESSAGE(code,string) string , + +static const char * const cdjpeg_message_table[] = { +#include "cderror.h" + NULL +}; + + +/* + * This list defines the known output image formats + * (not all of which need be supported by a given version). + * You can change the default output format by defining DEFAULT_FMT; + * indeed, you had better do so if you undefine PPM_SUPPORTED. + */ + +typedef enum { + FMT_BMP, /* BMP format (Windows flavor) */ + FMT_GIF, /* GIF format */ + FMT_OS2, /* BMP format (OS/2 flavor) */ + FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ + FMT_RLE, /* RLE format */ + FMT_TARGA, /* Targa format */ + FMT_TIFF /* TIFF format */ +} IMAGE_FORMATS; + +#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ +#define DEFAULT_FMT FMT_PPM +#endif + +static IMAGE_FORMATS requested_fmt; + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); + fprintf(stderr, " -fast Fast, low-quality processing\n"); + fprintf(stderr, " -grayscale Force grayscale output\n"); +#ifdef IDCT_SCALING_SUPPORTED + fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); +#endif +#ifdef BMP_SUPPORTED + fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n", + (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); +#endif +#ifdef GIF_SUPPORTED + fprintf(stderr, " -gif Select GIF output format%s\n", + (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); +#endif +#ifdef BMP_SUPPORTED + fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", + (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); +#endif +#ifdef PPM_SUPPORTED + fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", + (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); +#endif +#ifdef RLE_SUPPORTED + fprintf(stderr, " -rle Select Utah RLE output format%s\n", + (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); +#endif +#ifdef TARGA_SUPPORTED + fprintf(stderr, " -targa Select Targa output format%s\n", + (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); +#endif + fprintf(stderr, "Switches for advanced users:\n"); +#ifdef DCT_ISLOW_SUPPORTED + fprintf(stderr, " -dct int Use integer DCT method%s\n", + (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); +#endif +#ifdef DCT_IFAST_SUPPORTED + fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", + (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); +#endif +#ifdef DCT_FLOAT_SUPPORTED + fprintf(stderr, " -dct float Use floating-point DCT method%s\n", + (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); +#endif + fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); + fprintf(stderr, " -dither none Don't use dithering in quantization\n"); + fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); +#ifdef QUANT_2PASS_SUPPORTED + fprintf(stderr, " -map FILE Map to colors used in named image file\n"); +#endif + fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); +#ifdef QUANT_1PASS_SUPPORTED + fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); +#endif + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + exit(EXIT_FAILURE); +} + + +LOCAL(int) +parse_switches (j_decompress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + + /* Set up default JPEG parameters. */ + requested_fmt = DEFAULT_FMT; /* set default output file format */ + outfilename = NULL; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "bmp", 1)) { + /* BMP output format. */ + requested_fmt = FMT_BMP; + + } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || + keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { + /* Do color quantization. */ + int val; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d", &val) != 1) + usage(); + cinfo->desired_number_of_colors = val; + cinfo->quantize_colors = TRUE; + + } else if (keymatch(arg, "dct", 2)) { + /* Select IDCT algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "int", 1)) { + cinfo->dct_method = JDCT_ISLOW; + } else if (keymatch(argv[argn], "fast", 2)) { + cinfo->dct_method = JDCT_IFAST; + } else if (keymatch(argv[argn], "float", 2)) { + cinfo->dct_method = JDCT_FLOAT; + } else + usage(); + + } else if (keymatch(arg, "dither", 2)) { + /* Select dithering algorithm. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "fs", 2)) { + cinfo->dither_mode = JDITHER_FS; + } else if (keymatch(argv[argn], "none", 2)) { + cinfo->dither_mode = JDITHER_NONE; + } else if (keymatch(argv[argn], "ordered", 2)) { + cinfo->dither_mode = JDITHER_ORDERED; + } else + usage(); + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "fast", 1)) { + /* Select recommended processing options for quick-and-dirty output. */ + cinfo->two_pass_quantize = FALSE; + cinfo->dither_mode = JDITHER_ORDERED; + if (! cinfo->quantize_colors) /* don't override an earlier -colors */ + cinfo->desired_number_of_colors = 216; + cinfo->dct_method = JDCT_FASTEST; + cinfo->do_fancy_upsampling = FALSE; + + } else if (keymatch(arg, "gif", 1)) { + /* GIF output format. */ + requested_fmt = FMT_GIF; + + } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { + /* Force monochrome output. */ + cinfo->out_color_space = JCS_GRAYSCALE; + + } else if (keymatch(arg, "map", 3)) { + /* Quantize to a color map taken from an input file. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (for_real) { /* too expensive to do twice! */ +#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ + FILE * mapfile; + + if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + read_color_map(cinfo, mapfile); + fclose(mapfile); + cinfo->quantize_colors = TRUE; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "nosmooth", 3)) { + /* Suppress fancy upsampling */ + cinfo->do_fancy_upsampling = FALSE; + + } else if (keymatch(arg, "onepass", 3)) { + /* Use fast one-pass quantization. */ + cinfo->two_pass_quantize = FALSE; + + } else if (keymatch(arg, "os2", 3)) { + /* BMP output format (OS/2 flavor). */ + requested_fmt = FMT_OS2; + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { + /* PPM/PGM output format. */ + requested_fmt = FMT_PPM; + + } else if (keymatch(arg, "rle", 1)) { + /* RLE output format. */ + requested_fmt = FMT_RLE; + + } else if (keymatch(arg, "scale", 1)) { + /* Scale the output image by a fraction M/N. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%d/%d", + &cinfo->scale_num, &cinfo->scale_denom) != 2) + usage(); + + } else if (keymatch(arg, "targa", 1)) { + /* Targa output format. */ + requested_fmt = FMT_TARGA; + + } else { + usage(); /* bogus switch */ + } + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * Marker processor for COM and interesting APPn markers. + * This replaces the library's built-in processor, which just skips the marker. + * We want to print out the marker as text, to the extent possible. + * Note this code relies on a non-suspending data source. + */ + +LOCAL(unsigned int) +jpeg_getc (j_decompress_ptr cinfo) +/* Read next byte */ +{ + struct jpeg_source_mgr * datasrc = cinfo->src; + + if (datasrc->bytes_in_buffer == 0) { + if (! (*datasrc->fill_input_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + datasrc->bytes_in_buffer--; + return GETJOCTET(*datasrc->next_input_byte++); +} + + +METHODDEF(boolean) +print_text_marker (j_decompress_ptr cinfo) +{ + boolean traceit = (cinfo->err->trace_level >= 1); + INT32 length; + unsigned int ch; + unsigned int lastch = 0; + + length = jpeg_getc(cinfo) << 8; + length += jpeg_getc(cinfo); + length -= 2; /* discount the length word itself */ + + if (traceit) { + if (cinfo->unread_marker == JPEG_COM) + fprintf(stderr, "Comment, length %ld:\n", (long) length); + else /* assume it is an APPn otherwise */ + fprintf(stderr, "APP%d, length %ld:\n", + cinfo->unread_marker - JPEG_APP0, (long) length); + } + + while (--length >= 0) { + ch = jpeg_getc(cinfo); + if (traceit) { + /* Emit the character in a readable form. + * Nonprintables are converted to \nnn form, + * while \ is converted to \\. + * Newlines in CR, CR/LF, or LF form will be printed as one newline. + */ + if (ch == '\r') { + fprintf(stderr, "\n"); + } else if (ch == '\n') { + if (lastch != '\r') + fprintf(stderr, "\n"); + } else if (ch == '\\') { + fprintf(stderr, "\\\\"); + } else if (isprint(ch)) { + putc(ch, stderr); + } else { + fprintf(stderr, "\\%03o", ch); + } + lastch = ch; + } + } + + if (traceit) + fprintf(stderr, "\n"); + + return TRUE; +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + int file_index; + djpeg_dest_ptr dest_mgr = NULL; + FILE * input_file; + FILE * output_file; + JDIMENSION num_scanlines; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "djpeg"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG decompression object with default error handling. */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + /* Add some application-specific error messages (from cderror.h) */ + jerr.addon_message_table = cdjpeg_message_table; + jerr.first_addon_message = JMSG_FIRSTADDONCODE; + jerr.last_addon_message = JMSG_LASTADDONCODE; + + /* Insert custom marker processor for COM and APP12. + * APP12 is used by some digital camera makers for textual info, + * so we provide the ability to display it as text. + * If you like, additional APPn marker types can be selected for display, + * but don't try to override APP0 or APP14 this way (see libjpeg.doc). + */ + jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); + jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); + + /* Now safe to enable signal catcher. */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &cinfo); +#endif + + /* Scan command line to find file names. */ + /* It is convenient to use just one switch-parsing routine, but the switch + * values read here are ignored; we will rescan the switches after opening + * the input file. + * (Exception: tracing level set here controls verbosity for COM markers + * found during jpeg_read_header...) + */ + + file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &cinfo, &progress); +#endif + + /* Specify data source for decompression */ + jpeg_stdio_src(&cinfo, input_file); + + /* Read file header, set default decompression parameters */ + (void) jpeg_read_header(&cinfo, TRUE); + + /* Adjust default decompression parameters by re-parsing the options */ + file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); + + /* Initialize the output module now to let it override any crucial + * option settings (for instance, GIF wants to force color quantization). + */ + switch (requested_fmt) { +#ifdef BMP_SUPPORTED + case FMT_BMP: + dest_mgr = jinit_write_bmp(&cinfo, FALSE); + break; + case FMT_OS2: + dest_mgr = jinit_write_bmp(&cinfo, TRUE); + break; +#endif +#ifdef GIF_SUPPORTED + case FMT_GIF: + dest_mgr = jinit_write_gif(&cinfo); + break; +#endif +#ifdef PPM_SUPPORTED + case FMT_PPM: + dest_mgr = jinit_write_ppm(&cinfo); + break; +#endif +#ifdef RLE_SUPPORTED + case FMT_RLE: + dest_mgr = jinit_write_rle(&cinfo); + break; +#endif +#ifdef TARGA_SUPPORTED + case FMT_TARGA: + dest_mgr = jinit_write_targa(&cinfo); + break; +#endif + default: + ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); + break; + } + dest_mgr->output_file = output_file; + + /* Start decompressor */ + (void) jpeg_start_decompress(&cinfo); + + /* Write output file header */ + (*dest_mgr->start_output) (&cinfo, dest_mgr); + + /* Process data */ + while (cinfo.output_scanline < cinfo.output_height) { + num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, + dest_mgr->buffer_height); + (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); + } + +#ifdef PROGRESS_REPORT + /* Hack: count final pass as done in case finish_output does an extra pass. + * The library won't have updated completed_passes. + */ + progress.pub.completed_passes = progress.pub.total_passes; +#endif + + /* Finish decompression and release memory. + * I must do it in this order because output module has allocated memory + * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. + */ + (*dest_mgr->finish_output) (&cinfo, dest_mgr); + (void) jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &cinfo); +#endif + + /* All done. */ + exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/src/dep/src/irrlicht/jpeglib/example.c b/src/dep/src/irrlicht/jpeglib/example.c new file mode 100644 index 0000000..9dcbd7d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/example.c @@ -0,0 +1,433 @@ +/* + * example.c + * + * This file illustrates how to use the IJG code as a subroutine library + * to read or write JPEG image files. You should look at this code in + * conjunction with the documentation file libjpeg.doc. + * + * This code will not do anything useful as-is, but it may be helpful as a + * skeleton for constructing routines that call the JPEG library. + * + * We present these routines in the same coding style used in the JPEG code + * (ANSI function definitions, etc); but you are of course free to code your + * routines in a different style if you prefer. + */ + +#include + +/* + * Include file for users of JPEG library. + * You will need to have included system headers that define at least + * the typedefs FILE and size_t before you can include jpeglib.h. + * (stdio.h is sufficient on ANSI-conforming systems.) + * You may also wish to include "jerror.h". + */ + +#include "jpeglib.h" + +/* + * is used for the optional error recovery mechanism shown in + * the second part of the example. + */ + +#include + + + +/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/ + +/* This half of the example shows how to feed data into the JPEG compressor. + * We present a minimal version that does not worry about refinements such + * as error recovery (the JPEG code will just exit() if it gets an error). + */ + + +/* + * IMAGE DATA FORMATS: + * + * The standard input image format is a rectangular array of pixels, with + * each pixel having the same number of "component" values (color channels). + * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars). + * If you are working with color data, then the color values for each pixel + * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit + * RGB color. + * + * For this example, we'll assume that this data structure matches the way + * our application has stored the image in memory, so we can just pass a + * pointer to our image buffer. In particular, let's say that the image is + * RGB color and is described by: + */ + +extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */ +extern int image_height; /* Number of rows in image */ +extern int image_width; /* Number of columns in image */ + + +/* + * Sample routine for JPEG compression. We assume that the target file name + * and a compression quality factor are passed in. + */ + +GLOBAL(void) +write_JPEG_file (char * filename, int quality) +{ + /* This struct contains the JPEG compression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + * It is possible to have several such structures, representing multiple + * compression/decompression processes, in existence at once. We refer + * to any one struct (and its associated working data) as a "JPEG object". + */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + /* Step 1: allocate and initialize JPEG compression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + /* Here we use the library-supplied code to send compressed data to a + * stdio stream. You can also write your own code to do something else. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to write binary files. + */ + if ((outfile = fopen(filename, "wb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + exit(1); + } + jpeg_stdio_dest(&cinfo, outfile); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = image_width; /* image width and height, in pixels */ + cinfo.image_height = image_height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + /* Now use the library's routine to set default compression parameters. + * (You must set at least cinfo.in_color_space before calling this, + * since the defaults depend on the source color space.) + */ + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); + + /* Step 4: Start compressor */ + + /* TRUE ensures that we will write a complete interchange-JPEG file. + * Pass TRUE unless you are very sure of what you're doing. + */ + jpeg_start_compress(&cinfo, TRUE); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + /* Here we use the library's state variable cinfo.next_scanline as the + * loop counter, so that we don't have to keep track ourselves. + * To keep things simple, we pass one scanline per call; you can pass + * more if you wish, though. + */ + row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ + + while (cinfo.next_scanline < cinfo.image_height) { + /* jpeg_write_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could pass + * more than one scanline at a time if that's more convenient. + */ + row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + /* After finish_compress, we can close the output file. */ + fclose(outfile); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + + /* And we're done! */ +} + + +/* + * SOME FINE POINTS: + * + * In the above loop, we ignored the return value of jpeg_write_scanlines, + * which is the number of scanlines actually written. We could get away + * with this because we were only relying on the value of cinfo.next_scanline, + * which will be incremented correctly. If you maintain additional loop + * variables then you should be careful to increment them properly. + * Actually, for output to a stdio stream you needn't worry, because + * then jpeg_write_scanlines will write all the lines passed (or else exit + * with a fatal error). Partial writes can only occur if you use a data + * destination module that can demand suspension of the compressor. + * (If you don't know what that's for, you don't need it.) + * + * If the compressor requires full-image buffers (for entropy-coding + * optimization or a multi-scan JPEG file), it will create temporary + * files for anything that doesn't fit within the maximum-memory setting. + * (Note that temp files are NOT needed if you use the default parameters.) + * On some systems you may need to set up a signal handler to ensure that + * temporary files are deleted if the program is interrupted. See libjpeg.doc. + * + * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG + * files to be compatible with everyone else's. If you cannot readily read + * your data in that order, you'll need an intermediate array to hold the + * image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top + * source data using the JPEG code's internal virtual-array mechanisms. + */ + + + +/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/ + +/* This half of the example shows how to read data from the JPEG decompressor. + * It's a bit more refined than the above, in that we show: + * (a) how to modify the JPEG library's standard error-reporting behavior; + * (b) how to allocate workspace using the library's memory manager. + * + * Just to make this example a little different from the first one, we'll + * assume that we do not intend to put the whole image into an in-memory + * buffer, but to send it line-by-line someplace else. We need a one- + * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG + * memory manager allocate it for us. This approach is actually quite useful + * because we don't need to remember to deallocate the buffer separately: it + * will go away automatically when the JPEG object is cleaned up. + */ + + +/* + * ERROR HANDLING: + * + * The JPEG library's standard error handler (jerror.c) is divided into + * several "methods" which you can override individually. This lets you + * adjust the behavior without duplicating a lot of code, which you might + * have to update with each future release. + * + * Our example here shows how to override the "error_exit" method so that + * control is returned to the library's caller when a fatal error occurs, + * rather than calling exit() as the standard error_exit method does. + * + * We use C's setjmp/longjmp facility to return control. This means that the + * routine which calls the JPEG library must first execute a setjmp() call to + * establish the return point. We want the replacement error_exit to do a + * longjmp(). But we need to make the setjmp buffer accessible to the + * error_exit routine. To do this, we make a private extension of the + * standard JPEG error handler object. (If we were using C++, we'd say we + * were making a subclass of the regular error handler.) + * + * Here's the extended error handler struct: + */ + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + + jmp_buf setjmp_buffer; /* for return to caller */ +}; + +typedef struct my_error_mgr * my_error_ptr; + +/* + * Here's the routine that will replace the standard error_exit method: + */ + +METHODDEF(void) +my_error_exit (j_common_ptr cinfo) +{ + /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ + my_error_ptr myerr = (my_error_ptr) cinfo->err; + + /* Always display the message. */ + /* We could postpone this until after returning, if we chose. */ + (*cinfo->err->output_message) (cinfo); + + /* Return control to the setjmp point */ + longjmp(myerr->setjmp_buffer, 1); +} + + +/* + * Sample routine for JPEG decompression. We assume that the source file name + * is passed in. We want to return 1 on success, 0 on error. + */ + + +GLOBAL(int) +read_JPEG_file (char * filename) +{ + /* This struct contains the JPEG decompression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct cinfo; + /* We use our private extension JPEG error handler. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct my_error_mgr jerr; + /* More stuff */ + FILE * infile; /* source file */ + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + + /* In this example we want to open the input file before doing anything else, + * so that the setjmp() error recovery below can assume the file is open. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to read binary files. + */ + + if ((infile = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + return 0; + } + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We set up the normal JPEG error routines, then override error_exit. */ + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + /* Establish the setjmp return context for my_error_exit to use. */ + if (setjmp(jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. + * We need to clean up the JPEG object, close the input file, and return. + */ + jpeg_destroy_decompress(&cinfo); + fclose(infile); + return 0; + } + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_stdio_src(&cinfo, infile); + + /* Step 3: read file parameters with jpeg_read_header() */ + + (void) jpeg_read_header(&cinfo, TRUE); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + + /* In this example, we don't need to change any of the defaults set by + * jpeg_read_header(), so we do nothing here. + */ + + /* Step 5: Start decompressor */ + + (void) jpeg_start_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = cinfo.output_width * cinfo.output_components; + /* Make a one-row-high sample array that will go away when done with image */ + buffer = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo.output_scanline < cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + /* Assume put_scanline_someplace wants a pointer and sample count. */ + put_scanline_someplace(buffer[0], row_stride); + } + + /* Step 7: Finish decompression */ + + (void) jpeg_finish_decompress(&cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* Step 8: Release JPEG decompression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_decompress(&cinfo); + + /* After finish_decompress, we can close the input file. + * Here we postpone it until after no more JPEG errors are possible, + * so as to simplify the setjmp error logic above. (Actually, I don't + * think that jpeg_destroy can do an error exit, but why assume anything...) + */ + fclose(infile); + + /* At this point you may want to check to see whether any corrupt-data + * warnings occurred (test whether jerr.pub.num_warnings is nonzero). + */ + + /* And we're done! */ + return 1; +} + + +/* + * SOME FINE POINTS: + * + * In the above code, we ignored the return value of jpeg_read_scanlines, + * which is the number of scanlines actually read. We could get away with + * this because we asked for only one line at a time and we weren't using + * a suspending data source. See libjpeg.doc for more info. + * + * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress(); + * we should have done it beforehand to ensure that the space would be + * counted against the JPEG max_memory setting. In some systems the above + * code would risk an out-of-memory error. However, in general we don't + * know the output image dimensions before jpeg_start_decompress(), unless we + * call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this. + * + * Scanlines are returned in the same order as they appear in the JPEG file, + * which is standardly top-to-bottom. If you must emit data bottom-to-top, + * you can use one of the virtual arrays provided by the JPEG memory manager + * to invert the data. See wrbmp.c for an example. + * + * As with compression, some operating modes may require temporary files. + * On some systems you may need to set up a signal handler to ensure that + * temporary files are deleted if the program is interrupted. See libjpeg.doc. + */ diff --git a/src/dep/src/irrlicht/jpeglib/filelist.doc b/src/dep/src/irrlicht/jpeglib/filelist.doc new file mode 100644 index 0000000..ad6a82d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/filelist.doc @@ -0,0 +1,210 @@ +IJG JPEG LIBRARY: FILE LIST + +Copyright (C) 1994-1998, Thomas G. Lane. +This file is part of the Independent JPEG Group's software. +For conditions of distribution and use, see the accompanying README file. + + +Here is a road map to the files in the IJG JPEG distribution. The +distribution includes the JPEG library proper, plus two application +programs ("cjpeg" and "djpeg") which use the library to convert JPEG +files to and from some other popular image formats. A third application +"jpegtran" uses the library to do lossless conversion between different +variants of JPEG. There are also two stand-alone applications, +"rdjpgcom" and "wrjpgcom". + + +THE JPEG LIBRARY +================ + +Include files: + +jpeglib.h JPEG library's exported data and function declarations. +jconfig.h Configuration declarations. Note: this file is not present + in the distribution; it is generated during installation. +jmorecfg.h Additional configuration declarations; need not be changed + for a standard installation. +jerror.h Declares JPEG library's error and trace message codes. +jinclude.h Central include file used by all IJG .c files to reference + system include files. +jpegint.h JPEG library's internal data structures. +jchuff.h Private declarations for Huffman encoder modules. +jdhuff.h Private declarations for Huffman decoder modules. +jdct.h Private declarations for forward & reverse DCT subsystems. +jmemsys.h Private declarations for memory management subsystem. +jversion.h Version information. + +Applications using the library should include jpeglib.h (which in turn +includes jconfig.h and jmorecfg.h). Optionally, jerror.h may be included +if the application needs to reference individual JPEG error codes. The +other include files are intended for internal use and would not normally +be included by an application program. (cjpeg/djpeg/etc do use jinclude.h, +since its function is to improve portability of the whole IJG distribution. +Most other applications will directly include the system include files they +want, and hence won't need jinclude.h.) + + +C source code files: + +These files contain most of the functions intended to be called directly by +an application program: + +jcapimin.c Application program interface: core routines for compression. +jcapistd.c Application program interface: standard compression. +jdapimin.c Application program interface: core routines for decompression. +jdapistd.c Application program interface: standard decompression. +jcomapi.c Application program interface routines common to compression + and decompression. +jcparam.c Compression parameter setting helper routines. +jctrans.c API and library routines for transcoding compression. +jdtrans.c API and library routines for transcoding decompression. + +Compression side of the library: + +jcinit.c Initialization: determines which other modules to use. +jcmaster.c Master control: setup and inter-pass sequencing logic. +jcmainct.c Main buffer controller (preprocessor => JPEG compressor). +jcprepct.c Preprocessor buffer controller. +jccoefct.c Buffer controller for DCT coefficient buffer. +jccolor.c Color space conversion. +jcsample.c Downsampling. +jcdctmgr.c DCT manager (DCT implementation selection & control). +jfdctint.c Forward DCT using slow-but-accurate integer method. +jfdctfst.c Forward DCT using faster, less accurate integer method. +jfdctflt.c Forward DCT using floating-point arithmetic. +jchuff.c Huffman entropy coding for sequential JPEG. +jcphuff.c Huffman entropy coding for progressive JPEG. +jcmarker.c JPEG marker writing. +jdatadst.c Data destination manager for stdio output. + +Decompression side of the library: + +jdmaster.c Master control: determines which other modules to use. +jdinput.c Input controller: controls input processing modules. +jdmainct.c Main buffer controller (JPEG decompressor => postprocessor). +jdcoefct.c Buffer controller for DCT coefficient buffer. +jdpostct.c Postprocessor buffer controller. +jdmarker.c JPEG marker reading. +jdhuff.c Huffman entropy decoding for sequential JPEG. +jdphuff.c Huffman entropy decoding for progressive JPEG. +jddctmgr.c IDCT manager (IDCT implementation selection & control). +jidctint.c Inverse DCT using slow-but-accurate integer method. +jidctfst.c Inverse DCT using faster, less accurate integer method. +jidctflt.c Inverse DCT using floating-point arithmetic. +jidctred.c Inverse DCTs with reduced-size outputs. +jdsample.c Upsampling. +jdcolor.c Color space conversion. +jdmerge.c Merged upsampling/color conversion (faster, lower quality). +jquant1.c One-pass color quantization using a fixed-spacing colormap. +jquant2.c Two-pass color quantization using a custom-generated colormap. + Also handles one-pass quantization to an externally given map. +jdatasrc.c Data source manager for stdio input. + +Support files for both compression and decompression: + +jerror.c Standard error handling routines (application replaceable). +jmemmgr.c System-independent (more or less) memory management code. +jutils.c Miscellaneous utility routines. + +jmemmgr.c relies on a system-dependent memory management module. The IJG +distribution includes the following implementations of the system-dependent +module: + +jmemnobs.c "No backing store": assumes adequate virtual memory exists. +jmemansi.c Makes temporary files with ANSI-standard routine tmpfile(). +jmemname.c Makes temporary files with program-generated file names. +jmemdos.c Custom implementation for MS-DOS (16-bit environment only): + can use extended and expanded memory as well as temp files. +jmemmac.c Custom implementation for Apple Macintosh. + +Exactly one of the system-dependent modules should be configured into an +installed JPEG library (see install.doc for hints about which one to use). +On unusual systems you may find it worthwhile to make a special +system-dependent memory manager. + + +Non-C source code files: + +jmemdosa.asm 80x86 assembly code support for jmemdos.c; used only in + MS-DOS-specific configurations of the JPEG library. + + +CJPEG/DJPEG/JPEGTRAN +==================== + +Include files: + +cdjpeg.h Declarations shared by cjpeg/djpeg/jpegtran modules. +cderror.h Additional error and trace message codes for cjpeg et al. +transupp.h Declarations for jpegtran support routines in transupp.c. + +C source code files: + +cjpeg.c Main program for cjpeg. +djpeg.c Main program for djpeg. +jpegtran.c Main program for jpegtran. +cdjpeg.c Utility routines used by all three programs. +rdcolmap.c Code to read a colormap file for djpeg's "-map" switch. +rdswitch.c Code to process some of cjpeg's more complex switches. + Also used by jpegtran. +transupp.c Support code for jpegtran: lossless image manipulations. + +Image file reader modules for cjpeg: + +rdbmp.c BMP file input. +rdgif.c GIF file input (now just a stub). +rdppm.c PPM/PGM file input. +rdrle.c Utah RLE file input. +rdtarga.c Targa file input. + +Image file writer modules for djpeg: + +wrbmp.c BMP file output. +wrgif.c GIF file output (a mere shadow of its former self). +wrppm.c PPM/PGM file output. +wrrle.c Utah RLE file output. +wrtarga.c Targa file output. + + +RDJPGCOM/WRJPGCOM +================= + +C source code files: + +rdjpgcom.c Stand-alone rdjpgcom application. +wrjpgcom.c Stand-alone wrjpgcom application. + +These programs do not depend on the IJG library. They do use +jconfig.h and jinclude.h, only to improve portability. + + +ADDITIONAL FILES +================ + +Documentation (see README for a guide to the documentation files): + +README Master documentation file. +*.doc Other documentation files. +*.1 Documentation in Unix man page format. +change.log Version-to-version change highlights. +example.c Sample code for calling JPEG library. + +Configuration/installation files and programs (see install.doc for more info): + +configure Unix shell script to perform automatic configuration. +ltconfig Support scripts for configure (from GNU libtool). +ltmain.sh +config.guess +config.sub +install-sh Install shell script for those Unix systems lacking one. +ckconfig.c Program to generate jconfig.h on non-Unix systems. +jconfig.doc Template for making jconfig.h by hand. +makefile.* Sample makefiles for particular systems. +jconfig.* Sample jconfig.h for particular systems. +ansi2knr.c De-ANSIfier for pre-ANSI C compilers (courtesy of + L. Peter Deutsch and Aladdin Enterprises). + +Test files (see install.doc for test procedure): + +test*.* Source and comparison files for confidence test. + These are binary image files, NOT text files. diff --git a/src/dep/src/irrlicht/jpeglib/install-sh b/src/dep/src/irrlicht/jpeglib/install-sh new file mode 100644 index 0000000..082fd7c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/install-sh @@ -0,0 +1,250 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/src/dep/src/irrlicht/jpeglib/install.doc b/src/dep/src/irrlicht/jpeglib/install.doc new file mode 100644 index 0000000..7d72c93 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/install.doc @@ -0,0 +1,1063 @@ +INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software + +Copyright (C) 1991-1998, Thomas G. Lane. +This file is part of the Independent JPEG Group's software. +For conditions of distribution and use, see the accompanying README file. + + +This file explains how to configure and install the IJG software. We have +tried to make this software extremely portable and flexible, so that it can be +adapted to almost any environment. The downside of this decision is that the +installation process is complicated. We have provided shortcuts to simplify +the task on common systems. But in any case, you will need at least a little +familiarity with C programming and program build procedures for your system. + +If you are only using this software as part of a larger program, the larger +program's installation procedure may take care of configuring the IJG code. +For example, Ghostscript's installation script will configure the IJG code. +You don't need to read this file if you just want to compile Ghostscript. + +If you are on a Unix machine, you may not need to read this file at all. +Try doing + ./configure + make + make test +If that doesn't complain, do + make install +(better do "make -n install" first to see if the makefile will put the files +where you want them). Read further if you run into snags or want to customize +the code for your system. + + +TABLE OF CONTENTS +----------------- + +Before you start +Configuring the software: + using the automatic "configure" script + using one of the supplied jconfig and makefile files + by hand +Building the software +Testing the software +Installing the software +Optional stuff +Optimization +Hints for specific systems + + +BEFORE YOU START +================ + +Before installing the software you must unpack the distributed source code. +Since you are reading this file, you have probably already succeeded in this +task. However, there is a potential for error if you needed to convert the +files to the local standard text file format (for example, if you are on +MS-DOS you may have converted LF end-of-line to CR/LF). You must apply +such conversion to all the files EXCEPT those whose names begin with "test". +The test files contain binary data; if you change them in any way then the +self-test will give bad results. + +Please check the last section of this file to see if there are hints for the +specific machine or compiler you are using. + + +CONFIGURING THE SOFTWARE +======================== + +To configure the IJG code for your system, you need to create two files: + * jconfig.h: contains values for system-dependent #define symbols. + * Makefile: controls the compilation process. +(On a non-Unix machine, you may create "project files" or some other +substitute for a Makefile. jconfig.h is needed in any environment.) + +We provide three different ways to generate these files: + * On a Unix system, you can just run the "configure" script. + * We provide sample jconfig files and makefiles for popular machines; + if your machine matches one of the samples, just copy the right sample + files to jconfig.h and Makefile. + * If all else fails, read the instructions below and make your own files. + + +Configuring the software using the automatic "configure" script +--------------------------------------------------------------- + +If you are on a Unix machine, you can just type + ./configure +and let the configure script construct appropriate configuration files. +If you're using "csh" on an old version of System V, you might need to type + sh configure +instead to prevent csh from trying to execute configure itself. +Expect configure to run for a few minutes, particularly on slower machines; +it works by compiling a series of test programs. + +Configure was created with GNU Autoconf and it follows the usual conventions +for GNU configure scripts. It makes a few assumptions that you may want to +override. You can do this by providing optional switches to configure: + +* If you want to build libjpeg as a shared library, say + ./configure --enable-shared +To get both shared and static libraries, say + ./configure --enable-shared --enable-static +Note that these switches invoke GNU libtool to take care of system-dependent +shared library building methods. If things don't work this way, please try +running configure without either switch; that should build a static library +without using libtool. If that works, your problem is probably with libtool +not with the IJG code. libtool is fairly new and doesn't support all flavors +of Unix yet. (You might be able to find a newer version of libtool than the +one included with libjpeg; see ftp.gnu.org. Report libtool problems to +bug-libtool@gnu.org.) + +* Configure will use gcc (GNU C compiler) if it's available, otherwise cc. +To force a particular compiler to be selected, use the CC option, for example + ./configure CC='cc' +The same method can be used to include any unusual compiler switches. +For example, on HP-UX you probably want to say + ./configure CC='cc -Aa' +to get HP's compiler to run in ANSI mode. + +* The default CFLAGS setting is "-O" for non-gcc compilers, "-O2" for gcc. +You can override this by saying, for example, + ./configure CFLAGS='-g' +if you want to compile with debugging support. + +* Configure will set up the makefile so that "make install" will install files +into /usr/local/bin, /usr/local/man, etc. You can specify an installation +prefix other than "/usr/local" by giving configure the option "--prefix=PATH". + +* If you don't have a lot of swap space, you may need to enable the IJG +software's internal virtual memory mechanism. To do this, give the option +"--enable-maxmem=N" where N is the default maxmemory limit in megabytes. +This is discussed in more detail under "Selecting a memory manager", below. +You probably don't need to worry about this on reasonably-sized Unix machines, +unless you plan to process very large images. + +Configure has some other features that are useful if you are cross-compiling +or working in a network of multiple machine types; but if you need those +features, you probably already know how to use them. + + +Configuring the software using one of the supplied jconfig and makefile files +----------------------------------------------------------------------------- + +If you have one of these systems, you can just use the provided configuration +files: + +Makefile jconfig file System and/or compiler + +makefile.manx jconfig.manx Amiga, Manx Aztec C +makefile.sas jconfig.sas Amiga, SAS C +makeproj.mac jconfig.mac Apple Macintosh, Metrowerks CodeWarrior +mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C +makefile.bcc jconfig.bcc MS-DOS or OS/2, Borland C +makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C) +makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C (16-bit only) +makefile.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C +makefile.vc jconfig.vc Windows NT/95, MS Visual C++ +make*.ds jconfig.vc Windows NT/95, MS Developer Studio +makefile.mms jconfig.vms Digital VMS, with MMS software +makefile.vms jconfig.vms Digital VMS, without MMS software + +Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or +whatever your system uses as the standard makefile name). For more info see +the appropriate system-specific hints section near the end of this file. + + +Configuring the software by hand +-------------------------------- + +First, generate a jconfig.h file. If you are moderately familiar with C, +the comments in jconfig.doc should be enough information to do this; just +copy jconfig.doc to jconfig.h and edit it appropriately. Otherwise, you may +prefer to use the ckconfig.c program. You will need to compile and execute +ckconfig.c by hand --- we hope you know at least enough to do that. +ckconfig.c may not compile the first try (in fact, the whole idea is for it +to fail if anything is going to). If you get compile errors, fix them by +editing ckconfig.c according to the directions given in ckconfig.c. Once +you get it to run, it will write a suitable jconfig.h file, and will also +print out some advice about which makefile to use. + +You may also want to look at the canned jconfig files, if there is one for a +system similar to yours. + +Second, select a makefile and copy it to Makefile (or whatever your system +uses as the standard makefile name). The most generic makefiles we provide +are + makefile.ansi: if your C compiler supports function prototypes + makefile.unix: if not. +(You have function prototypes if ckconfig.c put "#define HAVE_PROTOTYPES" +in jconfig.h.) You may want to start from one of the other makefiles if +there is one for a system similar to yours. + +Look over the selected Makefile and adjust options as needed. In particular +you may want to change the CC and CFLAGS definitions. For instance, if you +are using GCC, set CC=gcc. If you had to use any compiler switches to get +ckconfig.c to work, make sure the same switches are in CFLAGS. + +If you are on a system that doesn't use makefiles, you'll need to set up +project files (or whatever you do use) to compile all the source files and +link them into executable files cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom. +See the file lists in any of the makefiles to find out which files go into +each program. Note that the provided makefiles all make a "library" file +libjpeg first, but you don't have to do that if you don't want to; the file +lists identify which source files are actually needed for compression, +decompression, or both. As a last resort, you can make a batch script that +just compiles everything and links it all together; makefile.vms is an example +of this (it's for VMS systems that have no make-like utility). + +Here are comments about some specific configuration decisions you'll +need to make: + +Command line style +------------------ + +These programs can use a Unix-like command line style which supports +redirection and piping, like this: + cjpeg inputfile >outputfile + cjpeg outputfile + source program | cjpeg >outputfile +The simpler "two file" command line style is just + cjpeg inputfile outputfile +You may prefer the two-file style, particularly if you don't have pipes. + +You MUST use two-file style on any system that doesn't cope well with binary +data fed through stdin/stdout; this is true for some MS-DOS compilers, for +example. If you're not on a Unix system, it's safest to assume you need +two-file style. (But if your compiler provides either the Posix-standard +fdopen() library routine or a Microsoft-compatible setmode() routine, you +can safely use the Unix command line style, by defining USE_FDOPEN or +USE_SETMODE respectively.) + +To use the two-file style, make jconfig.h say "#define TWO_FILE_COMMANDLINE". + +Selecting a memory manager +-------------------------- + +The IJG code is capable of working on images that are too big to fit in main +memory; data is swapped out to temporary files as necessary. However, the +code to do this is rather system-dependent. We provide five different +memory managers: + +* jmemansi.c This version uses the ANSI-standard library routine tmpfile(), + which not all non-ANSI systems have. On some systems + tmpfile() may put the temporary file in a non-optimal + location; if you don't like what it does, use jmemname.c. + +* jmemname.c This version creates named temporary files. For anything + except a Unix machine, you'll need to configure the + select_file_name() routine appropriately; see the comments + near the head of jmemname.c. If you use this version, define + NEED_SIGNAL_CATCHER in jconfig.h to make sure the temp files + are removed if the program is aborted. + +* jmemnobs.c (That stands for No Backing Store :-).) This will compile on + almost any system, but it assumes you have enough main memory + or virtual memory to hold the biggest images you work with. + +* jmemdos.c This should be used with most 16-bit MS-DOS compilers. + See the system-specific notes about MS-DOS for more info. + IMPORTANT: if you use this, define USE_MSDOS_MEMMGR in + jconfig.h, and include the assembly file jmemdosa.asm in the + programs. The supplied makefiles and jconfig files for + 16-bit MS-DOS compilers already do both. + +* jmemmac.c Custom version for Apple Macintosh; see the system-specific + notes for Macintosh for more info. + +To use a particular memory manager, change the SYSDEPMEM variable in your +makefile to equal the corresponding object file name (for example, jmemansi.o +or jmemansi.obj for jmemansi.c). + +If you have plenty of (real or virtual) main memory, just use jmemnobs.c. +"Plenty" means about ten bytes for every pixel in the largest images +you plan to process, so a lot of systems don't meet this criterion. +If yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have +to use jmemname.c; be sure to adjust select_file_name() for local conditions. +You may also need to change unlink() to remove() in close_backing_store(). + +Except with jmemnobs.c or jmemmac.c, you need to adjust the DEFAULT_MAX_MEM +setting to a reasonable value for your system (either by adding a #define for +DEFAULT_MAX_MEM to jconfig.h, or by adding a -D switch to the Makefile). +This value limits the amount of data space the program will attempt to +allocate. Code and static data space isn't counted, so the actual memory +needs for cjpeg or djpeg are typically 100 to 150Kb more than the max-memory +setting. Larger max-memory settings reduce the amount of I/O needed to +process a large image, but too large a value can result in "insufficient +memory" failures. On most Unix machines (and other systems with virtual +memory), just set DEFAULT_MAX_MEM to several million and forget it. At the +other end of the spectrum, for MS-DOS machines you probably can't go much +above 300K to 400K. (On MS-DOS the value refers to conventional memory only. +Extended/expanded memory is handled separately by jmemdos.c.) + + +BUILDING THE SOFTWARE +===================== + +Now you should be able to compile the software. Just say "make" (or +whatever's necessary to start the compilation). Have a cup of coffee. + +Here are some things that could go wrong: + +If your compiler complains about undefined structures, you should be able to +shut it up by putting "#define INCOMPLETE_TYPES_BROKEN" in jconfig.h. + +If you have trouble with missing system include files or inclusion of the +wrong ones, read jinclude.h. This shouldn't happen if you used configure +or ckconfig.c to set up jconfig.h. + +There are a fair number of routines that do not use all of their parameters; +some compilers will issue warnings about this, which you can ignore. There +are also a few configuration checks that may give "unreachable code" warnings. +Any other warning deserves investigation. + +If you don't have a getenv() library routine, define NO_GETENV. + +Also see the system-specific hints, below. + + +TESTING THE SOFTWARE +==================== + +As a quick test of functionality we've included a small sample image in +several forms: + testorig.jpg Starting point for the djpeg tests. + testimg.ppm The output of djpeg testorig.jpg + testimg.bmp The output of djpeg -bmp -colors 256 testorig.jpg + testimg.jpg The output of cjpeg testimg.ppm + testprog.jpg Progressive-mode equivalent of testorig.jpg. + testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm +(The first- and second-generation .jpg files aren't identical since JPEG is +lossy.) If you can generate duplicates of the testimg* files then you +probably have working programs. + +With most of the makefiles, "make test" will perform the necessary +comparisons. + +If you're using a makefile that doesn't provide the test option, run djpeg +and cjpeg by hand and compare the output files to testimg* with whatever +binary file comparison tool you have. The files should be bit-for-bit +identical. + +If the programs complain "MAX_ALLOC_CHUNK is wrong, please fix", then you +need to reduce MAX_ALLOC_CHUNK to a value that fits in type size_t. +Try adding "#define MAX_ALLOC_CHUNK 65520L" to jconfig.h. A less likely +configuration error is "ALIGN_TYPE is wrong, please fix": defining ALIGN_TYPE +as long should take care of that one. + +If the cjpeg test run fails with "Missing Huffman code table entry", it's a +good bet that you needed to define RIGHT_SHIFT_IS_UNSIGNED. Go back to the +configuration step and run ckconfig.c. (This is a good plan for any other +test failure, too.) + +If you are using Unix (one-file) command line style on a non-Unix system, +it's a good idea to check that binary I/O through stdin/stdout actually +works. You should get the same results from "djpeg out.ppm" +as from "djpeg -outfile out.ppm testorig.jpg". Note that the makefiles all +use the latter style and therefore do not exercise stdin/stdout! If this +check fails, try recompiling with USE_SETMODE or USE_FDOPEN defined. +If it still doesn't work, better use two-file style. + +If you chose a memory manager other than jmemnobs.c, you should test that +temporary-file usage works. Try "djpeg -bmp -colors 256 -max 0 testorig.jpg" +and make sure its output matches testimg.bmp. If you have any really large +images handy, try compressing them with -optimize and/or decompressing with +-colors 256 to make sure your DEFAULT_MAX_MEM setting is not too large. + +NOTE: this is far from an exhaustive test of the JPEG software; some modules, +such as 1-pass color quantization, are not exercised at all. It's just a +quick test to give you some confidence that you haven't missed something +major. + + +INSTALLING THE SOFTWARE +======================= + +Once you're done with the above steps, you can install the software by +copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom) +to wherever you normally install programs. On Unix systems, you'll also want +to put the man pages (cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1) +in the man-page directory. The pre-fab makefiles don't support this step +since there's such a wide variety of installation procedures on different +systems. + +If you generated a Makefile with the "configure" script, you can just say + make install +to install the programs and their man pages into the standard places. +(You'll probably need to be root to do this.) We recommend first saying + make -n install +to see where configure thought the files should go. You may need to edit +the Makefile, particularly if your system's conventions for man page +filenames don't match what configure expects. + +If you want to install the IJG library itself, for use in compiling other +programs besides ours, then you need to put the four include files + jpeglib.h jerror.h jconfig.h jmorecfg.h +into your include-file directory, and put the library file libjpeg.a +(extension may vary depending on system) wherever library files go. +If you generated a Makefile with "configure", it will do what it thinks +is the right thing if you say + make install-lib + + +OPTIONAL STUFF +============== + +Progress monitor: + +If you like, you can #define PROGRESS_REPORT (in jconfig.h) to enable display +of percent-done progress reports. The routine provided in cdjpeg.c merely +prints percentages to stderr, but you can customize it to do something +fancier. + +Utah RLE file format support: + +We distribute the software with support for RLE image files (Utah Raster +Toolkit format) disabled, because the RLE support won't compile without the +Utah library. If you have URT version 3.1 or later, you can enable RLE +support as follows: + 1. #define RLE_SUPPORTED in jconfig.h. + 2. Add a -I option to CFLAGS in the Makefile for the directory + containing the URT .h files (typically the "include" + subdirectory of the URT distribution). + 3. Add -L... -lrle to LDLIBS in the Makefile, where ... specifies + the directory containing the URT "librle.a" file (typically the + "lib" subdirectory of the URT distribution). + +Support for 12-bit-deep pixel data: + +The JPEG standard allows either 8-bit or 12-bit data precision. (For color, +this means 8 or 12 bits per channel, of course.) If you need to work with +deeper than 8-bit data, you can compile the IJG code for 12-bit operation. +To do so: + 1. In jmorecfg.h, define BITS_IN_JSAMPLE as 12 rather than 8. + 2. In jconfig.h, undefine BMP_SUPPORTED, RLE_SUPPORTED, and TARGA_SUPPORTED, + because the code for those formats doesn't handle 12-bit data and won't + even compile. (The PPM code does work, as explained below. The GIF + code works too; it scales 8-bit GIF data to and from 12-bit depth + automatically.) + 3. Compile. Don't expect "make test" to pass, since the supplied test + files are for 8-bit data. + +Currently, 12-bit support does not work on 16-bit-int machines. + +Note that a 12-bit version will not read 8-bit JPEG files, nor vice versa; +so you'll want to keep around a regular 8-bit compilation as well. +(Run-time selection of data depth, to allow a single copy that does both, +is possible but would probably slow things down considerably; it's very low +on our to-do list.) + +The PPM reader (rdppm.c) can read 12-bit data from either text-format or +binary-format PPM and PGM files. Binary-format PPM/PGM files which have a +maxval greater than 255 are assumed to use 2 bytes per sample, LSB first +(little-endian order). As of early 1995, 2-byte binary format is not +officially supported by the PBMPLUS library, but it is expected that a +future release of PBMPLUS will support it. Note that the PPM reader will +read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming +data is automatically rescaled to either maxval=255 or maxval=4095 as +appropriate for the cjpeg bit depth. + +The PPM writer (wrppm.c) will normally write 2-byte binary PPM or PGM +format, maxval 4095, when compiled with BITS_IN_JSAMPLE=12. Since this +format is not yet widely supported, you can disable it by compiling wrppm.c +with PPM_NORAWWORD defined; then the data is scaled down to 8 bits to make a +standard 1-byte/sample PPM or PGM file. (Yes, this means still another copy +of djpeg to keep around. But hopefully you won't need it for very long. +Poskanzer's supposed to get that new PBMPLUS release out Real Soon Now.) + +Of course, if you are working with 12-bit data, you probably have it stored +in some other, nonstandard format. In that case you'll probably want to +write your own I/O modules to read and write your format. + +Note that a 12-bit version of cjpeg always runs in "-optimize" mode, in +order to generate valid Huffman tables. This is necessary because our +default Huffman tables only cover 8-bit data. + +Removing code: + +If you need to make a smaller version of the JPEG software, some optional +functions can be removed at compile time. See the xxx_SUPPORTED #defines in +jconfig.h and jmorecfg.h. If at all possible, we recommend that you leave in +decoder support for all valid JPEG files, to ensure that you can read anyone's +output. Taking out support for image file formats that you don't use is the +most painless way to make the programs smaller. Another possibility is to +remove some of the DCT methods: in particular, the "IFAST" method may not be +enough faster than the others to be worth keeping on your machine. (If you +do remove ISLOW or IFAST, be sure to redefine JDCT_DEFAULT or JDCT_FASTEST +to a supported method, by adding a #define in jconfig.h.) + + +OPTIMIZATION +============ + +Unless you own a Cray, you'll probably be interested in making the JPEG +software go as fast as possible. This section covers some machine-dependent +optimizations you may want to try. We suggest that before trying any of +this, you first get the basic installation to pass the self-test step. +Repeat the self-test after any optimization to make sure that you haven't +broken anything. + +The integer DCT routines perform a lot of multiplications. These +multiplications must yield 32-bit results, but none of their input values +are more than 16 bits wide. On many machines, notably the 680x0 and 80x86 +CPUs, a 16x16=>32 bit multiply instruction is faster than a full 32x32=>32 +bit multiply. Unfortunately there is no portable way to specify such a +multiplication in C, but some compilers can generate one when you use the +right combination of casts. See the MULTIPLYxxx macro definitions in +jdct.h. If your compiler makes "int" be 32 bits and "short" be 16 bits, +defining SHORTxSHORT_32 is fairly likely to work. When experimenting with +alternate definitions, be sure to test not only whether the code still works +(use the self-test), but also whether it is actually faster --- on some +compilers, alternate definitions may compute the right answer, yet be slower +than the default. Timing cjpeg on a large PGM (grayscale) input file is the +best way to check this, as the DCT will be the largest fraction of the runtime +in that mode. (Note: some of the distributed compiler-specific jconfig files +already contain #define switches to select appropriate MULTIPLYxxx +definitions.) + +If your machine has sufficiently fast floating point hardware, you may find +that the float DCT method is faster than the integer DCT methods, even +after tweaking the integer multiply macros. In that case you may want to +make the float DCT be the default method. (The only objection to this is +that float DCT results may vary slightly across machines.) To do that, add +"#define JDCT_DEFAULT JDCT_FLOAT" to jconfig.h. Even if you don't change +the default, you should redefine JDCT_FASTEST, which is the method selected +by djpeg's -fast switch. Don't forget to update the documentation files +(usage.doc and/or cjpeg.1, djpeg.1) to agree with what you've done. + +If access to "short" arrays is slow on your machine, it may be a win to +define type JCOEF as int rather than short. This will cost a good deal of +memory though, particularly in some multi-pass modes, so don't do it unless +you have memory to burn and short is REALLY slow. + +If your compiler can compile function calls in-line, make sure the INLINE +macro in jmorecfg.h is defined as the keyword that marks a function +inline-able. Some compilers have a switch that tells the compiler to inline +any function it thinks is profitable (e.g., -finline-functions for gcc). +Enabling such a switch is likely to make the compiled code bigger but faster. + +In general, it's worth trying the maximum optimization level of your compiler, +and experimenting with any optional optimizations such as loop unrolling. +(Unfortunately, far too many compilers have optimizer bugs ... be prepared to +back off if the code fails self-test.) If you do any experimentation along +these lines, please report the optimal settings to jpeg-info@uunet.uu.net so +we can mention them in future releases. Be sure to specify your machine and +compiler version. + + +HINTS FOR SPECIFIC SYSTEMS +========================== + +We welcome reports on changes needed for systems not mentioned here. Submit +'em to jpeg-info@uunet.uu.net. Also, if configure or ckconfig.c is wrong +about how to configure the JPEG software for your system, please let us know. + + +Acorn RISC OS: + +(Thanks to Simon Middleton for these hints on compiling with Desktop C.) +After renaming the files according to Acorn conventions, take a copy of +makefile.ansi, change all occurrences of 'libjpeg.a' to 'libjpeg.o' and +change these definitions as indicated: + +CFLAGS= -throwback -IC: -Wn +LDLIBS=C:o.Stubs +SYSDEPMEM=jmemansi.o +LN=Link +AR=LibFile -c -o + +Also add a new line '.c.o:; $(cc) $< $(cflags) -c -o $@'. Remove the +lines '$(RM) libjpeg.o' and '$(AR2) libjpeg.o' and the 'jconfig.h' +dependency section. + +Copy jconfig.doc to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE +and CHAR_IS_UNSIGNED. + +Run the makefile using !AMU not !Make. If you want to use the 'clean' and +'test' makefile entries then you will have to fiddle with the syntax a bit +and rename the test files. + + +Amiga: + +SAS C 6.50 reportedly is too buggy to compile the IJG code properly. +A patch to update to 6.51 is available from SAS or AmiNet FTP sites. + +The supplied config files are set up to use jmemname.c as the memory +manager, with temporary files being created on the device named by +"JPEGTMP:". + + +Atari ST/STE/TT: + +Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st +to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively. The +project files should work as-is with Pure C. For Turbo C, change library +filenames "pc..." to "tc..." in each project file. Note that libjpeg.prj +selects jmemansi.c as the recommended memory manager. You'll probably want to +adjust the DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K +less than your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into +jconfig.h to do this. + +To use the 68881/68882 coprocessor for the floating point DCT, add the +compiler option "-8" to the project files and replace pcfltlib.lib with +pc881lib.lib in cjpeg.prj and djpeg.prj. Or if you don't have a +coprocessor, you may prefer to remove the float DCT code by undefining +DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float +code will be too slow to be useful). In that case, you can delete +pcfltlib.lib from the project files. + +Note that you must make libjpeg.lib before making cjpeg.ttp, djpeg.ttp, +or jpegtran.ttp. You'll have to perform the self-test by hand. + +We haven't bothered to include project files for rdjpgcom and wrjpgcom. +Those source files should just be compiled by themselves; they don't +depend on the JPEG library. + +There is a bug in some older versions of the Turbo C library which causes the +space used by temporary files created with "tmpfile()" not to be freed after +an abnormal program exit. If you check your disk afterwards, you will find +cluster chains that are allocated but not used by a file. This should not +happen in cjpeg/djpeg/jpegtran, since we enable a signal catcher to explicitly +close temp files before exiting. But if you use the JPEG library with your +own code, be sure to supply a signal catcher, or else use a different +system-dependent memory manager. + + +Cray: + +Should you be so fortunate as to be running JPEG on a Cray YMP, there is a +compiler bug in old versions of Cray's Standard C (prior to 3.1). If you +still have an old compiler, you'll need to insert a line reading +"#pragma novector" just before the loop + for (i = 1; i <= (int) htbl->bits[l]; i++) + huffsize[p++] = (char) l; +in fix_huff_tbl (in V5beta1, line 204 of jchuff.c and line 176 of jdhuff.c). +[This bug may or may not still occur with the current IJG code, but it's +probably a dead issue anyway...] + + +HP-UX: + +If you have HP-UX 7.05 or later with the "software development" C compiler, +you should run the compiler in ANSI mode. If using the configure script, +say + ./configure CC='cc -Aa' +(or -Ae if you prefer). If configuring by hand, use makefile.ansi and add +"-Aa" to the CFLAGS line in the makefile. + +If you have a pre-7.05 system, or if you are using the non-ANSI C compiler +delivered with a minimum HP-UX system, then you must use makefile.unix +(and do NOT add -Aa); or just run configure without the CC option. + +On HP 9000 series 800 machines, the HP C compiler is buggy in revisions prior +to A.08.07. If you get complaints about "not a typedef name", you'll have to +use makefile.unix, or run configure without the CC option. + + +Macintosh, generic comments: + +The supplied user-interface files (cjpeg.c, djpeg.c, etc) are set up to +provide a Unix-style command line interface. You can use this interface on +the Mac by means of the ccommand() library routine provided by Metrowerks +CodeWarrior or Think C. This is only appropriate for testing the library, +however; to make a user-friendly equivalent of cjpeg/djpeg you'd really want +to develop a Mac-style user interface. There isn't a complete example +available at the moment, but there are some helpful starting points: +1. Sam Bushell's free "To JPEG" applet provides drag-and-drop conversion to +JPEG under System 7 and later. This only illustrates how to use the +compression half of the library, but it does a very nice job of that part. +The CodeWarrior source code is available from http://www.pobox.com/~jsam. +2. Jim Brunner prepared a Mac-style user interface for both compression and +decompression. Unfortunately, it hasn't been updated since IJG v4, and +the library's API has changed considerably since then. Still it may be of +some help, particularly as a guide to compiling the IJG code under Think C. +Jim's code is available from the Info-Mac archives, at sumex-aim.stanford.edu +or mirrors thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx. + +jmemmac.c is the recommended memory manager back end for Macintosh. It uses +NewPtr/DisposePtr instead of malloc/free, and has a Mac-specific +implementation of jpeg_mem_available(). It also creates temporary files that +follow Mac conventions. (That part of the code relies on System-7-or-later OS +functions. See the comments in jmemmac.c if you need to run it on System 6.) +NOTE that USE_MAC_MEMMGR must be defined in jconfig.h to use jmemmac.c. + +You can also use jmemnobs.c, if you don't care about handling images larger +than available memory. If you use any memory manager back end other than +jmemmac.c, we recommend replacing "malloc" and "free" by "NewPtr" and +"DisposePtr", because Mac C libraries often have peculiar implementations of +malloc/free. (For instance, free() may not return the freed space to the +Mac Memory Manager. This is undesirable for the IJG code because jmemmgr.c +already clumps space requests.) + + +Macintosh, Metrowerks CodeWarrior: + +The Unix-command-line-style interface can be used by defining USE_CCOMMAND. +You'll also need to define TWO_FILE_COMMANDLINE to avoid stdin/stdout. +This means that when using the cjpeg/djpeg programs, you'll have to type the +input and output file names in the "Arguments" text-edit box, rather than +using the file radio buttons. (Perhaps USE_FDOPEN or USE_SETMODE would +eliminate the problem, but I haven't heard from anyone who's tried it.) + +On 680x0 Macs, Metrowerks defines type "double" as a 10-byte IEEE extended +float. jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power +of 2. Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint. + +The supplied configuration file jconfig.mac can be used for your jconfig.h; +it includes all the recommended symbol definitions. If you have AppleScript +installed, you can run the supplied script makeproj.mac to create CodeWarrior +project files for the library and the testbed applications, then build the +library and applications. (Thanks to Dan Sears and Don Agro for this nifty +hack, which saves us from trying to maintain CodeWarrior project files as part +of the IJG distribution...) + + +Macintosh, Think C: + +The documentation in Jim Brunner's "JPEG Convert" source code (see above) +includes detailed build instructions for Think C; it's probably somewhat +out of date for the current release, but may be helpful. + +If you want to build the minimal command line version, proceed as follows. +You'll have to prepare project files for the programs; we don't include any +in the distribution since they are not text files. Use the file lists in +any of the supplied makefiles as a guide. Also add the ANSI and Unix C +libraries in a separate segment. You may need to divide the JPEG files into +more than one segment; we recommend dividing compression and decompression +modules. Define USE_CCOMMAND in jconfig.h so that the ccommand() routine is +called. You must also define TWO_FILE_COMMANDLINE because stdin/stdout +don't handle binary data correctly. + +On 680x0 Macs, Think C defines type "double" as a 12-byte IEEE extended float. +jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power of 2. +Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint. + +jconfig.mac should work as a jconfig.h configuration file for Think C, +but the makeproj.mac AppleScript script is specific to CodeWarrior. Sorry. + + +MIPS R3000: + +MIPS's cc version 1.31 has a rather nasty optimization bug. Don't use -O +if you have that compiler version. (Use "cc -V" to check the version.) +Note that the R3000 chip is found in workstations from DEC and others. + + +MS-DOS, generic comments for 16-bit compilers: + +The IJG code is designed to work well in 80x86 "small" or "medium" memory +models (i.e., data pointers are 16 bits unless explicitly declared "far"; +code pointers can be either size). You may be able to use small model to +compile cjpeg or djpeg by itself, but you will probably have to use medium +model for any larger application. This won't make much difference in +performance. You *will* take a noticeable performance hit if you use a +large-data memory model, and you should avoid "huge" model if at all +possible. Be sure that NEED_FAR_POINTERS is defined in jconfig.h if you use +a small-data memory model; be sure it is NOT defined if you use a large-data +model. (The supplied makefiles and jconfig files for Borland and Microsoft C +compile in medium model and define NEED_FAR_POINTERS.) + +The DOS-specific memory manager, jmemdos.c, should be used if possible. +It needs some assembly-code routines which are in jmemdosa.asm; make sure +your makefile assembles that file and includes it in the library. If you +don't have a suitable assembler, you can get pre-assembled object files for +jmemdosa by FTP from ftp.uu.net:/graphics/jpeg/jdosaobj.zip. (DOS-oriented +distributions of the IJG source code often include these object files.) + +When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set +MAX_ALLOC_CHUNK to less than 64K (65520L is a typical value). If your +C library's far-heap malloc() can't allocate blocks that large, reduce +MAX_ALLOC_CHUNK to whatever it can handle. + +If you can't use jmemdos.c for some reason --- for example, because you +don't have an assembler to assemble jmemdosa.asm --- you'll have to fall +back to jmemansi.c or jmemname.c. You'll probably still need to set +MAX_ALLOC_CHUNK in jconfig.h, because most DOS C libraries won't malloc() +more than 64K at a time. IMPORTANT: if you use jmemansi.c or jmemname.c, +you will have to compile in a large-data memory model in order to get the +right stdio library. Too bad. + +wrjpgcom needs to be compiled in large model, because it malloc()s a 64KB +work area to hold the comment text. If your C library's malloc can't +handle that, reduce MAX_COM_LENGTH as necessary in wrjpgcom.c. + +Most MS-DOS compilers treat stdin/stdout as text files, so you must use +two-file command line style. But if your compiler has either fdopen() or +setmode(), you can use one-file style if you like. To do this, define +USE_SETMODE or USE_FDOPEN so that stdin/stdout will be set to binary mode. +(USE_SETMODE seems to work with more DOS compilers than USE_FDOPEN.) You +should test that I/O through stdin/stdout produces the same results as I/O +to explicitly named files... the "make test" procedures in the supplied +makefiles do NOT use stdin/stdout. + + +MS-DOS, generic comments for 32-bit compilers: + +None of the above comments about memory models apply if you are using a +32-bit flat-memory-space environment, such as DJGPP or Watcom C. (And you +should use one if you have it, as performance will be much better than +8086-compatible code!) For flat-memory-space compilers, do NOT define +NEED_FAR_POINTERS, and do NOT use jmemdos.c. Use jmemnobs.c if the +environment supplies adequate virtual memory, otherwise use jmemansi.c or +jmemname.c. + +You'll still need to be careful about binary I/O through stdin/stdout. +See the last paragraph of the previous section. + + +MS-DOS, Borland C: + +Be sure to convert all the source files to DOS text format (CR/LF newlines). +Although Borland C will often work OK with unmodified Unix (LF newlines) +source files, sometimes it will give bogus compile errors. +"Illegal character '#'" is the most common such error. (This is true with +Borland C 3.1, but perhaps is fixed in newer releases.) + +If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE. +jconfig.bcc already includes #define USE_SETMODE to make this work. +(fdopen does not work correctly.) + + +MS-DOS, Microsoft C: + +makefile.mc6 works with Microsoft C, DOS Visual C++, etc. It should only +be used if you want to build a 16-bit (small or medium memory model) program. + +If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE. +jconfig.mc6 already includes #define USE_SETMODE to make this work. +(fdopen does not work correctly.) + +Note that this makefile assumes that the working copy of itself is called +"makefile". If you want to call it something else, say "makefile.mak", +be sure to adjust the dependency line that reads "$(RFILE) : makefile". +Otherwise the make will fail because it doesn't know how to create "makefile". +Worse, some releases of Microsoft's make utilities give an incorrect error +message in this situation. + +Old versions of MS C fail with an "out of macro expansion space" error +because they can't cope with the macro TRACEMS8 (defined in jerror.h). +If this happens to you, the easiest solution is to change TRACEMS8 to +expand to nothing. You'll lose the ability to dump out JPEG coefficient +tables with djpeg -debug -debug, but at least you can compile. + +Original MS C 6.0 is very buggy; it compiles incorrect code unless you turn +off optimization entirely (remove -O from CFLAGS). 6.00A is better, but it +still generates bad code if you enable loop optimizations (-Ol or -Ox). + +MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ... +which is on by default. To work around this bug, compile that one file +with /Oo-. + + +Microsoft Windows (all versions), generic comments: + +Some Windows system include files define typedef boolean as "unsigned char". +The IJG code also defines typedef boolean, but we make it "int" by default. +This doesn't affect the IJG programs because we don't import those Windows +include files. But if you use the JPEG library in your own program, and some +of your program's files import one definition of boolean while some import the +other, you can get all sorts of mysterious problems. A good preventive step +is to make the IJG library use "unsigned char" for boolean. To do that, +add something like this to your jconfig.h file: + /* Define "boolean" as unsigned char, not int, per Windows custom */ + #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ + typedef unsigned char boolean; + #endif + #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +(This is already in jconfig.vc, by the way.) + +windef.h contains the declarations + #define far + #define FAR far +Since jmorecfg.h tries to define FAR as empty, you may get a compiler +warning if you include both jpeglib.h and windef.h (which windows.h +includes). To suppress the warning, you can put "#ifndef FAR"/"#endif" +around the line "#define FAR" in jmorecfg.h. + +When using the library in a Windows application, you will almost certainly +want to modify or replace the error handler module jerror.c, since our +default error handler does a couple of inappropriate things: + 1. it tries to write error and warning messages on stderr; + 2. in event of a fatal error, it exits by calling exit(). + +A simple stopgap solution for problem 1 is to replace the line + fprintf(stderr, "%s\n", buffer); +(in output_message in jerror.c) with + MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK|MB_ICONERROR); +It's highly recommended that you at least do that much, since otherwise +error messages will disappear into nowhere. (Beginning with IJG v6b, this +code is already present in jerror.c; just define USE_WINDOWS_MESSAGEBOX in +jconfig.h to enable it.) + +The proper solution for problem 2 is to return control to your calling +application after a library error. This can be done with the setjmp/longjmp +technique discussed in libjpeg.doc and illustrated in example.c. (NOTE: +some older Windows C compilers provide versions of setjmp/longjmp that +don't actually work under Windows. You may need to use the Windows system +functions Catch and Throw instead.) + +The recommended memory manager under Windows is jmemnobs.c; in other words, +let Windows do any virtual memory management needed. You should NOT use +jmemdos.c nor jmemdosa.asm under Windows. + +For Windows 3.1, we recommend compiling in medium or large memory model; +for newer Windows versions, use a 32-bit flat memory model. (See the MS-DOS +sections above for more info about memory models.) In the 16-bit memory +models only, you'll need to put + #define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */ +into jconfig.h to limit allocation chunks to 64Kb. (Without that, you'd +have to use huge memory model, which slows things down unnecessarily.) +jmemnobs.c works without modification in large or flat memory models, but to +use medium model, you need to modify its jpeg_get_large and jpeg_free_large +routines to allocate far memory. In any case, you might like to replace +its calls to malloc and free with direct calls on Windows memory allocation +functions. + +You may also want to modify jdatasrc.c and jdatadst.c to use Windows file +operations rather than fread/fwrite. This is only necessary if your C +compiler doesn't provide a competent implementation of C stdio functions. + +You might want to tweak the RGB_xxx macros in jmorecfg.h so that the library +will accept or deliver color pixels in BGR sample order, not RGB; BGR order +is usually more convenient under Windows. Note that this change will break +the sample applications cjpeg/djpeg, but the library itself works fine. + + +Many people want to convert the IJG library into a DLL. This is reasonably +straightforward, but watch out for the following: + + 1. Don't try to compile as a DLL in small or medium memory model; use +large model, or even better, 32-bit flat model. Many places in the IJG code +assume the address of a local variable is an ordinary (not FAR) pointer; +that isn't true in a medium-model DLL. + + 2. Microsoft C cannot pass file pointers between applications and DLLs. +(See Microsoft Knowledge Base, PSS ID Number Q50336.) So jdatasrc.c and +jdatadst.c don't work if you open a file in your application and then pass +the pointer to the DLL. One workaround is to make jdatasrc.c/jdatadst.c +part of your main application rather than part of the DLL. + + 3. You'll probably need to modify the macros GLOBAL() and EXTERN() to +attach suitable linkage keywords to the exported routine names. Similarly, +you'll want to modify METHODDEF() and JMETHOD() to ensure function pointers +are declared in a way that lets application routines be called back through +the function pointers. These macros are in jmorecfg.h. Typical definitions +for a 16-bit DLL are: + #define GLOBAL(type) type _far _pascal _loadds _export + #define EXTERN(type) extern type _far _pascal _loadds + #define METHODDEF(type) static type _far _pascal + #define JMETHOD(type,methodname,arglist) \ + type (_far _pascal *methodname) arglist +For a 32-bit DLL you may want something like + #define GLOBAL(type) __declspec(dllexport) type + #define EXTERN(type) extern __declspec(dllexport) type +Although not all the GLOBAL routines are actually intended to be called by +the application, the performance cost of making them all DLL entry points is +negligible. + +The unmodified IJG library presents a very C-specific application interface, +so the resulting DLL is only usable from C or C++ applications. There has +been some talk of writing wrapper code that would present a simpler interface +usable from other languages, such as Visual Basic. This is on our to-do list +but hasn't been very high priority --- any volunteers out there? + + +Microsoft Windows, Borland C: + +The provided jconfig.bcc should work OK in a 32-bit Windows environment, +but you'll need to tweak it in a 16-bit environment (you'd need to define +NEED_FAR_POINTERS and MAX_ALLOC_CHUNK). Beware that makefile.bcc will need +alteration if you want to use it for Windows --- in particular, you should +use jmemnobs.c not jmemdos.c under Windows. + +Borland C++ 4.5 fails with an internal compiler error when trying to compile +jdmerge.c in 32-bit mode. If enough people complain, perhaps Borland will fix +it. In the meantime, the simplest known workaround is to add a redundant +definition of the variable range_limit in h2v1_merged_upsample(), at the head +of the block that handles odd image width (about line 268 in v6 jdmerge.c): + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + register JSAMPLE * range_limit = cinfo->sample_range_limit; /* ADD THIS */ + cb = GETJSAMPLE(*inptr1); +Pretty bizarre, especially since the very similar routine h2v2_merged_upsample +doesn't trigger the bug. +Recent reports suggest that this bug does not occur with "bcc32a" (the +Pentium-optimized version of the compiler). + +Another report from a user of Borland C 4.5 was that incorrect code (leading +to a color shift in processed images) was produced if any of the following +optimization switch combinations were used: + -Ot -Og + -Ot -Op + -Ot -Om +So try backing off on optimization if you see such a problem. (Are there +several different releases all numbered "4.5"??) + + +Microsoft Windows, Microsoft Visual C++: + +jconfig.vc should work OK with any Microsoft compiler for a 32-bit memory +model. makefile.vc is intended for command-line use. (If you are using +the Developer Studio environment, you may prefer the DevStudio project +files; see below.) + +Some users feel that it's easier to call the library from C++ code if you +force VC++ to treat the library as C++ code, which you can do by renaming +all the *.c files to *.cpp (and adjusting the makefile to match). This +avoids the need to put extern "C" { ... } around #include "jpeglib.h" in +your C++ application. + + +Microsoft Windows, Microsoft Developer Studio: + +We include makefiles that should work as project files in DevStudio 4.2 or +later. There is a library makefile that builds the IJG library as a static +Win32 library, and an application makefile that builds the sample applications +as Win32 console applications. (Even if you only want the library, we +recommend building the applications so that you can run the self-test.) + +To use: +1. Copy jconfig.vc to jconfig.h, makelib.ds to jpeg.mak, and + makeapps.ds to apps.mak. (Note that the renaming is critical!) +2. Click on the .mak files to construct project workspaces. + (If you are using DevStudio more recent than 4.2, you'll probably + get a message saying that the makefiles are being updated.) +3. Build the library project, then the applications project. +4. Move the application .exe files from `app`\Release to an + appropriate location on your path. +5. To perform the self-test, execute the command line + NMAKE /f makefile.vc test + + +OS/2, Borland C++: + +Watch out for optimization bugs in older Borland compilers; you may need +to back off the optimization switch settings. See the comments in +makefile.bcc. + + +SGI: + +On some SGI systems, you may need to set "AR2= ar -ts" in the Makefile. +If you are using configure, you can do this by saying + ./configure RANLIB='ar -ts' +This change is not needed on all SGIs. Use it only if the make fails at the +stage of linking the completed programs. + +On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2" +reportedly speeds up the float DCT method substantially, enough to make it +faster than the default int method (but still slower than the fast int +method). If you use -mips2, you may want to alter the default DCT method to +be float. To do this, put "#define JDCT_DEFAULT JDCT_FLOAT" in jconfig.h. + + +VMS: + +On an Alpha/VMS system with MMS, be sure to use the "/Marco=Alpha=1" +qualifier with MMS when building the JPEG package. + +VAX/VMS v5.5-1 may have problems with the test step of the build procedure +reporting differences when it compares the original and test images. If the +error points to the last block of the files, it is most likely bogus and may +be safely ignored. It seems to be because the files are Stream_LF and +Backup/Compare has difficulty with the (presumably) null padded files. +This problem was not observed on VAX/VMS v6.1 or AXP/VMS v6.1. diff --git a/src/dep/src/irrlicht/jpeglib/jcapimin.c b/src/dep/src/irrlicht/jpeglib/jcapimin.c new file mode 100644 index 0000000..493af5c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcapimin.c @@ -0,0 +1,280 @@ +/* + * jcapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-compression case or the transcoding-only + * case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jcapistd.c. But also see jcparam.c for + * parameter-setup helper routines, jcomapi.c for routines shared by + * compression and decompression, and jctrans.c for the transcoding case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG compression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) +{ + int i; + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_compress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = FALSE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->dest = NULL; + + cinfo->comp_info = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + cinfo->script_space = NULL; + + cinfo->input_gamma = 1.0; /* in case application forgets */ + + /* OK, I'm ready */ + cinfo->global_state = CSTATE_START; +} + + +/* + * Destruction of a JPEG compression object + */ + +GLOBAL(void) +jpeg_destroy_compress (j_compress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG compression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_compress (j_compress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Forcibly suppress or un-suppress all quantization and Huffman tables. + * Marks all currently defined tables as already written (if suppress) + * or not written (if !suppress). This will control whether they get emitted + * by a subsequent jpeg_start_compress call. + * + * This routine is exported for use by applications that want to produce + * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + * since it is called by jpeg_start_compress, we put it here --- otherwise + * jcparam.o would be linked whether the application used it or not. + */ + +GLOBAL(void) +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) +{ + int i; + JQUANT_TBL * qtbl; + JHUFF_TBL * htbl; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL) + qtbl->sent_table = suppress; + } + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL) + htbl->sent_table = suppress; + } +} + + +/* + * Finish JPEG compression. + * + * If a multipass operating mode was selected, this may do a great deal of + * work including most of the actual output. + */ + +GLOBAL(void) +jpeg_finish_compress (j_compress_ptr cinfo) +{ + JDIMENSION iMCU_row; + + if (cinfo->global_state == CSTATE_SCANNING || + cinfo->global_state == CSTATE_RAW_OK) { + /* Terminate first pass */ + if (cinfo->next_scanline < cinfo->image_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_pass) (cinfo); + } else if (cinfo->global_state != CSTATE_WRCOEFS) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any remaining passes */ + while (! cinfo->master->is_last_pass) { + (*cinfo->master->prepare_for_pass) (cinfo); + for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) iMCU_row; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* We bypass the main controller and invoke coef controller directly; + * all work is being done from the coefficient buffer. + */ + if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } + (*cinfo->master->finish_pass) (cinfo); + } + /* Write EOI, do final cleanup */ + (*cinfo->marker->write_file_trailer) (cinfo); + (*cinfo->dest->term_destination) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); +} + + +/* + * Write a special marker. + * This is only recommended for writing COM or APPn markers. + * Must be called after jpeg_start_compress() and before + * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). + */ + +GLOBAL(void) +jpeg_write_marker (j_compress_ptr cinfo, int marker, + const JOCTET *dataptr, unsigned int datalen) +{ + JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val)); + + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); + write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ + while (datalen--) { + (*write_marker_byte) (cinfo, *dataptr); + dataptr++; + } +} + +/* Same, but piecemeal. */ + +GLOBAL(void) +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +{ + if (cinfo->next_scanline != 0 || + (cinfo->global_state != CSTATE_SCANNING && + cinfo->global_state != CSTATE_RAW_OK && + cinfo->global_state != CSTATE_WRCOEFS)) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); +} + +GLOBAL(void) +jpeg_write_m_byte (j_compress_ptr cinfo, int val) +{ + (*cinfo->marker->write_marker_byte) (cinfo, val); +} + + +/* + * Alternate compression function: just write an abbreviated table file. + * Before calling this, all parameters and a data destination must be set up. + * + * To produce a pair of files containing abbreviated tables and abbreviated + * image data, one would proceed as follows: + * + * initialize JPEG object + * set JPEG parameters + * set destination to table file + * jpeg_write_tables(cinfo); + * set destination to image file + * jpeg_start_compress(cinfo, FALSE); + * write data... + * jpeg_finish_compress(cinfo); + * + * jpeg_write_tables has the side effect of marking all tables written + * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + * will not re-emit the tables unless it is passed write_all_tables=TRUE. + */ + +GLOBAL(void) +jpeg_write_tables (j_compress_ptr cinfo) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Initialize the marker writer ... bit of a crock to do it here. */ + jinit_marker_writer(cinfo); + /* Write them tables! */ + (*cinfo->marker->write_tables_only) (cinfo); + /* And clean up. */ + (*cinfo->dest->term_destination) (cinfo); + /* + * In library releases up through v6a, we called jpeg_abort() here to free + * any working memory allocated by the destination manager and marker + * writer. Some applications had a problem with that: they allocated space + * of their own from the library memory manager, and didn't want it to go + * away during write_tables. So now we do nothing. This will cause a + * memory leak if an app calls write_tables repeatedly without doing a full + * compression cycle or otherwise resetting the JPEG object. However, that + * seems less bad than unexpectedly freeing memory in the normal case. + * An app that prefers the old behavior can call jpeg_abort for itself after + * each call to jpeg_write_tables(). + */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jcapistd.c b/src/dep/src/irrlicht/jpeglib/jcapistd.c new file mode 100644 index 0000000..fed66ca --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcapistd.c @@ -0,0 +1,161 @@ +/* + * jcapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the compression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-compression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_compress, it will end up linking in the entire compressor. + * We thus must separate this file from jcapimin.c to avoid linking the + * whole compression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Compression initialization. + * Before calling this, all parameters and a data destination must be set up. + * + * We require a write_all_tables parameter as a failsafe check when writing + * multiple datastreams from the same compression object. Since prior runs + * will have left all the tables marked sent_table=TRUE, a subsequent run + * would emit an abbreviated stream (no tables) by default. This may be what + * is wanted, but for safety's sake it should not be the default behavior: + * programmers should have to make a deliberate choice to emit abbreviated + * images. Therefore the documentation and examples should encourage people + * to pass write_all_tables=TRUE; then it will take active thought to do the + * wrong thing. + */ + +GLOBAL(void) +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (write_all_tables) + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + jinit_compress_master(cinfo); + /* Set up for the first pass */ + (*cinfo->master->prepare_for_pass) (cinfo); + /* Ready for application to drive first pass through jpeg_write_scanlines + * or jpeg_write_raw_data. + */ + cinfo->next_scanline = 0; + cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); +} + + +/* + * Write some scanlines of data to the JPEG compressor. + * + * The return value will be the number of lines actually written. + * This should be less than the supplied num_lines only in case that + * the data destination module has requested suspension of the compressor, + * or if more than image_height scanlines are passed in. + * + * Note: we warn about excess calls to jpeg_write_scanlines() since + * this likely signals an application programmer error. However, + * excess scanlines passed in the last valid call are *silently* ignored, + * so that the application need not adjust num_lines for end-of-image + * when using a multiple-scanline buffer. + */ + +GLOBAL(JDIMENSION) +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION num_lines) +{ + JDIMENSION row_ctr, rows_left; + + if (cinfo->global_state != CSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_scanlines. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_scanlines. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Ignore any extra scanlines at bottom of image. */ + rows_left = cinfo->image_height - cinfo->next_scanline; + if (num_lines > rows_left) + num_lines = rows_left; + + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); + cinfo->next_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to write raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION num_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != CSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->next_scanline >= cinfo->image_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->next_scanline; + cinfo->progress->pass_limit = (long) cinfo->image_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Give master control module another chance if this is first call to + * jpeg_write_raw_data. This lets output of the frame/scan headers be + * delayed so that application can write COM, etc, markers between + * jpeg_start_compress and jpeg_write_raw_data. + */ + if (cinfo->master->call_pass_startup) + (*cinfo->master->pass_startup) (cinfo); + + /* Verify that at least one iMCU row has been passed. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Directly compress the row. */ + if (! (*cinfo->coef->compress_data) (cinfo, data)) { + /* If compressor did not consume the whole row, suspend processing. */ + return 0; + } + + /* OK, we processed one iMCU row. */ + cinfo->next_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} diff --git a/src/dep/src/irrlicht/jpeglib/jccoefct.c b/src/dep/src/irrlicht/jpeglib/jccoefct.c new file mode 100644 index 0000000..c713b85 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jccoefct.c @@ -0,0 +1,449 @@ +/* + * jccoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for compression. + * This controller is the top level of the JPEG compressor proper. + * The coefficient buffer lies between forward-DCT and entropy encoding steps. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* We use a full-image coefficient buffer when doing Huffman optimization, + * and also for writing multiple-scan JPEG files. In all cases, the DCT + * step is run during the first pass, and subsequent passes need only read + * the buffered coefficients. + */ +#ifdef ENTROPY_OPT_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#else +#ifdef C_MULTISCAN_FILES_SUPPORTED +#define FULL_COEF_BUFFER_SUPPORTED +#endif +#endif + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* For single-pass compression, it's sufficient to buffer just one MCU + * (although this may prove a bit slow in practice). We allocate a + * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + * MCU constructed and sent. (On 80x86, the workspace is FAR even though + * it's not really very big; this is to keep the module interfaces unchanged + * when a large coefficient buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays. + */ + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +/* Forward declarations */ +METHODDEF(boolean) compress_data + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#ifdef FULL_COEF_BUFFER_SUPPORTED +METHODDEF(boolean) compress_first_pass + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +METHODDEF(boolean) compress_output + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (coef->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_data; + break; +#ifdef FULL_COEF_BUFFER_SUPPORTED + case JBUF_SAVE_AND_PASS: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_first_pass; + break; + case JBUF_CRANK_DEST: + if (coef->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + coef->pub.compress_data = compress_output; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data in the single-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(boolean) +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, bi, ci, yindex, yoffset, blockcnt; + JDIMENSION ypos, xpos; + jpeg_component_info *compptr; + + /* Loop to write as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Determine where data comes from in input_buf and do the DCT thing. + * Each call on forward_DCT processes a horizontal row of DCT blocks + * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + * sequentially. Dummy blocks at the right or bottom edge are filled in + * specially. The data in them does not matter for image reconstruction, + * so we fill them with values that will encode to the smallest amount of + * data, viz: all zeroes in the AC entries, DC entries equal to previous + * block's DC value. (Thanks to Thomas Kinsman for this idea.) + */ + blkn = 0; + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + xpos = MCU_col_num * compptr->MCU_sample_width; + ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[compptr->component_index], + coef->MCU_buffer[blkn], + ypos, xpos, (JDIMENSION) blockcnt); + if (blockcnt < compptr->MCU_width) { + /* Create some dummy blocks at the right edge of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], + (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for (bi = blockcnt; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; + } + } + } else { + /* Create a row of dummy blocks at the bottom of the image. */ + jzero_far((void FAR *) coef->MCU_buffer[blkn], + compptr->MCU_width * SIZEOF(JBLOCK)); + for (bi = 0; bi < compptr->MCU_width; bi++) { + coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; + } + } + blkn += compptr->MCU_width; + ypos += DCTSIZE; + } + } + /* Try to write the MCU. In event of a suspension failure, we will + * re-DCT the MCU on restart (a bit inefficient, could be fixed...) + */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +#ifdef FULL_COEF_BUFFER_SUPPORTED + +/* + * Process some data in the first pass of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the image. + * This amount of data is read from the source buffer, DCT'd and quantized, + * and saved into the virtual arrays. We also generate suitable dummy blocks + * as needed at the right and lower edges. (The dummy blocks are constructed + * in the virtual arrays, which have been padded appropriately.) This makes + * it possible for subsequent passes not to worry about real vs. dummy blocks. + * + * We must also emit the data to the entropy encoder. This is conveniently + * done by calling compress_output() after we've loaded the current strip + * of the virtual arrays. + * + * NB: input_buf contains a plane for each component in image. All + * components are DCT'd and loaded into the virtual arrays in this pass. + * However, it may be that only a subset of the components are emitted to + * the entropy encoder during this first pass; be careful about looking + * at the scan-dependent variables (MCU dimensions, etc). + */ + +METHODDEF(boolean) +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION blocks_across, MCUs_across, MCUindex; + int bi, ci, h_samp_factor, block_row, block_rows, ndummy; + JCOEF lastDC; + jpeg_component_info *compptr; + JBLOCKARRAY buffer; + JBLOCKROW thisblockrow, lastblockrow; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (coef->iMCU_row_num < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + blocks_across = compptr->width_in_blocks; + h_samp_factor = compptr->h_samp_factor; + /* Count number of dummy blocks to be added at the right margin. */ + ndummy = (int) (blocks_across % h_samp_factor); + if (ndummy > 0) + ndummy = h_samp_factor - ndummy; + /* Perform DCT for all non-dummy blocks in this iMCU row. Each call + * on forward_DCT processes a complete horizontal row of DCT blocks. + */ + for (block_row = 0; block_row < block_rows; block_row++) { + thisblockrow = buffer[block_row]; + (*cinfo->fdct->forward_DCT) (cinfo, compptr, + input_buf[ci], thisblockrow, + (JDIMENSION) (block_row * DCTSIZE), + (JDIMENSION) 0, blocks_across); + if (ndummy > 0) { + /* Create dummy blocks at the right edge of the image. */ + thisblockrow += blocks_across; /* => first dummy block */ + jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); + lastDC = thisblockrow[-1][0]; + for (bi = 0; bi < ndummy; bi++) { + thisblockrow[bi][0] = lastDC; + } + } + } + /* If at end of image, create dummy block rows as needed. + * The tricky part here is that within each MCU, we want the DC values + * of the dummy blocks to match the last real block's DC value. + * This squeezes a few more bytes out of the resulting file... + */ + if (coef->iMCU_row_num == last_iMCU_row) { + blocks_across += ndummy; /* include lower right corner */ + MCUs_across = blocks_across / h_samp_factor; + for (block_row = block_rows; block_row < compptr->v_samp_factor; + block_row++) { + thisblockrow = buffer[block_row]; + lastblockrow = buffer[block_row-1]; + jzero_far((void FAR *) thisblockrow, + (size_t) (blocks_across * SIZEOF(JBLOCK))); + for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { + lastDC = lastblockrow[h_samp_factor-1][0]; + for (bi = 0; bi < h_samp_factor; bi++) { + thisblockrow[bi][0] = lastDC; + } + thisblockrow += h_samp_factor; /* advance to next MCU in row */ + lastblockrow += h_samp_factor; + } + } + } + } + /* NB: compress_output will increment iMCU_row_num if successful. + * A suspension return will result in redoing all the work above next time. + */ + + /* Emit data to the entropy encoder, sharing code with subsequent passes */ + return compress_output(cinfo, input_buf); +} + + +/* + * Process some data in subsequent passes of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. + * NB: during first pass, this is safe only because the buffers will + * already be aligned properly, so jmemmgr.c won't need to do any I/O. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + +#endif /* FULL_COEF_BUFFER_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef FULL_COEF_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + int ci; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->whole_image[0] = NULL; /* flag for no virtual arrays */ + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jccolor.c b/src/dep/src/irrlicht/jpeglib/jccolor.c new file mode 100644 index 0000000..2663724 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jccolor.c @@ -0,0 +1,459 @@ +/* + * jccolor.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_converter pub; /* public fields */ + + /* Private state for RGB->YCC conversion */ + INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ +} my_color_converter; + +typedef my_color_converter * my_cconvert_ptr; + + +/**************** RGB -> YCbCr conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + * were not represented exactly. Now we sacrifice exact representation of + * maximum red and maximum blue in order to get exact grayscales. + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times R,G,B for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + * in the tables to save adding them separately in the inner loop. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS) +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L< Y section */ +#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ +#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ +#define R_CB_OFF (3*(MAXJSAMPLE+1)) +#define G_CB_OFF (4*(MAXJSAMPLE+1)) +#define B_CB_OFF (5*(MAXJSAMPLE+1)) +#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ +#define G_CR_OFF (6*(MAXJSAMPLE+1)) +#define B_CR_OFF (7*(MAXJSAMPLE+1)) +#define TABLE_SIZE (8*(MAXJSAMPLE+1)) + + +/* + * Initialize for RGB->YCC colorspace conversion. + */ + +METHODDEF(void) +rgb_ycc_start (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + INT32 * rgb_ycc_tab; + INT32 i; + + /* Allocate and fill in the conversion tables. */ + cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))); + + for (i = 0; i <= MAXJSAMPLE; i++) { + rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; + rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; + rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; + rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; + /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + * This ensures that the maximum output will round to MAXJSAMPLE + * not MAXJSAMPLE+1, and thus that we don't have to range-limit. + */ + rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +/* B=>Cb and R=>Cr tables are the same + rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; +*/ + rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; + rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * + * Note that we change from the application's interleaved-pixel format + * to our internal noninterleaved, one-plane-per-component format. + * The input buffer is therefore three times as wide as the output buffer. + * + * A starting row offset is provided only for the output buffer. The caller + * can easily adjust the passed input_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +rgb_ycc_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/**************** Cases other than RGB -> YCbCr **************/ + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles RGB->grayscale conversion, which is the same + * as the RGB->Y portion of RGB->YCbCr. + * We assume rgb_ycc_start has been called (we only use the Y tables). + */ + +METHODDEF(void) +rgb_gray_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = GETJSAMPLE(inptr[RGB_RED]); + g = GETJSAMPLE(inptr[RGB_GREEN]); + b = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + /* Y */ + outptr[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles Adobe-style CMYK->YCCK conversion, + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + * conversion as above, while passing K (black) unchanged. + * We assume rgb_ycc_start has been called. + */ + +METHODDEF(void) +cmyk_ycck_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int r, g, b; + register INT32 * ctab = cconvert->rgb_ycc_tab; + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2, outptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + outptr3 = output_buf[3][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); + g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); + b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); + /* K passes through as-is */ + outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ + inptr += 4; + /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations + * must be too; we do not need an explicit range-limiting operation. + * Hence the value being shifted is never negative, and we don't + * need the general RIGHT_SHIFT macro. + */ + /* Y */ + outptr0[col] = (JSAMPLE) + ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) + >> SCALEBITS); + /* Cb */ + outptr1[col] = (JSAMPLE) + ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) + >> SCALEBITS); + /* Cr */ + outptr2[col] = (JSAMPLE) + ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) + >> SCALEBITS); + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles grayscale output with no conversion. + * The source can be either plain grayscale or YCbCr (since Y == gray). + */ + +METHODDEF(void) +grayscale_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + int instride = cinfo->input_components; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr = output_buf[0][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ + inptr += instride; + } + } +} + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles multi-component colorspaces without conversion. + * We assume input_components == num_components. + */ + +METHODDEF(void) +null_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr; + register JDIMENSION col; + register int ci; + int nc = cinfo->num_components; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + /* It seems fastest to make a separate pass for each component. */ + for (ci = 0; ci < nc; ci++) { + inptr = *input_buf; + outptr = output_buf[ci][output_row]; + for (col = 0; col < num_cols; col++) { + outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ + inptr += nc; + } + } + input_buf++; + output_row++; + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +null_method (j_compress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for input colorspace conversion. + */ + +GLOBAL(void) +jinit_color_converter (j_compress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_converter)); + cinfo->cconvert = (struct jpeg_color_converter *) cconvert; + /* set start_pass to null method until we find out differently */ + cconvert->pub.start_pass = null_method; + + /* Make sure input_components agrees with in_color_space */ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + if (cinfo->input_components != 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + if (cinfo->input_components != RGB_PIXELSIZE) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; +#endif /* else share code with YCbCr */ + + case JCS_YCbCr: + if (cinfo->input_components != 3) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->input_components != 4) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->input_components < 1) + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + break; + } + + /* Check num_components, set conversion method based on requested space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_GRAYSCALE) + cconvert->pub.color_convert = grayscale_convert; + else if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_gray_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = grayscale_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_RGB) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = rgb_ycc_convert; + } else if (cinfo->in_color_space == JCS_YCbCr) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + if (cinfo->in_color_space == JCS_CMYK) { + cconvert->pub.start_pass = rgb_ycc_start; + cconvert->pub.color_convert = cmyk_ycck_convert; + } else if (cinfo->in_color_space == JCS_YCCK) + cconvert->pub.color_convert = null_convert; + else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: /* allow null conversion of JCS_UNKNOWN */ + if (cinfo->jpeg_color_space != cinfo->in_color_space || + cinfo->num_components != cinfo->input_components) + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + cconvert->pub.color_convert = null_convert; + break; + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jcdctmgr.c b/src/dep/src/irrlicht/jpeglib/jcdctmgr.c new file mode 100644 index 0000000..e3f90dc --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcdctmgr.c @@ -0,0 +1,387 @@ +/* + * jcdctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the forward-DCT management logic. + * This code selects a particular DCT implementation to be used, + * and it performs related housekeeping chores including coefficient + * quantization. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_forward_dct pub; /* public fields */ + + /* Pointer to the DCT routine actually in use */ + forward_DCT_method_ptr do_dct; + + /* The actual post-DCT divisors --- not identical to the quant table + * entries, because of scaling (especially for an unnormalized DCT). + * Each table is given in normal array order. + */ + DCTELEM * divisors[NUM_QUANT_TBLS]; + +#ifdef DCT_FLOAT_SUPPORTED + /* Same as above for the floating-point case. */ + float_DCT_method_ptr do_float_dct; + FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; +#endif +} my_fdct_controller; + +typedef my_fdct_controller * my_fdct_ptr; + + +/* + * Initialize for a processing pass. + * Verify that all referenced Q-tables are present, and set up + * the divisor table for each one. + * In the current implementation, DCT of all components is done during + * the first pass, even if only some components will be output in the + * first scan. Hence all components should be examined here. + */ + +METHODDEF(void) +start_pass_fdctmgr (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + int ci, qtblno, i; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + DCTELEM * dtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + qtblno = compptr->quant_tbl_no; + /* Make sure specified quantization table is present */ + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + qtbl = cinfo->quant_tbl_ptrs[qtblno]; + /* Compute divisors for this quant table */ + /* We may do this more than once for same table, but it's not a big deal */ + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + /* For LL&M IDCT method, divisors are equal to raw quantization + * coefficients multiplied by 8 (to counteract scaling). + */ + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + */ +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + if (fdct->divisors[qtblno] == NULL) { + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = (DCTELEM) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-3); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + FAST_FLOAT * fdtbl; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + if (fdct->float_divisors[qtblno] == NULL) { + fdct->float_divisors[qtblno] = (FAST_FLOAT *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)); + } + fdtbl = fdct->float_divisors[qtblno]; + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fdtbl[i] = (FAST_FLOAT) + (1.0 / (((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Perform forward DCT on one or more blocks of a component. + * + * The input samples are taken from the sample_data[] array starting at + * position start_row/start_col, and moving to the right for any additional + * blocks. The quantized coefficients are returned in coef_blocks[]. + */ + +METHODDEF(void) +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for integer DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + forward_DCT_method_ptr do_dct = fdct->do_dct; + DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register DCTELEM *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register DCTELEM temp, qval; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ +#ifdef FAST_DIVIDE +#define DIVIDE_BY(a,b) a /= b +#else +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#endif + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; + } + } + } +} + + +#ifdef DCT_FLOAT_SUPPORTED + +METHODDEF(void) +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) +/* This version is used for floating-point DCT implementations. */ +{ + /* This routine is heavily used, so it's worth coding it tightly. */ + my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + float_DCT_method_ptr do_dct = fdct->do_float_dct; + FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; + FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + JDIMENSION bi; + + sample_data += start_row; /* fold in the vertical offset once */ + + for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { + /* Load data into workspace, applying unsigned->signed conversion */ + { register FAST_FLOAT *workspaceptr; + register JSAMPROW elemptr; + register int elemr; + + workspaceptr = workspace; + for (elemr = 0; elemr < DCTSIZE; elemr++) { + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); +#else + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = (FAST_FLOAT) + (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + } + } +#endif + } + } + + /* Perform the DCT */ + (*do_dct) (workspace); + + /* Quantize/descale the coefficients, and store into coef_blocks[] */ + { register FAST_FLOAT temp; + register int i; + register JCOEFPTR output_ptr = coef_blocks[bi]; + + for (i = 0; i < DCTSIZE2; i++) { + /* Apply the quantization and scaling factor */ + temp = workspace[i] * divisors[i]; + /* Round to nearest integer. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * The maximum coefficient size is +-16K (for 12-bit data), so this + * code should work for either 16-bit or 32-bit ints. + */ + output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); + } + } + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ + + +/* + * Initialize FDCT manager. + */ + +GLOBAL(void) +jinit_forward_dct (j_compress_ptr cinfo) +{ + my_fdct_ptr fdct; + int i; + + fdct = (my_fdct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_fdct_controller)); + cinfo->fdct = (struct jpeg_forward_dct *) fdct; + fdct->pub.start_pass = start_pass_fdctmgr; + + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_islow; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + fdct->pub.forward_DCT = forward_DCT; + fdct->do_dct = jpeg_fdct_ifast; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + fdct->pub.forward_DCT = forward_DCT_float; + fdct->do_float_dct = jpeg_fdct_float; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + + /* Mark divisor tables unallocated */ + for (i = 0; i < NUM_QUANT_TBLS; i++) { + fdct->divisors[i] = NULL; +#ifdef DCT_FLOAT_SUPPORTED + fdct->float_divisors[i] = NULL; +#endif + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jchuff.c b/src/dep/src/irrlicht/jpeglib/jchuff.c new file mode 100644 index 0000000..16d9366 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jchuff.c @@ -0,0 +1,909 @@ +/* + * jchuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jcphuff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + savable_state saved; /* Bit buffer & DC state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * dc_count_ptrs[NUM_HUFF_TBLS]; + long * ac_count_ptrs[NUM_HUFF_TBLS]; +#endif +} huff_entropy_encoder; + +typedef huff_entropy_encoder * huff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF(void) +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + entropy->pub.encode_mcu = encode_mcu_gather; + entropy->pub.finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + entropy->pub.encode_mcu = encode_mcu_huff; + entropy->pub.finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->dc_count_ptrs[dctbl] == NULL) + entropy->dc_count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy->ac_count_ptrs[actbl] == NULL) + entropy->ac_count_ptrs[actbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jcphuff.c. + */ + +GLOBAL(void) +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + c_derived_tbl *dtbl; + int p, i, l, lastp, si, maxsymbol; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (c_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_derived_tbl)); + dtbl = *pdtbl; + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + lastp = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure C.3: generate encoding tables */ + /* These are code and size indexed by symbol value */ + + /* Set all codeless symbols to have code length 0; + * this lets us detect duplicate VAL entries here, and later + * allows emit_bits to detect any attempt to emit such symbols. + */ + MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); + + /* This is also a convenient place to check for out-of-range + * and duplicated VAL entries. We allow 0..255 for AC symbols + * but only 0..15 for DC. (We could constrain them further + * based on data depth and mode, but this seems enough.) + */ + maxsymbol = isDC ? 15 : 255; + + for (p = 0; p < lastp; p++) { + i = htbl->huffval[p]; + if (i < 0 || i > maxsymbol || dtbl->ehufsi[i]) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + dtbl->ehufco[i] = huffcode[p]; + dtbl->ehufsi[i] = huffsize[p]; + } +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL(boolean) +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(boolean) +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL(boolean) +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* Encode a single block's worth of coefficients */ + +LOCAL(boolean) +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, + c_derived_tbl *dctbl, c_derived_tbl *actbl) +{ + register int temp, temp2; + register int nbits; + register int k, r, i; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = temp2 = block[0] - last_dc_val; + + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + i = (r << 4) + nbits; + if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) + return FALSE; + + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(boolean) +emit_restart (working_state * state, int restart_num) +{ + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +METHODDEF(boolean) +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], state.cur.last_dc_val[ci], + entropy->dc_derived_tbls[compptr->dc_tbl_no], + entropy->ac_derived_tbls[compptr->ac_tbl_no])) + return FALSE; + /* Update last_dc_val */ + state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF(void) +finish_pass_huff (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + + +/* Process a single block's worth of coefficients */ + +LOCAL(void) +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, + long dc_counts[], long ac_counts[]) +{ + register int temp; + register int nbits; + register int k, r; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = block[0] - last_dc_val; + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + ac_counts[0]++; +} + + +/* + * Trial-encode one MCU's worth of Huffman-compressed coefficients. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF(boolean) +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn, ci; + jpeg_component_info * compptr; + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + entropy->dc_count_ptrs[compptr->dc_tbl_no], + entropy->ac_count_ptrs[compptr->ac_tbl_no]); + entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + return TRUE; +} + + +/* + * Generate the best Huffman code table for the given counts, fill htbl. + * Note this is also used by jcphuff.c. + * + * The JPEG standard requires that no symbol be assigned a codeword of all + * one bits (so that padding bits added at the end of a compressed segment + * can't look like a valid code). Because of the canonical ordering of + * codewords, this just means that there must be an unused slot in the + * longest codeword length category. Section K.2 of the JPEG spec suggests + * reserving such a slot by pretending that symbol 256 is a valid symbol + * with count 1. In theory that's not optimal; giving it count zero but + * including it in the symbol set anyway should give a better Huffman code. + * But the theoretically better code actually seems to come out worse in + * practice, because it produces more all-ones bytes (which incur stuffed + * zero bytes in the final file). In any case the difference is tiny. + * + * The JPEG standard requires Huffman codes to be no more than 16 bits long. + * If some symbols have a very small but nonzero probability, the Huffman tree + * must be adjusted to meet the code length restriction. We currently use + * the adjustment method suggested in JPEG section K.2. This method is *not* + * optimal; it may not choose the best possible limited-length code. But + * typically only very-low-frequency symbols will be given less-than-optimal + * lengths, so the code is almost optimal. Experimental comparisons against + * an optimal limited-length-code algorithm indicate that the difference is + * microscopic --- usually less than a hundredth of a percent of total size. + * So the extra complexity of an optimal algorithm doesn't seem worthwhile. + */ + +GLOBAL(void) +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) +{ +#define MAX_CLEN 32 /* assumed maximum initial code length */ + UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ + int codesize[257]; /* codesize[k] = code length of symbol k */ + int others[257]; /* next symbol in current branch of tree */ + int c1, c2; + int p, i, j; + long v; + + /* This algorithm is explained in section K.2 of the JPEG standard */ + + MEMZERO(bits, SIZEOF(bits)); + MEMZERO(codesize, SIZEOF(codesize)); + for (i = 0; i < 257; i++) + others[i] = -1; /* init links to empty */ + + freq[256] = 1; /* make sure 256 has a nonzero count */ + /* Including the pseudo-symbol 256 in the Huffman procedure guarantees + * that no real symbol is given code-value of all ones, because 256 + * will be placed last in the largest codeword category. + */ + + /* Huffman's basic algorithm to assign optimal code lengths to symbols */ + + for (;;) { + /* Find the smallest nonzero frequency, set c1 = its symbol */ + /* In case of ties, take the larger symbol number */ + c1 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v) { + v = freq[i]; + c1 = i; + } + } + + /* Find the next smallest nonzero frequency, set c2 = its symbol */ + /* In case of ties, take the larger symbol number */ + c2 = -1; + v = 1000000000L; + for (i = 0; i <= 256; i++) { + if (freq[i] && freq[i] <= v && i != c1) { + v = freq[i]; + c2 = i; + } + } + + /* Done if we've merged everything into one frequency */ + if (c2 < 0) + break; + + /* Else merge the two counts/trees */ + freq[c1] += freq[c2]; + freq[c2] = 0; + + /* Increment the codesize of everything in c1's tree branch */ + codesize[c1]++; + while (others[c1] >= 0) { + c1 = others[c1]; + codesize[c1]++; + } + + others[c1] = c2; /* chain c2 onto c1's tree branch */ + + /* Increment the codesize of everything in c2's tree branch */ + codesize[c2]++; + while (others[c2] >= 0) { + c2 = others[c2]; + codesize[c2]++; + } + } + + /* Now count the number of symbols of each code length */ + for (i = 0; i <= 256; i++) { + if (codesize[i]) { + /* The JPEG standard seems to think that this can't happen, */ + /* but I'm paranoid... */ + if (codesize[i] > MAX_CLEN) + ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); + + bits[codesize[i]]++; + } + } + + /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + * Huffman procedure assigned any such lengths, we must adjust the coding. + * Here is what the JPEG spec says about how this next bit works: + * Since symbols are paired for the longest Huffman code, the symbols are + * removed from this length category two at a time. The prefix for the pair + * (which is one bit shorter) is allocated to one of the pair; then, + * skipping the BITS entry for that prefix length, a code word from the next + * shortest nonzero BITS entry is converted into a prefix for two code words + * one bit longer. + */ + + for (i = MAX_CLEN; i > 16; i--) { + while (bits[i] > 0) { + j = i - 2; /* find length of new prefix to be used */ + while (bits[j] == 0) + j--; + + bits[i] -= 2; /* remove two symbols */ + bits[i-1]++; /* one goes in this length */ + bits[j+1] += 2; /* two new symbols in this length */ + bits[j]--; /* symbol of this length is now a prefix */ + } + } + + /* Remove the count for the pseudo-symbol 256 from the largest codelength */ + while (bits[i] == 0) /* find largest codelength still in use */ + i--; + bits[i]--; + + /* Return final symbol counts (only for lengths 0..16) */ + MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits)); + + /* Return a list of the symbols sorted by code length */ + /* It's not real clear to me why we don't need to consider the codelength + * changes made above, but the JPEG spec seems to think this works. + */ + p = 0; + for (i = 1; i <= MAX_CLEN; i++) { + for (j = 0; j <= 255; j++) { + if (codesize[j] == i) { + htbl->huffval[p] = (UINT8) j; + p++; + } + } + } + + /* Set sent_table FALSE so updated table will be written to JPEG file. */ + htbl->sent_table = FALSE; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + boolean did_ac[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + MEMZERO(did_ac, SIZEOF(did_ac)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + if (! did_ac[actbl]) { + htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); + did_ac[actbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_huff_encoder (j_compress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_huff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; +#endif + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jchuff.h b/src/dep/src/irrlicht/jpeglib/jchuff.h new file mode 100644 index 0000000..8c02c09 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jchuff.h @@ -0,0 +1,47 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* The legal range of a DCT coefficient is + * -1024 .. +1023 for 8-bit data; + * -16384 .. +16383 for 12-bit data. + * Hence the magnitude should always fit in 10 or 14 bits respectively. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MAX_COEF_BITS 10 +#else +#define MAX_COEF_BITS 14 +#endif + +/* Derived data constructed for each Huffman table */ + +typedef struct { + unsigned int ehufco[256]; /* code for each symbol */ + char ehufsi[256]; /* length of code for each symbol */ + /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Expand a Huffman table definition into the derived format */ +EXTERN(void) jpeg_make_c_derived_tbl + JPP((j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl)); + +/* Generate an optimal table definition given the specified counts */ +EXTERN(void) jpeg_gen_optimal_table + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/src/dep/src/irrlicht/jpeglib/jcinit.c b/src/dep/src/irrlicht/jpeglib/jcinit.c new file mode 100644 index 0000000..19de8d0 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcinit.c @@ -0,0 +1,72 @@ +/* + * jcinit.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains initialization logic for the JPEG compressor. + * This routine is in charge of selecting the modules to be executed and + * making an initialization call to each one. + * + * Logically, this code belongs in jcmaster.c. It's split out because + * linking this routine implies linking the entire compression library. + * For a transcoding-only application, we want to be able to use jcmaster.c + * without linking in the whole library. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Master selection of compression modules. + * This is done once at the start of processing an image. We determine + * which modules will be used and give them appropriate initialization calls. + */ + +GLOBAL(void) +jinit_compress_master (j_compress_ptr cinfo) +{ + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, FALSE /* full compression */); + + /* Preprocessing */ + if (! cinfo->raw_data_in) { + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); + } + /* Forward DCT */ + jinit_forward_dct(cinfo); + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* Need a full-image coefficient buffer in any multi-pass mode. */ + jinit_c_coef_controller(cinfo, + (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding)); + jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} diff --git a/src/dep/src/irrlicht/jpeglib/jcmainct.c b/src/dep/src/irrlicht/jpeglib/jcmainct.c new file mode 100644 index 0000000..14aa4c7 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcmainct.c @@ -0,0 +1,293 @@ +/* + * jcmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for compression. + * The main buffer lies between the pre-processor and the JPEG + * compressor proper; it holds downsampled data in the JPEG colorspace. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Note: currently, there is no operating mode in which a full-image buffer + * is needed at this step. If there were, that mode could not be used with + * "raw data" input, since this module is bypassed in that case. However, + * we've left the code here for possible use in special applications. + */ +#undef FULL_MAIN_BUFFER_SUPPORTED + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_main_controller pub; /* public fields */ + + JDIMENSION cur_iMCU_row; /* number of current iMCU row */ + JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ + boolean suspended; /* remember if we suspended output */ + J_BUF_MODE pass_mode; /* current operating mode */ + + /* If using just a strip buffer, this points to the entire set of buffers + * (we allocate one for each component). In the full-image case, this + * points to the currently accessible strips of the virtual arrays. + */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* If using full-image storage, this array holds pointers to virtual-array + * control blocks for each component. Unused if not full-image storage. + */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +#endif +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#ifdef FULL_MAIN_BUFFER_SUPPORTED +METHODDEF(void) process_data_buffer_main + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Do nothing in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + main->cur_iMCU_row = 0; /* initialize counters */ + main->rowgroup_ctr = 0; + main->suspended = FALSE; + main->pass_mode = pass_mode; /* save mode for use by process_data */ + + switch (pass_mode) { + case JBUF_PASS_THRU: +#ifdef FULL_MAIN_BUFFER_SUPPORTED + if (main->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + main->pub.process_data = process_data_simple_main; + break; +#ifdef FULL_MAIN_BUFFER_SUPPORTED + case JBUF_SAVE_SOURCE: + case JBUF_CRANK_DEST: + case JBUF_SAVE_AND_PASS: + if (main->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + main->pub.process_data = process_data_buffer_main; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This routine handles the simple pass-through mode, + * where we have only a strip buffer. + */ + +METHODDEF(void) +process_data_simple_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Read input data if we haven't filled the main buffer yet */ + if (main->rowgroup_ctr < DCTSIZE) + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + + /* If we don't have a full iMCU row buffered, return to application for + * more data. Note that preprocessor will always pad to fill the iMCU row + * at the bottom of the image. + */ + if (main->rowgroup_ctr != DCTSIZE) + return; + + /* Send the completed row to the compressor */ + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + + +#ifdef FULL_MAIN_BUFFER_SUPPORTED + +/* + * Process some data. + * This routine handles all of the modes that use a full-size buffer. + */ + +METHODDEF(void) +process_data_buffer_main (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci; + jpeg_component_info *compptr; + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { + /* Realign the virtual buffers if at the start of an iMCU row. */ + if (main->rowgroup_ctr == 0) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main->whole_image[ci], + main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + } + /* In a read pass, pretend we just read some source data. */ + if (! writing) { + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; + main->rowgroup_ctr = DCTSIZE; + } + } + + /* If a write pass, read input data until the current iMCU row is full. */ + /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ + if (writing) { + (*cinfo->prep->pre_process_data) (cinfo, + input_buf, in_row_ctr, in_rows_avail, + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) DCTSIZE); + /* Return to application if we need more data to fill the iMCU row. */ + if (main->rowgroup_ctr < DCTSIZE) + return; + } + + /* Emit data, unless this is a sink-only pass. */ + if (main->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { + /* If compressor did not consume the whole row, then we must need to + * suspend processing and return to the application. In this situation + * we pretend we didn't yet consume the last input row; otherwise, if + * it happened to be the last row of the image, the application would + * think we were done. + */ + if (! main->suspended) { + (*in_row_ctr)--; + main->suspended = TRUE; + } + return; + } + /* We did finish the row. Undo our little suspension hack if a previous + * call suspended; then mark the main buffer empty. + */ + if (main->suspended) { + (*in_row_ctr)++; + main->suspended = FALSE; + } + } + + /* If get here, we are done with this iMCU row. Mark buffer empty. */ + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; + } +} + +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_c_main_controller *) main; + main->pub.start_pass = start_pass_main; + + /* We don't need to create a buffer in raw-data mode. */ + if (cinfo->raw_data_in) + return; + + /* Create the buffer. It holds downsampled data, so each component + * may be of a different size. + */ + if (need_full_buffer) { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component */ + /* Note we pad the bottom to a multiple of the iMCU height */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor) * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else { +#ifdef FULL_MAIN_BUFFER_SUPPORTED + main->whole_image[0] = NULL; /* flag for no virtual arrays */ +#endif + /* Allocate a strip buffer for each component */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + } + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jcmarker.c b/src/dep/src/irrlicht/jpeglib/jcmarker.c new file mode 100644 index 0000000..0d3ca5e --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcmarker.c @@ -0,0 +1,664 @@ +/* + * jcmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write JPEG datastream markers. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_writer pub; /* public fields */ + + unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */ +} my_marker_writer; + +typedef my_marker_writer * my_marker_ptr; + + +/* + * Basic output routines. + * + * Note that we do not support suspension while writing a marker. + * Therefore, an application using suspension must ensure that there is + * enough buffer space for the initial markers (typ. 600-700 bytes) before + * calling jpeg_start_compress, and enough space to write the trailing EOI + * (a few bytes) before calling jpeg_finish_compress. Multipass compression + * modes are not supported at all with suspension, so those two are the only + * points where markers will be written. + */ + +LOCAL(void) +emit_byte (j_compress_ptr cinfo, int val) +/* Emit a byte */ +{ + struct jpeg_destination_mgr * dest = cinfo->dest; + + *(dest->next_output_byte)++ = (JOCTET) val; + if (--dest->free_in_buffer == 0) { + if (! (*dest->empty_output_buffer) (cinfo)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + } +} + + +LOCAL(void) +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) +/* Emit a marker code */ +{ + emit_byte(cinfo, 0xFF); + emit_byte(cinfo, (int) mark); +} + + +LOCAL(void) +emit_2bytes (j_compress_ptr cinfo, int value) +/* Emit a 2-byte integer; these are always MSB first in JPEG files */ +{ + emit_byte(cinfo, (value >> 8) & 0xFF); + emit_byte(cinfo, value & 0xFF); +} + + +/* + * Routines to write specific marker types. + */ + +LOCAL(int) +emit_dqt (j_compress_ptr cinfo, int index) +/* Emit a DQT marker */ +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ +{ + JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; + int prec; + int i; + + if (qtbl == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); + + prec = 0; + for (i = 0; i < DCTSIZE2; i++) { + if (qtbl->quantval[i] > 255) + prec = 1; + } + + if (! qtbl->sent_table) { + emit_marker(cinfo, M_DQT); + + emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec<<4)); + + for (i = 0; i < DCTSIZE2; i++) { + /* The table entries must be emitted in zigzag order. */ + unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; + if (prec) + emit_byte(cinfo, (int) (qval >> 8)); + emit_byte(cinfo, (int) (qval & 0xFF)); + } + + qtbl->sent_table = TRUE; + } + + return prec; +} + + +LOCAL(void) +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) +/* Emit a DHT marker */ +{ + JHUFF_TBL * htbl; + int length, i; + + if (is_ac) { + htbl = cinfo->ac_huff_tbl_ptrs[index]; + index += 0x10; /* output index has AC bit set */ + } else { + htbl = cinfo->dc_huff_tbl_ptrs[index]; + } + + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); + + if (! htbl->sent_table) { + emit_marker(cinfo, M_DHT); + + length = 0; + for (i = 1; i <= 16; i++) + length += htbl->bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for (i = 1; i <= 16; i++) + emit_byte(cinfo, htbl->bits[i]); + + for (i = 0; i < length; i++) + emit_byte(cinfo, htbl->huffval[i]); + + htbl->sent_table = TRUE; + } +} + + +LOCAL(void) +emit_dac (j_compress_ptr cinfo) +/* Emit a DAC marker */ +/* Since the useful info is so small, we want to emit all the tables in */ +/* one DAC marker. Therefore this routine does its own scan of the table. */ +{ +#ifdef C_ARITH_CODING_SUPPORTED + char dc_in_use[NUM_ARITH_TBLS]; + char ac_in_use[NUM_ARITH_TBLS]; + int length, i; + jpeg_component_info *compptr; + + for (i = 0; i < NUM_ARITH_TBLS; i++) + dc_in_use[i] = ac_in_use[i] = 0; + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + dc_in_use[compptr->dc_tbl_no] = 1; + ac_in_use[compptr->ac_tbl_no] = 1; + } + + length = 0; + for (i = 0; i < NUM_ARITH_TBLS; i++) + length += dc_in_use[i] + ac_in_use[i]; + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + if (dc_in_use[i]) { + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); + } + if (ac_in_use[i]) { + emit_byte(cinfo, i + 0x10); + emit_byte(cinfo, cinfo->arith_ac_K[i]); + } + } +#endif /* C_ARITH_CODING_SUPPORTED */ +} + + +LOCAL(void) +emit_dri (j_compress_ptr cinfo) +/* Emit a DRI marker */ +{ + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); /* fixed length */ + + emit_2bytes(cinfo, (int) cinfo->restart_interval); +} + + +LOCAL(void) +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) +/* Emit a SOF marker */ +{ + int ci; + jpeg_component_info *compptr; + + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ + + /* Make sure image isn't bigger than SOF field can handle */ + if ((long) cinfo->image_height > 65535L || + (long) cinfo->image_width > 65535L) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); + + emit_byte(cinfo, cinfo->data_precision); + emit_2bytes(cinfo, (int) cinfo->image_height); + emit_2bytes(cinfo, (int) cinfo->image_width); + + emit_byte(cinfo, cinfo->num_components); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + emit_byte(cinfo, compptr->component_id); + emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); + emit_byte(cinfo, compptr->quant_tbl_no); + } +} + + +LOCAL(void) +emit_sos (j_compress_ptr cinfo) +/* Emit a SOS marker */ +{ + int i, td, ta; + jpeg_component_info *compptr; + + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ + + emit_byte(cinfo, cinfo->comps_in_scan); + + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + emit_byte(cinfo, compptr->component_id); + td = compptr->dc_tbl_no; + ta = compptr->ac_tbl_no; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan; + * furthermore, Huffman coding of DC refinement uses no table at all. + * We emit 0 for unused field(s); this is recommended by the P&M text + * but does not seem to be specified in the standard. + */ + if (cinfo->Ss == 0) { + ta = 0; /* DC scan */ + if (cinfo->Ah != 0 && !cinfo->arith_code) + td = 0; /* no DC table either */ + } else { + td = 0; /* AC scan */ + } + } + emit_byte(cinfo, (td << 4) + ta); + } + + emit_byte(cinfo, cinfo->Ss); + emit_byte(cinfo, cinfo->Se); + emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); +} + + +LOCAL(void) +emit_jfif_app0 (j_compress_ptr cinfo) +/* Emit a JFIF-compliant APP0 marker */ +{ + /* + * Length of APP0 block (2 bytes) + * Block ID (4 bytes - ASCII "JFIF") + * Zero byte (1 byte to terminate the ID string) + * Version Major, Minor (2 bytes - major first) + * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) + * Xdpu (2 bytes - dots per unit horizontal) + * Ydpu (2 bytes - dots per unit vertical) + * Thumbnail X size (1 byte) + * Thumbnail Y size (1 byte) + */ + + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ + + emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0x49); + emit_byte(cinfo, 0x46); + emit_byte(cinfo, 0); + emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */ + emit_byte(cinfo, cinfo->JFIF_minor_version); + emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ + emit_2bytes(cinfo, (int) cinfo->X_density); + emit_2bytes(cinfo, (int) cinfo->Y_density); + emit_byte(cinfo, 0); /* No thumbnail image */ + emit_byte(cinfo, 0); +} + + +LOCAL(void) +emit_adobe_app14 (j_compress_ptr cinfo) +/* Emit an Adobe APP14 marker */ +{ + /* + * Length of APP14 block (2 bytes) + * Block ID (5 bytes - ASCII "Adobe") + * Version Number (2 bytes - currently 100) + * Flags0 (2 bytes - currently 0) + * Flags1 (2 bytes - currently 0) + * Color transform (1 byte) + * + * Although Adobe TN 5116 mentions Version = 101, all the Adobe files + * now in circulation seem to use Version = 100, so that's what we write. + * + * We write the color transform byte as 1 if the JPEG color space is + * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + * whether the encoder performed a transformation, which is pretty useless. + */ + + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ + + emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ + emit_byte(cinfo, 0x64); + emit_byte(cinfo, 0x6F); + emit_byte(cinfo, 0x62); + emit_byte(cinfo, 0x65); + emit_2bytes(cinfo, 100); /* Version */ + emit_2bytes(cinfo, 0); /* Flags0 */ + emit_2bytes(cinfo, 0); /* Flags1 */ + switch (cinfo->jpeg_color_space) { + case JCS_YCbCr: + emit_byte(cinfo, 1); /* Color transform = 1 */ + break; + case JCS_YCCK: + emit_byte(cinfo, 2); /* Color transform = 2 */ + break; + default: + emit_byte(cinfo, 0); /* Color transform = 0 */ + break; + } +} + + +/* + * These routines allow writing an arbitrary marker with parameters. + * The only intended use is to emit COM or APPn markers after calling + * write_file_header and before calling write_frame_header. + * Other uses are not guaranteed to produce desirable results. + * Counting the parameter bytes properly is the caller's responsibility. + */ + +METHODDEF(void) +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen) +/* Emit an arbitrary marker header */ +{ + if (datalen > (unsigned int) 65533) /* safety check */ + ERREXIT(cinfo, JERR_BAD_LENGTH); + + emit_marker(cinfo, (JPEG_MARKER) marker); + + emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ +} + +METHODDEF(void) +write_marker_byte (j_compress_ptr cinfo, int val) +/* Emit one byte of marker parameters following write_marker_header */ +{ + emit_byte(cinfo, val); +} + + +/* + * Write datastream header. + * This consists of an SOI and optional APPn markers. + * We recommend use of the JFIF marker, but not the Adobe marker, + * when using YCbCr or grayscale data. The JFIF marker should NOT + * be used for any other JPEG colorspace. The Adobe marker is helpful + * to distinguish RGB, CMYK, and YCCK colorspaces. + * Note that an application can write additional header markers after + * jpeg_start_compress returns. + */ + +METHODDEF(void) +write_file_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + emit_marker(cinfo, M_SOI); /* first the SOI */ + + /* SOI is defined to reset restart interval to 0 */ + marker->last_restart_interval = 0; + + if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ + emit_jfif_app0(cinfo); + if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ + emit_adobe_app14(cinfo); +} + + +/* + * Write frame header. + * This consists of DQT and SOFn markers. + * Note that we do not emit the SOF until we have emitted the DQT(s). + * This avoids compatibility problems with incorrect implementations that + * try to error-check the quant table numbers as soon as they see the SOF. + */ + +METHODDEF(void) +write_frame_header (j_compress_ptr cinfo) +{ + int ci, prec; + boolean is_baseline; + jpeg_component_info *compptr; + + /* Emit DQT for each quantization table. + * Note that emit_dqt() suppresses any duplicate tables. + */ + prec = 0; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prec += emit_dqt(cinfo, compptr->quant_tbl_no); + } + /* now prec is nonzero iff there are any 16-bit quant tables. */ + + /* Check for a non-baseline specification. + * Note we assume that Huffman table numbers won't be changed later. + */ + if (cinfo->arith_code || cinfo->progressive_mode || + cinfo->data_precision != 8) { + is_baseline = FALSE; + } else { + is_baseline = TRUE; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) + is_baseline = FALSE; + } + if (prec && is_baseline) { + is_baseline = FALSE; + /* If it's baseline except for quantizer size, warn the user */ + TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); + } + } + + /* Emit the proper SOF marker */ + if (cinfo->arith_code) { + emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ + } else { + if (cinfo->progressive_mode) + emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ + else if (is_baseline) + emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ + else + emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ + } +} + + +/* + * Write scan header. + * This consists of DHT or DAC markers, optional DRI, and SOS. + * Compressed data will be written following the SOS. + */ + +METHODDEF(void) +write_scan_header (j_compress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + int i; + jpeg_component_info *compptr; + + if (cinfo->arith_code) { + /* Emit arith conditioning info. We may have some duplication + * if the file has multiple scans, but it's so small it's hardly + * worth worrying about. + */ + emit_dac(cinfo); + } else { + /* Emit Huffman tables. + * Note that emit_dht() suppresses any duplicate tables. + */ + for (i = 0; i < cinfo->comps_in_scan; i++) { + compptr = cinfo->cur_comp_info[i]; + if (cinfo->progressive_mode) { + /* Progressive mode: only DC or only AC tables are used in one scan */ + if (cinfo->Ss == 0) { + if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + } else { + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } else { + /* Sequential mode: need both DC and AC tables */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); + emit_dht(cinfo, compptr->ac_tbl_no, TRUE); + } + } + } + + /* Emit DRI if required --- note that DRI value could change for each scan. + * We avoid wasting space with unnecessary DRIs, however. + */ + if (cinfo->restart_interval != marker->last_restart_interval) { + emit_dri(cinfo); + marker->last_restart_interval = cinfo->restart_interval; + } + + emit_sos(cinfo); +} + + +/* + * Write datastream trailer. + */ + +METHODDEF(void) +write_file_trailer (j_compress_ptr cinfo) +{ + emit_marker(cinfo, M_EOI); +} + + +/* + * Write an abbreviated table-specification datastream. + * This consists of SOI, DQT and DHT tables, and EOI. + * Any table that is defined and not marked sent_table = TRUE will be + * emitted. Note that all tables will be marked sent_table = TRUE at exit. + */ + +METHODDEF(void) +write_tables_only (j_compress_ptr cinfo) +{ + int i; + + emit_marker(cinfo, M_SOI); + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + if (cinfo->quant_tbl_ptrs[i] != NULL) + (void) emit_dqt(cinfo, i); + } + + if (! cinfo->arith_code) { + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, FALSE); + if (cinfo->ac_huff_tbl_ptrs[i] != NULL) + emit_dht(cinfo, i, TRUE); + } + } + + emit_marker(cinfo, M_EOI); +} + + +/* + * Initialize the marker writer module. + */ + +GLOBAL(void) +jinit_marker_writer (j_compress_ptr cinfo) +{ + my_marker_ptr marker; + + /* Create the subobject */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_marker_writer)); + cinfo->marker = (struct jpeg_marker_writer *) marker; + /* Initialize method pointers */ + marker->pub.write_file_header = write_file_header; + marker->pub.write_frame_header = write_frame_header; + marker->pub.write_scan_header = write_scan_header; + marker->pub.write_file_trailer = write_file_trailer; + marker->pub.write_tables_only = write_tables_only; + marker->pub.write_marker_header = write_marker_header; + marker->pub.write_marker_byte = write_marker_byte; + /* Initialize private state */ + marker->last_restart_interval = 0; +} diff --git a/src/dep/src/irrlicht/jpeglib/jcmaster.c b/src/dep/src/irrlicht/jpeglib/jcmaster.c new file mode 100644 index 0000000..e61138b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcmaster.c @@ -0,0 +1,590 @@ +/* + * jcmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG compressor. + * These routines are concerned with parameter validation, initial setup, + * and inter-pass control (determining the number of passes and the work + * to be done in each pass). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef enum { + main_pass, /* input data, also do first output step */ + huff_opt_pass, /* Huffman code optimization pass */ + output_pass /* data output pass */ +} c_pass_type; + +typedef struct { + struct jpeg_comp_master pub; /* public fields */ + + c_pass_type pass_type; /* the type of the current pass */ + + int pass_number; /* # of passes completed */ + int total_passes; /* total # of passes needed */ + + int scan_number; /* current index in scan_info[] */ +} my_comp_master; + +typedef my_comp_master * my_master_ptr; + + +/* + * Support routines that do various essential calculations. + */ + +LOCAL(void) +initial_setup (j_compress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ + int ci; + jpeg_component_info *compptr; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Sanity check on image dimensions */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0 || cinfo->input_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* Width of an input scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Fill in the correct component_index value; don't rely on application */ + compptr->component_index = ci; + /* For compression, we never do DCT scaling. */ + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed (this flag isn't actually used for compression) */ + compptr->component_needed = TRUE; + } + + /* Compute number of fully interleaved MCU rows (number of times that + * main controller will call coefficient controller). + */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL(void) +validate_script (j_compress_ptr cinfo) +/* Verify that the scan script in cinfo->scan_info[] is valid; also + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. + */ +{ + const jpeg_scan_info * scanptr; + int scanno, ncomps, ci, coefi, thisi; + int Ss, Se, Ah, Al; + boolean component_sent[MAX_COMPONENTS]; +#ifdef C_PROGRESSIVE_SUPPORTED + int * last_bitpos_ptr; + int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; + /* -1 until that coefficient has been seen; then last Al for it */ +#endif + + if (cinfo->num_scans <= 0) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); + + /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + * for progressive JPEG, no scan can have this. + */ + scanptr = cinfo->scan_info; + if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { +#ifdef C_PROGRESSIVE_SUPPORTED + cinfo->progressive_mode = TRUE; + last_bitpos_ptr = & last_bitpos[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (coefi = 0; coefi < DCTSIZE2; coefi++) + *last_bitpos_ptr++ = -1; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + for (ci = 0; ci < cinfo->num_components; ci++) + component_sent[ci] = FALSE; + } + + for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) { + /* Validate component indexes */ + ncomps = scanptr->comps_in_scan; + if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (thisi < 0 || thisi >= cinfo->num_components) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + /* Components must appear in SOF order within each scan */ + if (ci > 0 && thisi <= scanptr->component_index[ci-1]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + } + /* Validate progression parameters */ + Ss = scanptr->Ss; + Se = scanptr->Se; + Ah = scanptr->Ah; + Al = scanptr->Al; + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + * seems wrong: the upper bound ought to depend on data precision. + * Perhaps they really meant 0..N+1 for N-bit precision. + * Here we allow 0..10 for 8-bit data; Al larger than 10 results in + * out-of-range reconstructed DC values during the first DC scan, + * which might cause problems for some decoders. + */ +#if BITS_IN_JSAMPLE == 8 +#define MAX_AH_AL 10 +#else +#define MAX_AH_AL 13 +#endif + if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || + Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + if (Ss == 0) { + if (Se != 0) /* DC and AC together not OK */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + if (ncomps != 1) /* AC scans must be for only one component */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + for (ci = 0; ci < ncomps; ci++) { + last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0]; + if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */ + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + for (coefi = Ss; coefi <= Se; coefi++) { + if (last_bitpos_ptr[coefi] < 0) { + /* first scan of this coefficient */ + if (Ah != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } else { + /* not first scan */ + if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + } + last_bitpos_ptr[coefi] = Al; + } + } +#endif + } else { + /* For sequential JPEG, all progression parameters must be these: */ + if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0) + ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); + /* Make sure components are not sent twice */ + for (ci = 0; ci < ncomps; ci++) { + thisi = scanptr->component_index[ci]; + if (component_sent[thisi]) + ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] = TRUE; + } + } + } + + /* Now verify that everything got sent. */ + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + /* For progressive mode, we only check that at least some DC data + * got sent for each component; the spec does not require that all bits + * of all coefficients be transmitted. Would it be wiser to enforce + * transmission of all coefficient bits?? + */ + for (ci = 0; ci < cinfo->num_components; ci++) { + if (last_bitpos[ci][0] < 0) + ERREXIT(cinfo, JERR_MISSING_DATA); + } +#endif + } else { + for (ci = 0; ci < cinfo->num_components; ci++) { + if (! component_sent[ci]) + ERREXIT(cinfo, JERR_MISSING_DATA); + } + } +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +LOCAL(void) +select_scan_parameters (j_compress_ptr cinfo) +/* Set up the scan parameters for the current scan */ +{ + int ci; + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (cinfo->scan_info != NULL) { + /* Prepare for current scan --- the script is already validated */ + my_master_ptr master = (my_master_ptr) cinfo->master; + const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number; + + cinfo->comps_in_scan = scanptr->comps_in_scan; + for (ci = 0; ci < scanptr->comps_in_scan; ci++) { + cinfo->cur_comp_info[ci] = + &cinfo->comp_info[scanptr->component_index[ci]]; + } + cinfo->Ss = scanptr->Ss; + cinfo->Se = scanptr->Se; + cinfo->Ah = scanptr->Ah; + cinfo->Al = scanptr->Al; + } + else +#endif + { + /* Prepare for single sequential-JPEG scan containing all components */ + if (cinfo->num_components > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPS_IN_SCAN); + cinfo->comps_in_scan = cinfo->num_components; + for (ci = 0; ci < cinfo->num_components; ci++) { + cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; + } + cinfo->Ss = 0; + cinfo->Se = DCTSIZE2-1; + cinfo->Ah = 0; + cinfo->Al = 0; + } +} + + +LOCAL(void) +per_scan_setup (j_compress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = DCTSIZE; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } + + /* Convert restart specified in rows to actual MCU count. */ + /* Note that count must fit in 16 bits, so we provide limiting. */ + if (cinfo->restart_in_rows > 0) { + long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row; + cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L); + } +} + + +/* + * Per-pass setup. + * This is called at the beginning of each pass. We determine which modules + * will be active during this pass and give them appropriate start_pass calls. + * We also set is_last_pass to indicate whether any more passes will be + * required. + */ + +METHODDEF(void) +prepare_for_pass (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + switch (master->pass_type) { + case main_pass: + /* Initial pass: will collect input data, and do either Huffman + * optimization or data output for the first scan. + */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (! cinfo->raw_data_in) { + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->downsample->start_pass) (cinfo); + (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); + } + (*cinfo->fdct->start_pass) (cinfo); + (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding); + (*cinfo->coef->start_pass) (cinfo, + (master->total_passes > 1 ? + JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + if (cinfo->optimize_coding) { + /* No immediate data output; postpone writing frame/scan headers */ + master->pub.call_pass_startup = FALSE; + } else { + /* Will write frame/scan headers at first jpeg_write_scanlines call */ + master->pub.call_pass_startup = TRUE; + } + break; +#ifdef ENTROPY_OPT_SUPPORTED + case huff_opt_pass: + /* Do Huffman optimization for a scan after the first one. */ + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { + (*cinfo->entropy->start_pass) (cinfo, TRUE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + master->pub.call_pass_startup = FALSE; + break; + } + /* Special case: Huffman DC refinement scans need no Huffman table + * and therefore we can skip the optimization pass for them. + */ + master->pass_type = output_pass; + master->pass_number++; + /*FALLTHROUGH*/ +#endif + case output_pass: + /* Do a data-output pass. */ + /* We need not repeat per-scan setup if prior optimization pass did it. */ + if (! cinfo->optimize_coding) { + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + } + (*cinfo->entropy->start_pass) (cinfo, FALSE); + (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + /* We emit frame/scan headers now */ + if (master->scan_number == 0) + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); + master->pub.call_pass_startup = FALSE; + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + } + + master->pub.is_last_pass = (master->pass_number == master->total_passes-1); + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->total_passes; + } +} + + +/* + * Special start-of-pass hook. + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + * In single-pass processing, we need this hook because we don't want to + * write frame/scan headers during jpeg_start_compress; we want to let the + * application write COM markers etc. between jpeg_start_compress and the + * jpeg_write_scanlines loop. + * In multi-pass processing, this routine is not used. + */ + +METHODDEF(void) +pass_startup (j_compress_ptr cinfo) +{ + cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ + + (*cinfo->marker->write_frame_header) (cinfo); + (*cinfo->marker->write_scan_header) (cinfo); +} + + +/* + * Finish up at end of pass. + */ + +METHODDEF(void) +finish_pass_master (j_compress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* The entropy coder always needs an end-of-pass call, + * either to analyze statistics or to flush its output buffer. + */ + (*cinfo->entropy->finish_pass) (cinfo); + + /* Update state for next pass */ + switch (master->pass_type) { + case main_pass: + /* next pass is either output of scan 0 (after optimization) + * or output of scan 1 (if no optimization). + */ + master->pass_type = output_pass; + if (! cinfo->optimize_coding) + master->scan_number++; + break; + case huff_opt_pass: + /* next pass is always output of current scan */ + master->pass_type = output_pass; + break; + case output_pass: + /* next pass is either optimization or output of next scan */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + master->scan_number++; + break; + } + + master->pass_number++; +} + + +/* + * Initialize master compression control. + */ + +GLOBAL(void) +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_comp_master)); + cinfo->master = (struct jpeg_comp_master *) master; + master->pub.prepare_for_pass = prepare_for_pass; + master->pub.pass_startup = pass_startup; + master->pub.finish_pass = finish_pass_master; + master->pub.is_last_pass = FALSE; + + /* Validate parameters, determine derived values */ + initial_setup(cinfo); + + if (cinfo->scan_info != NULL) { +#ifdef C_MULTISCAN_FILES_SUPPORTED + validate_script(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + cinfo->progressive_mode = FALSE; + cinfo->num_scans = 1; + } + + if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ + cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + + /* Initialize my private state */ + if (transcode_only) { + /* no main pass in transcoding */ + if (cinfo->optimize_coding) + master->pass_type = huff_opt_pass; + else + master->pass_type = output_pass; + } else { + /* for normal compression, first pass is always this type: */ + master->pass_type = main_pass; + } + master->scan_number = 0; + master->pass_number = 0; + if (cinfo->optimize_coding) + master->total_passes = cinfo->num_scans * 2; + else + master->total_passes = cinfo->num_scans; +} diff --git a/src/dep/src/irrlicht/jpeglib/jcomapi.c b/src/dep/src/irrlicht/jpeglib/jcomapi.c new file mode 100644 index 0000000..1b1a340 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcomapi.c @@ -0,0 +1,106 @@ +/* + * jcomapi.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface routines that are used for both + * compression and decompression. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Abort processing of a JPEG compression or decompression operation, + * but don't destroy the object itself. + * + * For this, we merely clean up all the nonpermanent memory pools. + * Note that temp files (virtual arrays) are not allowed to belong to + * the permanent pool, so we will be able to close all temp files here. + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_abort (j_common_ptr cinfo) +{ + int pool; + + /* Do nothing if called on a not-initialized or destroyed JPEG object. */ + if (cinfo->mem == NULL) + return; + + /* Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { + (*cinfo->mem->free_pool) (cinfo, pool); + } + + /* Reset overall state for possible reuse of object */ + if (cinfo->is_decompressor) { + cinfo->global_state = DSTATE_START; + /* Try to keep application from accessing now-deleted marker list. + * A bit kludgy to do it here, but this is the most central place. + */ + ((j_decompress_ptr) cinfo)->marker_list = NULL; + } else { + cinfo->global_state = CSTATE_START; + } +} + + +/* + * Destruction of a JPEG object. + * + * Everything gets deallocated except the master jpeg_compress_struct itself + * and the error manager struct. Both of these are supplied by the application + * and must be freed, if necessary, by the application. (Often they are on + * the stack and so don't need to be freed anyway.) + * Closing a data source or destination, if necessary, is the application's + * responsibility. + */ + +GLOBAL(void) +jpeg_destroy (j_common_ptr cinfo) +{ + /* We need only tell the memory manager to release everything. */ + /* NB: mem pointer is NULL if memory mgr failed to initialize. */ + if (cinfo->mem != NULL) + (*cinfo->mem->self_destruct) (cinfo); + cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ + cinfo->global_state = 0; /* mark it destroyed */ +} + + +/* + * Convenience routines for allocating quantization and Huffman tables. + * (Would jutils.c be a more reasonable place to put these?) + */ + +GLOBAL(JQUANT_TBL *) +jpeg_alloc_quant_table (j_common_ptr cinfo) +{ + JQUANT_TBL *tbl; + + tbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} + + +GLOBAL(JHUFF_TBL *) +jpeg_alloc_huff_table (j_common_ptr cinfo) +{ + JHUFF_TBL *tbl; + + tbl = (JHUFF_TBL *) + (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); + tbl->sent_table = FALSE; /* make sure this is false in any new table */ + return tbl; +} diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.bcc b/src/dep/src/irrlicht/jpeglib/jconfig.bcc new file mode 100644 index 0000000..6538a0f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.bcc @@ -0,0 +1,48 @@ +/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#ifdef __MSDOS__ +#define NEED_FAR_POINTERS /* for small or medium memory model */ +#endif +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN /* this assumes you have -w-stu in CFLAGS */ + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#ifdef __MSDOS__ +#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */ +#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */ +#define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */ +#endif + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE +#define USE_SETMODE /* Borland has setmode() */ +#ifdef __MSDOS__ +#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */ +#endif +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.cfg b/src/dep/src/irrlicht/jpeglib/jconfig.cfg new file mode 100644 index 0000000..5bc0113 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.cfg @@ -0,0 +1,44 @@ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.doc for explanations */ + +#undef HAVE_PROTOTYPES +#undef HAVE_UNSIGNED_CHAR +#undef HAVE_UNSIGNED_SHORT +#undef void +#undef const +#undef CHAR_IS_UNSIGNED +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED +#undef INLINE +/* These are for configuring the JPEG memory manager. */ +#undef DEFAULT_MAX_MEM +#undef NO_MKTEMP + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.dj b/src/dep/src/irrlicht/jpeglib/jconfig.dj new file mode 100644 index 0000000..7cd1ed5 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.dj @@ -0,0 +1,38 @@ +/* jconfig.dj --- jconfig.h for DJGPP (Delorie's GNU C port) on MS-DOS. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* DJGPP uses flat 32-bit addressing */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Needed to make one-file style work in DJGPP */ +#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.doc b/src/dep/src/irrlicht/jpeglib/jconfig.doc new file mode 100644 index 0000000..6e2552b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.doc @@ -0,0 +1,155 @@ +/* + * jconfig.doc + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file documents the configuration options that are required to + * customize the JPEG software for a particular system. + * + * The actual configuration options for a particular installation are stored + * in jconfig.h. On many machines, jconfig.h can be generated automatically + * or copied from one of the "canned" jconfig files that we supply. But if + * you need to generate a jconfig.h file by hand, this file tells you how. + * + * DO NOT EDIT THIS FILE --- IT WON'T ACCOMPLISH ANYTHING. + * EDIT A COPY NAMED JCONFIG.H. + */ + + +/* + * These symbols indicate the properties of your machine or compiler. + * #define the symbol if yes, #undef it if no. + */ + +/* Does your compiler support function prototypes? + * (If not, you also need to use ansi2knr, see install.doc) + */ +#define HAVE_PROTOTYPES + +/* Does your compiler support the declaration "unsigned char" ? + * How about "unsigned short" ? + */ +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT + +/* Define "void" as "char" if your compiler doesn't know about type void. + * NOTE: be sure to define void such that "void *" represents the most general + * pointer type, e.g., that returned by malloc(). + */ +/* #define void char */ + +/* Define "const" as empty if your compiler doesn't know the "const" keyword. + */ +/* #define const */ + +/* Define this if an ordinary "char" type is unsigned. + * If you're not sure, leaving it undefined will work at some cost in speed. + * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal. + */ +#undef CHAR_IS_UNSIGNED + +/* Define this if your system has an ANSI-conforming file. + */ +#define HAVE_STDDEF_H + +/* Define this if your system has an ANSI-conforming file. + */ +#define HAVE_STDLIB_H + +/* Define this if your system does not have an ANSI/SysV , + * but does have a BSD-style . + */ +#undef NEED_BSD_STRINGS + +/* Define this if your system does not provide typedef size_t in any of the + * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in + * instead. + */ +#undef NEED_SYS_TYPES_H + +/* For 80x86 machines, you need to define NEED_FAR_POINTERS, + * unless you are using a large-data memory model or 80386 flat-memory mode. + * On less brain-damaged CPUs this symbol must not be defined. + * (Defining this symbol causes large data structures to be referenced through + * "far" pointers and to be allocated with a special version of malloc.) + */ +#undef NEED_FAR_POINTERS + +/* Define this if your linker needs global names to be unique in less + * than the first 15 characters. + */ +#undef NEED_SHORT_EXTERNAL_NAMES + +/* Although a real ANSI C compiler can deal perfectly well with pointers to + * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI + * and pseudo-ANSI compilers get confused. To keep one of these bozos happy, + * define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you + * actually get "missing structure definition" warnings or errors while + * compiling the JPEG code. + */ +#undef INCOMPLETE_TYPES_BROKEN + + +/* + * The following options affect code selection within the JPEG library, + * but they don't need to be visible to applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS has been defined. + */ + +#ifdef JPEG_INTERNALS + +/* Define this if your compiler implements ">>" on signed values as a logical + * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift, + * which is the normal and rational definition. + */ +#undef RIGHT_SHIFT_IS_UNSIGNED + + +#endif /* JPEG_INTERNALS */ + + +/* + * The remaining options do not affect the JPEG library proper, + * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c). + * Other applications can ignore these. + */ + +#ifdef JPEG_CJPEG_DJPEG + +/* These defines indicate which image (non-JPEG) file formats are allowed. */ + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +/* Define this if you want to name both input and output files on the command + * line, rather than using stdout and optionally stdin. You MUST do this if + * your system can't cope with binary I/O to stdin/stdout. See comments at + * head of cjpeg.c or djpeg.c. + */ +#undef TWO_FILE_COMMANDLINE + +/* Define this if your system needs explicit cleanup of temporary files. + * This is crucial under MS-DOS, where the temporary "files" may be areas + * of extended memory; on most other systems it's not as important. + */ +#undef NEED_SIGNAL_CATCHER + +/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb"). + * This is necessary on systems that distinguish text files from binary files, + * and is harmless on most systems that don't. If you have one of the rare + * systems that complains about the "b" spec, define this symbol. + */ +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. + */ +#undef PROGRESS_REPORT + + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.h b/src/dep/src/irrlicht/jpeglib/jconfig.h new file mode 100644 index 0000000..2f4da14 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.h @@ -0,0 +1,45 @@ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +/* Define "boolean" as unsigned char, not int, per Windows custom */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ + + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Microsoft has setmode() */ +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.mac b/src/dep/src/irrlicht/jpeglib/jconfig.mac new file mode 100644 index 0000000..1db67f5 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.mac @@ -0,0 +1,43 @@ +/* jconfig.mac --- jconfig.h for CodeWarrior on Apple Macintosh */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#define USE_MAC_MEMMGR /* Define this if you use jmemmac.c */ + +#define ALIGN_TYPE long /* Needed for 680x0 Macs */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define USE_CCOMMAND /* Command line reader for Macintosh */ +#define TWO_FILE_COMMANDLINE /* Binary I/O thru stdin/stdout doesn't work */ + +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.manx b/src/dep/src/irrlicht/jpeglib/jconfig.manx new file mode 100644 index 0000000..0dbd0b8 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.manx @@ -0,0 +1,43 @@ +/* jconfig.manx --- jconfig.h for Amiga systems using Manx Aztec C ver 5.x. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */ + +#define SHORTxSHORT_32 /* produces better DCT code with Aztec C */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE +#define NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#define signal_catcher _abort /* hack for Aztec C naming requirements */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.mc6 b/src/dep/src/irrlicht/jpeglib/jconfig.mc6 new file mode 100644 index 0000000..5492365 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.mc6 @@ -0,0 +1,52 @@ +/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#define NEED_FAR_POINTERS /* for small or medium memory model */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */ + +#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */ + +#define USE_FMEM /* Microsoft has _fmemcpy() and _fmemset() */ + +#define NEED_FHEAPMIN /* far heap management routines are broken */ + +#define SHORTxLCONST_32 /* enable compiler-specific DCT optimization */ +/* Note: the above define is known to improve the code with Microsoft C 6.00A. + * I do not know whether it is good for later compiler versions. + * Please report any info on this point to jpeg-info@uunet.uu.net. + */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE +#define USE_SETMODE /* Microsoft has setmode() */ +#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.sas b/src/dep/src/irrlicht/jpeglib/jconfig.sas new file mode 100644 index 0000000..a802dd3 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.sas @@ -0,0 +1,43 @@ +/* jconfig.sas --- jconfig.h for Amiga systems using SAS C 6.0 and up. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */ + +#define NO_MKTEMP /* SAS C doesn't have mktemp() */ + +#define SHORTxSHORT_32 /* produces better DCT code with SAS C */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE +#define NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.st b/src/dep/src/irrlicht/jpeglib/jconfig.st new file mode 100644 index 0000000..796b3c9 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.st @@ -0,0 +1,42 @@ +/* jconfig.st --- jconfig.h for Atari ST/STE/TT using Pure C or Turbo C. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#define INCOMPLETE_TYPES_BROKEN /* suppress undefined-structure warnings */ + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#define ALIGN_TYPE long /* apparently double is a weird size? */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE /* optional -- undef if you like Unix style */ +/* Note: if you undef TWO_FILE_COMMANDLINE, you may need to define + * USE_SETMODE. Some Atari compilers require it, some do not. + */ +#define NEED_SIGNAL_CATCHER /* needed if you use jmemname.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.vc b/src/dep/src/irrlicht/jpeglib/jconfig.vc new file mode 100644 index 0000000..2f4da14 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.vc @@ -0,0 +1,45 @@ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +/* Define "boolean" as unsigned char, not int, per Windows custom */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ + + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Microsoft has setmode() */ +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.vms b/src/dep/src/irrlicht/jpeglib/jconfig.vms new file mode 100644 index 0000000..eb582dc --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.vms @@ -0,0 +1,37 @@ +/* jconfig.vms --- jconfig.h for use on Digital VMS. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#define TWO_FILE_COMMANDLINE /* Needed on VMS */ +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jconfig.wat b/src/dep/src/irrlicht/jpeglib/jconfig.wat new file mode 100644 index 0000000..d57ceb9 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jconfig.wat @@ -0,0 +1,38 @@ +/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#define CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */ +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE /* optional */ +#define USE_SETMODE /* Needed to make one-file style work in Watcom */ +#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */ +#undef DONT_USE_B_MODE +#undef PROGRESS_REPORT /* optional */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/dep/src/irrlicht/jpeglib/jcparam.c b/src/dep/src/irrlicht/jpeglib/jcparam.c new file mode 100644 index 0000000..bbd175c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcparam.c @@ -0,0 +1,610 @@ +/* + * jcparam.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains optional default-setting code for the JPEG compressor. + * Applications do not have to use this file, but those that don't use it + * must know a lot more about the innards of the JPEG code. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Quantization table setup routines + */ + +GLOBAL(void) +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) +/* Define a quantization table equal to the basic_table times + * a scale factor (given as a percentage). + * If force_baseline is TRUE, the computed quantization table entries + * are limited to 1..255 for JPEG baseline compatibility. + */ +{ + JQUANT_TBL ** qtblptr; + int i; + long temp; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl); + + qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; + + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); + + for (i = 0; i < DCTSIZE2; i++) { + temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; + /* limit the values to the valid range */ + if (temp <= 0L) temp = 1L; + if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ + if (force_baseline && temp > 255L) + temp = 255L; /* limit to baseline range if requested */ + (*qtblptr)->quantval[i] = (UINT16) temp; + } + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*qtblptr)->sent_table = FALSE; +} + + +GLOBAL(void) +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables + * and a straight percentage-scaling quality scale. In most cases it's better + * to use jpeg_set_quality (below); this entry point is provided for + * applications that insist on a linear percentage scaling. + */ +{ + /* These are the sample quantization tables given in JPEG spec section K.1. + * The spec says that the values given produce "good" quality, and + * when divided by 2, "very good" quality. + */ + static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; + static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + + /* Set up two quantization tables using the specified scaling */ + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +} + + +GLOBAL(int) +jpeg_quality_scaling (int quality) +/* Convert a user-specified quality rating to a percentage scaling factor + * for an underlying quantization table, using our recommended scaling curve. + * The input 'quality' factor should be 0 (terrible) to 100 (very good). + */ +{ + /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ + if (quality <= 0) quality = 1; + if (quality > 100) quality = 100; + + /* The basic table is used as-is (scaling 100) for a quality of 50. + * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + * to make all the table entries 1 (hence, minimum quantization loss). + * Qualities 1..50 are converted to scaling percentage 5000/Q. + */ + if (quality < 50) + quality = 5000 / quality; + else + quality = 200 - quality*2; + + return quality; +} + + +GLOBAL(void) +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) +/* Set or change the 'quality' (quantization) setting, using default tables. + * This is the standard quality-adjusting entry point for typical user + * interfaces; only those who want detailed control over quantization tables + * would use the preceding three routines directly. + */ +{ + /* Convert user 0-100 rating to percentage scaling */ + quality = jpeg_quality_scaling(quality); + + /* Set up standard quality tables */ + jpeg_set_linear_quality(cinfo, quality, force_baseline); +} + + +/* + * Huffman table setup routines + */ + +LOCAL(void) +add_huff_table (j_compress_ptr cinfo, + JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) +/* Define a Huffman table */ +{ + int nsymbols, len; + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + /* Copy the number-of-symbols-of-each-code-length counts */ + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + + /* Validate the counts. We do this here mainly so we can copy the right + * number of symbols from the val[] array, without risking marching off + * the end of memory. jchuff.c will do a more thorough test later. + */ + nsymbols = 0; + for (len = 1; len <= 16; len++) + nsymbols += bits[len]; + if (nsymbols < 1 || nsymbols > 256) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8)); + + /* Initialize sent_table FALSE so table will be written to JPEG file. */ + (*htblptr)->sent_table = FALSE; +} + + +LOCAL(void) +std_huff_tables (j_compress_ptr cinfo) +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ +/* IMPORTANT: these are only valid for 8-bit data precision! */ +{ + static const UINT8 bits_dc_luminance[17] = + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_luminance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_dc_chrominance[17] = + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + static const UINT8 val_dc_chrominance[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + static const UINT8 bits_ac_luminance[17] = + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; + static const UINT8 val_ac_luminance[] = + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + static const UINT8 bits_ac_chrominance[17] = + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; + static const UINT8 val_ac_chrominance[] = + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }; + + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +} + + +/* + * Default parameter setup for compression. + * + * Applications that don't choose to use this routine must do their + * own setup of all these parameters. Alternately, you can call this + * to establish defaults and then alter parameters selectively. This + * is the recommended approach since, if we add any new parameters, + * your code will still work (they'll be set to reasonable defaults). + */ + +GLOBAL(void) +jpeg_set_defaults (j_compress_ptr cinfo) +{ + int i; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Allocate comp_info array large enough for maximum component count. + * Array is made permanent in case application wants to compress + * multiple images at same param settings. + */ + if (cinfo->comp_info == NULL) + cinfo->comp_info = (jpeg_component_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)); + + /* Initialize everything not dependent on the color space */ + + cinfo->data_precision = BITS_IN_JSAMPLE; + /* Set up two quantization tables using default quality of 75 */ + jpeg_set_quality(cinfo, 75, TRUE); + /* Set up two Huffman tables */ + std_huff_tables(cinfo); + + /* Initialize default arithmetic coding conditioning */ + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + + /* Default is no multiple-scan output */ + cinfo->scan_info = NULL; + cinfo->num_scans = 0; + + /* Expect normal source image, not raw downsampled data */ + cinfo->raw_data_in = FALSE; + + /* Use Huffman coding, not arithmetic coding, by default */ + cinfo->arith_code = FALSE; + + /* By default, don't do extra passes to optimize entropy coding */ + cinfo->optimize_coding = FALSE; + /* The standard Huffman tables are only valid for 8-bit data precision. + * If the precision is higher, force optimization on so that usable + * tables will be computed. This test can be removed if default tables + * are supplied that are valid for the desired precision. + */ + if (cinfo->data_precision > 8) + cinfo->optimize_coding = TRUE; + + /* By default, use the simpler non-cosited sampling alignment */ + cinfo->CCIR601_sampling = FALSE; + + /* No input smoothing */ + cinfo->smoothing_factor = 0; + + /* DCT algorithm preference */ + cinfo->dct_method = JDCT_DEFAULT; + + /* No restart markers */ + cinfo->restart_interval = 0; + cinfo->restart_in_rows = 0; + + /* Fill in default JFIF marker parameters. Note that whether the marker + * will actually be written is determined by jpeg_set_colorspace. + * + * By default, the library emits JFIF version code 1.01. + * An application that wants to emit JFIF 1.02 extension markers should set + * JFIF_minor_version to 2. We could probably get away with just defaulting + * to 1.02, but there may still be some decoders in use that will complain + * about that; saying 1.01 should minimize compatibility problems. + */ + cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; /* Pixel size is unknown by default */ + cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ + cinfo->Y_density = 1; + + /* Choose JPEG colorspace based on input space, set defaults accordingly */ + + jpeg_default_colorspace(cinfo); +} + + +/* + * Select an appropriate JPEG colorspace for in_color_space. + */ + +GLOBAL(void) +jpeg_default_colorspace (j_compress_ptr cinfo) +{ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + break; + case JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ + break; + case JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + break; + case JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + break; + default: + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + } +} + + +/* + * Set the JPEG colorspace, and choose colorspace-dependent default values. + */ + +GLOBAL(void) +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) +{ + jpeg_component_info * compptr; + int ci; + +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \ + (compptr = &cinfo->comp_info[index], \ + compptr->component_id = (id), \ + compptr->h_samp_factor = (hsamp), \ + compptr->v_samp_factor = (vsamp), \ + compptr->quant_tbl_no = (quant), \ + compptr->dc_tbl_no = (dctbl), \ + compptr->ac_tbl_no = (actbl) ) + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* For all colorspaces, we use Q and Huff tables 0 for luminance components, + * tables 1 for chrominance components. + */ + + cinfo->jpeg_color_space = colorspace; + + cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */ + cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */ + + switch (colorspace) { + case JCS_GRAYSCALE: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 1; + /* JFIF specifies component ID 1 */ + SET_COMP(0, 1, 1,1, 0, 0,0); + break; + case JCS_RGB: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ + cinfo->num_components = 3; + SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); + SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); + SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); + break; + case JCS_YCbCr: + cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ + cinfo->num_components = 3; + /* JFIF specifies component IDs 1,2,3 */ + /* We default to 2x2 subsamples of chrominance */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + break; + case JCS_CMYK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ + cinfo->num_components = 4; + SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0); + SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0); + SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0); + SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0); + break; + case JCS_YCCK: + cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ + cinfo->num_components = 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + break; + case JCS_UNKNOWN: + cinfo->num_components = cinfo->input_components; + if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + for (ci = 0; ci < cinfo->num_components; ci++) { + SET_COMP(ci, ci, 1,1, 0, 0,0); + } + break; + default: + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + } +} + + +#ifdef C_PROGRESSIVE_SUPPORTED + +LOCAL(jpeg_scan_info *) +fill_a_scan (jpeg_scan_info * scanptr, int ci, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for specified component */ +{ + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_scans (jpeg_scan_info * scanptr, int ncomps, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for each component */ +{ + int ci; + + for (ci = 0; ci < ncomps; ci++) { + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } + return scanptr; +} + +LOCAL(jpeg_scan_info *) +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) +/* Support routine: generate interleaved DC scan if possible, else N scans */ +{ + int ci; + + if (ncomps <= MAX_COMPS_IN_SCAN) { + /* Single interleaved DC scan */ + scanptr->comps_in_scan = ncomps; + for (ci = 0; ci < ncomps; ci++) + scanptr->component_index[ci] = ci; + scanptr->Ss = scanptr->Se = 0; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + } else { + /* Noninterleaved DC scan for each component */ + scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + } + return scanptr; +} + + +/* + * Create a recommended progressive-JPEG script. + * cinfo->num_components and cinfo->jpeg_color_space must be correct. + */ + +GLOBAL(void) +jpeg_simple_progression (j_compress_ptr cinfo) +{ + int ncomps = cinfo->num_components; + int nscans; + jpeg_scan_info * scanptr; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + /* Figure space needed for script. Calculation must match code below! */ + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + nscans = 10; + } else { + /* All-purpose script for other color spaces. */ + if (ncomps > MAX_COMPS_IN_SCAN) + nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ + else + nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ + } + + /* Allocate space for script. + * We need to put it in the permanent pool in case the application performs + * multiple compressions without changing the settings. To avoid a memory + * leak if jpeg_simple_progression is called repeatedly for the same JPEG + * object, we try to re-use previously allocated space, and we allocate + * enough space to handle YCbCr even if initially asked for grayscale. + */ + if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) { + cinfo->script_space_size = MAX(nscans, 10); + cinfo->script_space = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + } + scanptr = cinfo->script_space; + cinfo->scan_info = scanptr; + cinfo->num_scans = nscans; + + if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { + /* Custom script for YCbCr color images. */ + /* Initial DC scan */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + /* Initial AC scan: get some luma data out in a hurry */ + scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); + /* Chroma data is too small to be worth expending many scans on */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1); + /* Complete spectral selection for luma AC */ + scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2); + /* Refine next bit of luma AC */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1); + /* Finish DC successive approximation */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + /* Finish AC successive approximation */ + scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); + /* Luma bottom bit comes last since it's usually largest scan */ + scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); + } else { + /* All-purpose script for other color spaces. */ + /* Successive approximation first pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); + /* Successive approximation second pass */ + scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1); + /* Successive approximation final pass */ + scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); + } +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jcphuff.c b/src/dep/src/irrlicht/jpeglib/jcphuff.c new file mode 100644 index 0000000..a4ee850 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcphuff.c @@ -0,0 +1,833 @@ +/* + * jcphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for progressive JPEG. + * + * We do not support output suspension in this module, since the library + * currently does not allow multiple-scan files to be written with output + * suspension. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jchuff.h" /* Declarations shared with jchuff.c */ + +#ifdef C_PROGRESSIVE_SUPPORTED + +/* Expanded entropy encoder object for progressive Huffman encoding. */ + +typedef struct { + struct jpeg_entropy_encoder pub; /* public fields */ + + /* Mode flag: TRUE for optimization, FALSE for actual data output */ + boolean gather_statistics; + + /* Bit-level coding status. + * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. + */ + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ + + /* Coding status for DC components */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ + + /* Coding status for AC components */ + int ac_tbl_no; /* the table number of the single component */ + unsigned int EOBRUN; /* run length of EOBs */ + unsigned int BE; /* # of buffered correction bits before MCU */ + char * bit_buffer; /* buffer for correction bits (1 per char) */ + /* packing correction bits tightly would save some space but cost time... */ + + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan). + * Since any one scan codes only DC or only AC, we only need one set + * of tables, not one for DC and one for AC. + */ + c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Statistics tables for optimization; again, one set is enough */ + long * count_ptrs[NUM_HUFF_TBLS]; +} phuff_entropy_encoder; + +typedef phuff_entropy_encoder * phuff_entropy_ptr; + +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit + * buffer can hold. Larger sizes may slightly improve compression, but + * 1000 is already well into the realm of overkill. + * The minimum safe size is 64 bits. + */ + +#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ + +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. + * We assume that int right shift is unsigned if INT32 right shift is, + * which should be safe. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS int ishift_temp; +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo)); +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); + + +/* + * Initialize for a Huffman-compressed scan using progressive JPEG. + */ + +METHODDEF(void) +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + + entropy->cinfo = cinfo; + entropy->gather_statistics = gather_statistics; + + is_DC_band = (cinfo->Ss == 0); + + /* We assume jcmaster.c already validated the scan parameters. */ + + /* Select execution routines */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_first; + else + entropy->pub.encode_mcu = encode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.encode_mcu = encode_mcu_DC_refine; + else { + entropy->pub.encode_mcu = encode_mcu_AC_refine; + /* AC refinement needs a correction bit buffer */ + if (entropy->bit_buffer == NULL) + entropy->bit_buffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(char)); + } + } + if (gather_statistics) + entropy->pub.finish_pass = finish_pass_gather_phuff; + else + entropy->pub.finish_pass = finish_pass_phuff; + + /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 + * for AC coefficients. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Initialize DC predictions to 0 */ + entropy->last_dc_val[ci] = 0; + /* Get table index */ + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; + } + if (gather_statistics) { + /* Check for invalid table index */ + /* (make_c_derived_tbl does this in the other path) */ + if (tbl < 0 || tbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->count_ptrs[tbl] == NULL) + entropy->count_ptrs[tbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); + } else { + /* Compute derived values for Huffman table */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + & entropy->derived_tbls[tbl]); + } + } + + /* Initialize AC stuff */ + entropy->EOBRUN = 0; + entropy->BE = 0; + + /* Initialize bit buffer to empty */ + entropy->put_buffer = 0; + entropy->put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file. + * NB: these must be called only when actually outputting, + * that is, entropy->gather_statistics == FALSE. + */ + +/* Emit a byte */ +#define emit_byte(entropy,val) \ + { *(entropy)->next_output_byte++ = (JOCTET) (val); \ + if (--(entropy)->free_in_buffer == 0) \ + dump_buffer(entropy); } + + +LOCAL(void) +dump_buffer (phuff_entropy_ptr entropy) +/* Empty the output buffer; we do not support suspension in this module. */ +{ + struct jpeg_destination_mgr * dest = entropy->cinfo->dest; + + if (! (*dest->empty_output_buffer) (entropy->cinfo)) + ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); + /* After a successful buffer dump, must reset buffer pointers */ + entropy->next_output_byte = dest->next_output_byte; + entropy->free_in_buffer = dest->free_in_buffer; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(void) +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) +/* Emit some bits, unless we are in gather mode */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = entropy->put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + if (entropy->gather_statistics) + return; /* do nothing if we're only getting stats */ + + put_buffer &= (((INT32) 1)<put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(entropy, c); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(entropy, 0); + } + put_buffer <<= 8; + put_bits -= 8; + } + + entropy->put_buffer = put_buffer; /* update variables */ + entropy->put_bits = put_bits; +} + + +LOCAL(void) +flush_bits (phuff_entropy_ptr entropy) +{ + emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ + entropy->put_buffer = 0; /* and reset bit-buffer to empty */ + entropy->put_bits = 0; +} + + +/* + * Emit (or just count) a Huffman symbol. + */ + +INLINE +LOCAL(void) +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) +{ + if (entropy->gather_statistics) + entropy->count_ptrs[tbl_no][symbol]++; + else { + c_derived_tbl * tbl = entropy->derived_tbls[tbl_no]; + emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]); + } +} + + +/* + * Emit bits from a correction bit buffer. + */ + +LOCAL(void) +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, + unsigned int nbits) +{ + if (entropy->gather_statistics) + return; /* no real work */ + + while (nbits > 0) { + emit_bits(entropy, (unsigned int) (*bufstart), 1); + bufstart++; + nbits--; + } +} + + +/* + * Emit any pending EOBRUN symbol. + */ + +LOCAL(void) +emit_eobrun (phuff_entropy_ptr entropy) +{ + register int temp, nbits; + + if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ + temp = entropy->EOBRUN; + nbits = 0; + while ((temp >>= 1)) + nbits++; + /* safety check: shouldn't happen given limited correction-bit buffer */ + if (nbits > 14) + ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); + + emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); + if (nbits) + emit_bits(entropy, entropy->EOBRUN, nbits); + + entropy->EOBRUN = 0; + + /* Emit any buffered correction bits */ + emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); + entropy->BE = 0; + } +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(void) +emit_restart (phuff_entropy_ptr entropy, int restart_num) +{ + int ci; + + emit_eobrun(entropy); + + if (! entropy->gather_statistics) { + flush_bits(entropy); + emit_byte(entropy, 0xFF); + emit_byte(entropy, JPEG_RST0 + restart_num); + } + + if (entropy->cinfo->Ss == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) + entropy->last_dc_val[ci] = 0; + } else { + /* Re-initialize all AC-related fields to 0 */ + entropy->EOBRUN = 0; + entropy->BE = 0; + } +} + + +/* + * MCU encoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + int blkn, ci; + int Al = cinfo->Al; + JBLOCKROW block; + jpeg_component_info * compptr; + ISHIFT_TEMPS + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + + /* Compute the DC value after the required point transform by Al. + * This is simply an arithmetic right shift. + */ + temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al); + + /* DC differences are figured on the point-transformed values. */ + temp = temp2 - entropy->last_dc_val[ci]; + entropy->last_dc_val[ci] = temp2; + + /* Encode the DC coefficient difference per section G.1.2.1 */ + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_symbol(entropy, compptr->dc_tbl_no, nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + emit_bits(entropy, (unsigned int) temp2, nbits); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp, temp2; + register int nbits; + register int r, k; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ + + r = 0; /* r = run length of zeros */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { + r++; + continue; + } + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value; so the code is + * interwoven with finding the abs value (temp) and output bits (temp2). + */ + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + temp2 = ~temp; + } else { + temp >>= Al; /* apply the point transform */ + temp2 = temp; + } + /* Watch out for case that nonzero coef is zero after point transform */ + if (temp == 0) { + r++; + continue; + } + + /* Emit any pending EOBRUN */ + if (entropy->EOBRUN > 0) + emit_eobrun(entropy); + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + emit_bits(entropy, (unsigned int) temp2, nbits); + + r = 0; /* reset zero run length */ + } + + if (r > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + if (entropy->EOBRUN == 0x7FFF) + emit_eobrun(entropy); /* force it out to avoid overflow */ + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + int blkn; + int Al = cinfo->Al; + JBLOCKROW block; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* We simply emit the Al'th bit of the DC coefficient value. */ + temp = (*block)[0]; + emit_bits(entropy, (unsigned int) (temp >> Al), 1); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * MCU encoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + register int temp; + register int r, k; + int EOB; + char *BR_buffer; + unsigned int BR; + int Se = cinfo->Se; + int Al = cinfo->Al; + JBLOCKROW block; + int absvalues[DCTSIZE2]; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) + if (entropy->restarts_to_go == 0) + emit_restart(entropy, entropy->next_restart_num); + + /* Encode the MCU data block */ + block = MCU_data[0]; + + /* It is convenient to make a pre-pass to determine the transformed + * coefficients' absolute values and the EOB position. + */ + EOB = 0; + for (k = cinfo->Ss; k <= Se; k++) { + temp = (*block)[jpeg_natural_order[k]]; + /* We must apply the point transform by Al. For AC coefficients this + * is an integer division with rounding towards 0. To do this portably + * in C, we shift after obtaining the absolute value. + */ + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + absvalues[k] = temp; /* save abs value for main pass */ + if (temp == 1) + EOB = k; /* EOB = index of last newly-nonzero coef */ + } + + /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ + + r = 0; /* r = run length of zeros */ + BR = 0; /* BR = count of buffered bits added now */ + BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ + + for (k = cinfo->Ss; k <= Se; k++) { + if ((temp = absvalues[k]) == 0) { + r++; + continue; + } + + /* Emit any required ZRLs, but not if they can be folded into EOB */ + while (r > 15 && k <= EOB) { + /* emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + /* Emit ZRL */ + emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); + r -= 16; + /* Emit buffered correction bits that must be associated with ZRL */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + } + + /* If the coef was previously nonzero, it only needs a correction bit. + * NOTE: a straight translation of the spec's figure G.7 would suggest + * that we also need to test r > 15. But if r > 15, we can only get here + * if k > EOB, which implies that this coefficient is not 1. + */ + if (temp > 1) { + /* The correction bit is the next bit of the absolute value. */ + BR_buffer[BR++] = (char) (temp & 1); + continue; + } + + /* Emit any pending EOBRUN and the BE correction bits */ + emit_eobrun(entropy); + + /* Count/emit Huffman symbol for run length / number of bits */ + emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); + + /* Emit output bit for newly-nonzero coef */ + temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; + emit_bits(entropy, (unsigned int) temp, 1); + + /* Emit buffered correction bits that must be associated with this code */ + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ + BR = 0; + r = 0; /* reset zero run length */ + } + + if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + entropy->BE += BR; /* concat my correction bits to older ones */ + /* We force out the EOB if we risk either: + * 1. overflow of the EOB counter; + * 2. overflow of the correction bit buffer during the next MCU. + */ + if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) + emit_eobrun(entropy); + } + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed progressive scan. + */ + +METHODDEF(void) +finish_pass_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + + entropy->next_output_byte = cinfo->dest->next_output_byte; + entropy->free_in_buffer = cinfo->dest->free_in_buffer; + + /* Flush out any buffered data */ + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo->dest->next_output_byte = entropy->next_output_byte; + cinfo->dest->free_in_buffer = entropy->free_in_buffer; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather_phuff (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band; + int ci, tbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did[NUM_HUFF_TBLS]; + + /* Flush out buffered data (all we care about is counting the EOB symbol) */ + emit_eobrun(entropy); + + is_DC_band = (cinfo->Ss == 0); + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did, SIZEOF(did)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + if (is_DC_band) { + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; + tbl = compptr->dc_tbl_no; + } else { + tbl = compptr->ac_tbl_no; + } + if (! did[tbl]) { + if (is_DC_band) + htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; + else + htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); + did[tbl] = TRUE; + } + } +} + + +/* + * Module initialization routine for progressive Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_phuff_encoder (j_compress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)); + cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; + entropy->pub.start_pass = start_pass_phuff; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + entropy->count_ptrs[i] = NULL; + } + entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ +} + +#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jcprepct.c b/src/dep/src/irrlicht/jpeglib/jcprepct.c new file mode 100644 index 0000000..fdc4bc2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcprepct.c @@ -0,0 +1,354 @@ +/* + * jcprepct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the compression preprocessing controller. + * This controller manages the color conversion, downsampling, + * and edge expansion steps. + * + * Most of the complexity here is associated with buffering input rows + * as required by the downsampler. See the comments at the head of + * jcsample.c for the downsampler's needs. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* At present, jcsample.c can request context rows only for smoothing. + * In the future, we might also need context rows for CCIR601 sampling + * or other more-complex downsampling procedures. The code to support + * context rows should be compiled only if needed. + */ +#ifdef INPUT_SMOOTHING_SUPPORTED +#define CONTEXT_ROWS_SUPPORTED +#endif + + +/* + * For the simple (no-context-row) case, we just need to buffer one + * row group's worth of pixels for the downsampling step. At the bottom of + * the image, we pad to a full row group by replicating the last pixel row. + * The downsampler's last output row is then replicated if needed to pad + * out to a full iMCU row. + * + * When providing context rows, we must buffer three row groups' worth of + * pixels. Three row groups are physically allocated, but the row pointer + * arrays are made five row groups high, with the extra pointers above and + * below "wrapping around" to point to the last and first real row groups. + * This allows the downsampler to access the proper context rows. + * At the top and bottom of the image, we create dummy context rows by + * copying the first or last real pixel row. This copying could be avoided + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + * trouble on the compression side. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_prep_controller pub; /* public fields */ + + /* Downsampling input buffer. This buffer holds color-converted data + * until we have enough to do a downsample step. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + JDIMENSION rows_to_go; /* counts rows remaining in source image */ + int next_buf_row; /* index of next row to store in color_buf */ + +#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ + int this_row_group; /* starting row index of group to process */ + int next_buf_stop; /* downsample when we reach this index */ +#endif +} my_prep_controller; + +typedef my_prep_controller * my_prep_ptr; + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + + if (pass_mode != JBUF_PASS_THRU) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Initialize total-height counter for detecting bottom of image */ + prep->rows_to_go = cinfo->image_height; + /* Mark the conversion buffer empty */ + prep->next_buf_row = 0; +#ifdef CONTEXT_ROWS_SUPPORTED + /* Preset additional state variables for context mode. + * These aren't used in non-context mode, so we needn't test which mode. + */ + prep->this_row_group = 0; + /* Set next_buf_stop to stop after two row groups have been read in. */ + prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; +#endif +} + + +/* + * Expand an image vertically from height input_rows to height output_rows, + * by duplicating the bottom row. + */ + +LOCAL(void) +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, + int input_rows, int output_rows) +{ + register int row; + + for (row = input_rows; row < output_rows; row++) { + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + } +} + + +/* + * Process some data in the simple no-context case. + * + * Preprocessor output data is counted in "row groups". A row group + * is defined to be v_samp_factor sample rows of each component. + * Downsampling will produce this much data from each max_v_samp_factor + * input rows. + */ + +METHODDEF(void) +pre_process_data (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + JDIMENSION inrows; + jpeg_component_info * compptr; + + while (*in_row_ctr < in_rows_avail && + *out_row_group_ctr < out_row_groups_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = cinfo->max_v_samp_factor - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + /* If at bottom of image, pad to fill the conversion buffer. */ + if (prep->rows_to_go == 0 && + prep->next_buf_row < cinfo->max_v_samp_factor) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, cinfo->max_v_samp_factor); + } + prep->next_buf_row = cinfo->max_v_samp_factor; + } + /* If we've filled the conversion buffer, empty it. */ + if (prep->next_buf_row == cinfo->max_v_samp_factor) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, (JDIMENSION) 0, + output_buf, *out_row_group_ctr); + prep->next_buf_row = 0; + (*out_row_group_ctr)++; + } + /* If at bottom of image, pad the output to a full iMCU height. + * Note we assume the caller is providing a one-iMCU-height output buffer! + */ + if (prep->rows_to_go == 0 && + *out_row_group_ctr < out_row_groups_avail) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_blocks * DCTSIZE, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); + } + *out_row_group_ctr = out_row_groups_avail; + break; /* can exit outer loop without test */ + } + } +} + + +#ifdef CONTEXT_ROWS_SUPPORTED + +/* + * Process some data in the context case. + */ + +METHODDEF(void) +pre_process_context (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int numrows, ci; + int buf_height = cinfo->max_v_samp_factor * 3; + JDIMENSION inrows; + + while (*out_row_group_ctr < out_row_groups_avail) { + if (*in_row_ctr < in_rows_avail) { + /* Do color conversion to fill the conversion buffer. */ + inrows = in_rows_avail - *in_row_ctr; + numrows = prep->next_buf_stop - prep->next_buf_row; + numrows = (int) MIN((JDIMENSION) numrows, inrows); + (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); + /* Pad at top of image, if first time through */ + if (prep->rows_to_go == cinfo->image_height) { + for (ci = 0; ci < cinfo->num_components; ci++) { + int row; + for (row = 1; row <= cinfo->max_v_samp_factor; row++) { + jcopy_sample_rows(prep->color_buf[ci], 0, + prep->color_buf[ci], -row, + 1, cinfo->image_width); + } + } + } + *in_row_ctr += numrows; + prep->next_buf_row += numrows; + prep->rows_to_go -= numrows; + } else { + /* Return for more data, unless we are at the bottom of the image. */ + if (prep->rows_to_go != 0) + break; + /* When at bottom of image, pad to fill the conversion buffer. */ + if (prep->next_buf_row < prep->next_buf_stop) { + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; + } + } + /* If we've gotten enough data, downsample a row group. */ + if (prep->next_buf_row == prep->next_buf_stop) { + (*cinfo->downsample->downsample) (cinfo, + prep->color_buf, + (JDIMENSION) prep->this_row_group, + output_buf, *out_row_group_ctr); + (*out_row_group_ctr)++; + /* Advance pointers with wraparound as necessary. */ + prep->this_row_group += cinfo->max_v_samp_factor; + if (prep->this_row_group >= buf_height) + prep->this_row_group = 0; + if (prep->next_buf_row >= buf_height) + prep->next_buf_row = 0; + prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; + } + } +} + + +/* + * Create the wrapped-around downsampling input buffer needed for context mode. + */ + +LOCAL(void) +create_context_buffer (j_compress_ptr cinfo) +{ + my_prep_ptr prep = (my_prep_ptr) cinfo->prep; + int rgroup_height = cinfo->max_v_samp_factor; + int ci, i; + jpeg_component_info * compptr; + JSAMPARRAY true_buffer, fake_buffer; + + /* Grab enough space for fake row pointers for all the components; + * we need five row groups' worth of pointers for each component. + */ + fake_buffer = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate the actual buffer space (3 row groups) for this component. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + true_buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) (3 * rgroup_height)); + /* Copy true buffer row pointers into the middle of the fake row array */ + MEMCOPY(fake_buffer + rgroup_height, true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + /* Fill in the above and below wraparound pointers */ + for (i = 0; i < rgroup_height; i++) { + fake_buffer[i] = true_buffer[2 * rgroup_height + i]; + fake_buffer[4 * rgroup_height + i] = true_buffer[i]; + } + prep->color_buf[ci] = fake_buffer + rgroup_height; + fake_buffer += 5 * rgroup_height; /* point to space for next component */ + } +} + +#endif /* CONTEXT_ROWS_SUPPORTED */ + + +/* + * Initialize preprocessing controller. + */ + +GLOBAL(void) +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + my_prep_ptr prep; + int ci; + jpeg_component_info * compptr; + + if (need_full_buffer) /* safety check */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + prep = (my_prep_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_prep_controller)); + cinfo->prep = (struct jpeg_c_prep_controller *) prep; + prep->pub.start_pass = start_pass_prep; + + /* Allocate the color conversion buffer. + * We make the buffer wide enough to allow the downsampler to edge-expand + * horizontally within the buffer, if it so chooses. + */ + if (cinfo->downsample->need_context_rows) { + /* Set up to provide context rows */ +#ifdef CONTEXT_ROWS_SUPPORTED + prep->pub.pre_process_data = pre_process_context; + create_context_buffer(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* No context, just make it tall enough for one row group */ + prep->pub.pre_process_data = pre_process_data; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jcsample.c b/src/dep/src/irrlicht/jpeglib/jcsample.c new file mode 100644 index 0000000..fe29fca --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jcsample.c @@ -0,0 +1,519 @@ +/* + * jcsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains downsampling routines. + * + * Downsampling input data is counted in "row groups". A row group + * is defined to be max_v_samp_factor pixel rows of each component, + * from which the downsampler produces v_samp_factor sample rows. + * A single row group is processed in each call to the downsampler module. + * + * The downsampler is responsible for edge-expansion of its output data + * to fill an integral number of DCT blocks horizontally. The source buffer + * may be modified if it is helpful for this purpose (the source buffer is + * allocated wide enough to correspond to the desired output width). + * The caller (the prep controller) is responsible for vertical padding. + * + * The downsampler may request "context rows" by setting need_context_rows + * during startup. In this case, the input arrays will contain at least + * one row group's worth of pixels above and below the passed-in data; + * the caller will create dummy rows at image top and bottom by replicating + * the first or last real pixel row. + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + * + * The downsampling algorithm used here is a simple average of the source + * pixels covered by the output pixel. The hi-falutin sampling literature + * refers to this as a "box filter". In general the characteristics of a box + * filter are not very good, but for the specific cases we normally use (1:1 + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + * nearly so bad. If you intend to use other sampling ratios, you'd be well + * advised to improve this code. + * + * A simple input-smoothing capability is provided. This is mainly intended + * for cleaning up color-dithered GIF input files (if you find it inadequate, + * we suggest using an external filtering program such as pnmconvol). When + * enabled, each input pixel P is replaced by a weighted sum of itself and its + * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + * where SF = (smoothing_factor / 1024). + * Currently, smoothing is only supported for 2h2v sampling factors. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to downsample a single component */ +typedef JMETHOD(void, downsample1_ptr, + (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data)); + +/* Private subobject */ + +typedef struct { + struct jpeg_downsampler pub; /* public fields */ + + /* Downsampling method pointers, one per component */ + downsample1_ptr methods[MAX_COMPONENTS]; +} my_downsampler; + +typedef my_downsampler * my_downsample_ptr; + + +/* + * Initialize for a downsampling pass. + */ + +METHODDEF(void) +start_pass_downsample (j_compress_ptr cinfo) +{ + /* no work for now */ +} + + +/* + * Expand a component horizontally from width input_cols to width output_cols, + * by duplicating the rightmost samples. + */ + +LOCAL(void) +expand_right_edge (JSAMPARRAY image_data, int num_rows, + JDIMENSION input_cols, JDIMENSION output_cols) +{ + register JSAMPROW ptr; + register JSAMPLE pixval; + register int count; + int row; + int numcols = (int) (output_cols - input_cols); + + if (numcols > 0) { + for (row = 0; row < num_rows; row++) { + ptr = image_data[row] + input_cols; + pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ + for (count = numcols; count > 0; count--) + *ptr++ = pixval; + } + } +} + + +/* + * Do downsampling for a whole row group (all components). + * + * In this version we simply downsample each component independently. + */ + +METHODDEF(void) +sep_downsample (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) +{ + my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; + int ci; + jpeg_component_info * compptr; + JSAMPARRAY in_ptr, out_ptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + in_ptr = input_buf[ci] + in_row_index; + out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); + (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); + } +} + + +/* + * Downsample pixel values of a single component. + * One row group is processed per call. + * This version handles arbitrary integral sampling ratios, without smoothing. + * Note that this version is not actually used for customary sampling ratios. + */ + +METHODDEF(void) +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; + JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JSAMPROW inptr, outptr; + INT32 outvalue; + + h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; + v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; + numpix = h_expand * v_expand; + numpix2 = numpix/2; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * h_expand); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + for (outcol = 0, outcol_h = 0; outcol < output_cols; + outcol++, outcol_h += h_expand) { + outvalue = 0; + for (v = 0; v < v_expand; v++) { + inptr = input_data[inrow+v] + outcol_h; + for (h = 0; h < h_expand; h++) { + outvalue += (INT32) GETJSAMPLE(*inptr++); + } + } + *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); + } + inrow += v_expand; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * without smoothing. + */ + +METHODDEF(void) +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + /* Copy the data */ + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo->max_v_samp_factor, cinfo->image_width); + /* Edge-expand */ + expand_right_edge(output_data, cinfo->max_v_samp_factor, + cinfo->image_width, compptr->width_in_blocks * DCTSIZE); +} + + +/* + * Downsample pixel values of a single component. + * This version handles the common case of 2:1 horizontal and 1:1 vertical, + * without smoothing. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + bias = 0; /* bias = 0,1,0,1,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + + bias) >> 1); + bias ^= 1; /* 0=>1, 1=>0 */ + inptr += 2; + } + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * without smoothing. + */ + +METHODDEF(void) +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION outcol; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, outptr; + register int bias; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data, cinfo->max_v_samp_factor, + cinfo->image_width, output_cols * 2); + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + bias = 1; /* bias = 1,2,1,2,... for successive samples */ + for (outcol = 0; outcol < output_cols; outcol++) { + *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + + bias) >> 2); + bias ^= 3; /* 1=>2, 2=>1 */ + inptr0 += 2; inptr1 += 2; + } + inrow += 2; + } +} + + +#ifdef INPUT_SMOOTHING_SUPPORTED + +/* + * Downsample pixel values of a single component. + * This version handles the standard case of 2:1 horizontal and 2:1 vertical, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int inrow, outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols * 2); + + /* We don't bother to form the individual "smoothed" input pixel values; + * we can directly compute the output which is the average of the four + * smoothed values. Each of the four member pixels contributes a fraction + * (1-8*SF) to its own smoothed image and a fraction SF to each of the three + * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + * output. The four corner-adjacent neighbor pixels contribute a fraction + * SF to just one smoothed pixel, or SF/4 to the final output; while the + * eight edge-adjacent neighbors contribute SF to each of two smoothed + * pixels, or SF/2 overall. In order to use integer arithmetic, these + * factors are scaled by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ + neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ + + inrow = 0; + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr0 = input_data[inrow]; + inptr1 = input_data[inrow+1]; + above_ptr = input_data[inrow-1]; + below_ptr = input_data[inrow+2]; + + /* Special case for first column: pretend column -1 is same as column 0 */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); + neighsum += neighsum; + neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + /* sum of pixels directly mapped to this output element */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + /* sum of edge-neighbor pixels */ + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); + /* The edge-neighbors count twice as much as corner-neighbors */ + neighsum += neighsum; + /* Add in the corner-neighbors */ + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); + /* form final output scaled up by 2^16 */ + membersum = membersum * memberscale + neighsum * neighscale; + /* round, descale and output it */ + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + + GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + + GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); + neighsum += neighsum; + neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + + GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + inrow += 2; + } +} + + +/* + * Downsample pixel values of a single component. + * This version handles the special case of a full-size component, + * with smoothing. One row of context is required. + */ + +METHODDEF(void) +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY output_data) +{ + int outrow; + JDIMENSION colctr; + JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + register JSAMPROW inptr, above_ptr, below_ptr, outptr; + INT32 membersum, neighsum, memberscale, neighscale; + int colsum, lastcolsum, nextcolsum; + + /* Expand input data enough to let all the output samples be generated + * by the standard loop. Special-casing padded output would be more + * efficient. + */ + expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, + cinfo->image_width, output_cols); + + /* Each of the eight neighbor pixels contributes a fraction SF to the + * smoothed pixel, while the main pixel contributes (1-8*SF). In order + * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. + * Also recall that SF = smoothing_factor / 1024. + */ + + memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ + neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ + + for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { + outptr = output_data[outrow]; + inptr = input_data[outrow]; + above_ptr = input_data[outrow-1]; + below_ptr = input_data[outrow+1]; + + /* Special case for first column */ + colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + + GETJSAMPLE(*inptr); + membersum = GETJSAMPLE(*inptr++); + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = colsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + + for (colctr = output_cols - 2; colctr > 0; colctr--) { + membersum = GETJSAMPLE(*inptr++); + above_ptr++; below_ptr++; + nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + + GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + nextcolsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); + lastcolsum = colsum; colsum = nextcolsum; + } + + /* Special case for last column */ + membersum = GETJSAMPLE(*inptr); + neighsum = lastcolsum + (colsum - membersum) + colsum; + membersum = membersum * memberscale + neighsum * neighscale; + *outptr = (JSAMPLE) ((membersum + 32768) >> 16); + + } +} + +#endif /* INPUT_SMOOTHING_SUPPORTED */ + + +/* + * Module initialization routine for downsampling. + * Note that we must select a routine for each component. + */ + +GLOBAL(void) +jinit_downsampler (j_compress_ptr cinfo) +{ + my_downsample_ptr downsample; + int ci; + jpeg_component_info * compptr; + boolean smoothok = TRUE; + + downsample = (my_downsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_downsampler)); + cinfo->downsample = (struct jpeg_downsampler *) downsample; + downsample->pub.start_pass = start_pass_downsample; + downsample->pub.downsample = sep_downsample; + downsample->pub.need_context_rows = FALSE; + + if (cinfo->CCIR601_sampling) + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* Verify we can handle the sampling factors, and set up method pointers */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = fullsize_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = fullsize_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor == cinfo->max_v_samp_factor) { + smoothok = FALSE; + downsample->methods[ci] = h2v1_downsample; + } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && + compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor) { + downsample->methods[ci] = h2v2_smooth_downsample; + downsample->pub.need_context_rows = TRUE; + } else +#endif + downsample->methods[ci] = h2v2_downsample; + } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && + (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { + smoothok = FALSE; + downsample->methods[ci] = int_downsample; + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + } + +#ifdef INPUT_SMOOTHING_SUPPORTED + if (cinfo->smoothing_factor && !smoothok) + TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); +#endif +} diff --git a/src/dep/src/irrlicht/jpeglib/jctrans.c b/src/dep/src/irrlicht/jpeglib/jctrans.c new file mode 100644 index 0000000..8b36e36 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jctrans.c @@ -0,0 +1,388 @@ +/* + * jctrans.c + * + * Copyright (C) 1995-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding compression, + * that is, writing raw DCT coefficient arrays to an output JPEG file. + * The routines in jcapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transencode_master_selection + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); +LOCAL(void) transencode_coef_controller + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); + + +/* + * Compression initialization for writing raw-coefficient data. + * Before calling this, all parameters and a data destination must be set up. + * Call jpeg_finish_compress() to actually write the data. + * + * The number of passed virtual arrays must match cinfo->num_components. + * Note that the virtual arrays need not be filled or even realized at + * the time write_coefficients is called; indeed, if the virtual arrays + * were requested from this compression object's memory manager, they + * typically will be realized during this routine and filled afterwards. + */ + +GLOBAL(void) +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) +{ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Mark all tables to be written */ + jpeg_suppress_tables(cinfo, FALSE); + /* (Re)initialize error mgr and destination modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->dest->init_destination) (cinfo); + /* Perform master selection of active modules */ + transencode_master_selection(cinfo, coef_arrays); + /* Wait for jpeg_finish_compress() call */ + cinfo->next_scanline = 0; /* so jpeg_write_marker works */ + cinfo->global_state = CSTATE_WRCOEFS; +} + + +/* + * Initialize the compression object with default parameters, + * then copy from the source object all parameters needed for lossless + * transcoding. Parameters that can be varied without loss (such as + * scan script and Huffman optimization) are left in their default states. + */ + +GLOBAL(void) +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo) +{ + JQUANT_TBL ** qtblptr; + jpeg_component_info *incomp, *outcomp; + JQUANT_TBL *c_quant, *slot_quant; + int tblno, ci, coefi; + + /* Safety check to ensure start_compress not called yet. */ + if (dstinfo->global_state != CSTATE_START) + ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); + /* Copy fundamental image dimensions */ + dstinfo->image_width = srcinfo->image_width; + dstinfo->image_height = srcinfo->image_height; + dstinfo->input_components = srcinfo->num_components; + dstinfo->in_color_space = srcinfo->jpeg_color_space; + /* Initialize all parameters to default values */ + jpeg_set_defaults(dstinfo); + /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + * Fix it to get the right header markers for the image colorspace. + */ + jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); + dstinfo->data_precision = srcinfo->data_precision; + dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; + /* Copy the source's quantization tables. */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { + qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; + if (*qtblptr == NULL) + *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); + MEMCOPY((*qtblptr)->quantval, + srcinfo->quant_tbl_ptrs[tblno]->quantval, + SIZEOF((*qtblptr)->quantval)); + (*qtblptr)->sent_table = FALSE; + } + } + /* Copy the source's per-component info. + * Note we assume jpeg_set_defaults has allocated the dest comp_info array. + */ + dstinfo->num_components = srcinfo->num_components; + if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) + ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, + MAX_COMPONENTS); + for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; + ci < dstinfo->num_components; ci++, incomp++, outcomp++) { + outcomp->component_id = incomp->component_id; + outcomp->h_samp_factor = incomp->h_samp_factor; + outcomp->v_samp_factor = incomp->v_samp_factor; + outcomp->quant_tbl_no = incomp->quant_tbl_no; + /* Make sure saved quantization table for component matches the qtable + * slot. If not, the input file re-used this qtable slot. + * IJG encoder currently cannot duplicate this. + */ + tblno = outcomp->quant_tbl_no; + if (tblno < 0 || tblno >= NUM_QUANT_TBLS || + srcinfo->quant_tbl_ptrs[tblno] == NULL) + ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); + slot_quant = srcinfo->quant_tbl_ptrs[tblno]; + c_quant = incomp->quant_table; + if (c_quant != NULL) { + for (coefi = 0; coefi < DCTSIZE2; coefi++) { + if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) + ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); + } + } + /* Note: we do not copy the source's Huffman table assignments; + * instead we rely on jpeg_set_colorspace to have made a suitable choice. + */ + } + /* Also copy JFIF version and resolution information, if available. + * Strictly speaking this isn't "critical" info, but it's nearly + * always appropriate to copy it if available. In particular, + * if the application chooses to copy JFIF 1.02 extension markers from + * the source file, we need to copy the version to make sure we don't + * emit a file that has 1.02 extensions but a claimed version of 1.01. + * We will *not*, however, copy version info from mislabeled "2.01" files. + */ + if (srcinfo->saw_JFIF_marker) { + if (srcinfo->JFIF_major_version == 1) { + dstinfo->JFIF_major_version = srcinfo->JFIF_major_version; + dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version; + } + dstinfo->density_unit = srcinfo->density_unit; + dstinfo->X_density = srcinfo->X_density; + dstinfo->Y_density = srcinfo->Y_density; + } +} + + +/* + * Master selection of compression modules for transcoding. + * This substitutes for jcinit.c's initialization of the full compressor. + */ + +LOCAL(void) +transencode_master_selection (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + /* Although we don't actually use input_components for transcoding, + * jcmaster.c's initial_setup will complain if input_components is 0. + */ + cinfo->input_components = 1; + /* Initialize master control (includes parameter checking/processing) */ + jinit_c_master_control(cinfo, TRUE /* transcode only */); + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_encoder(cinfo); + } + + /* We need a special coefficient buffer controller. */ + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Write the datastream header (SOI, JFIF) immediately. + * Frame and scan headers are postponed till later. + * This lets application insert special markers after the SOI. + */ + (*cinfo->marker->write_file_header) (cinfo); +} + + +/* + * The rest of this file is a special implementation of the coefficient + * buffer controller. This is similar to jccoefct.c, but it handles only + * output from presupplied virtual arrays. Furthermore, we generate any + * dummy padding blocks on-the-fly rather than expecting them to be present + * in the arrays. + */ + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_c_coef_controller pub; /* public fields */ + + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* Virtual block array for each component. */ + jvirt_barray_ptr * whole_image; + + /* Workspace for constructing dummy blocks at right/bottom edges. */ + JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->mcu_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + if (pass_mode != JBUF_CRANK_DEST) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + coef->iMCU_row_num = 0; + start_iMCU_row(cinfo); +} + + +/* + * Process some data. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor block rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the entropy coder. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, blockcnt; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + coef->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (coef->iMCU_row_num < last_iMCU_row || + yindex+yoffset < compptr->last_row_height) { + /* Fill in pointers to real blocks in this row */ + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < blockcnt; xindex++) + MCU_buffer[blkn++] = buffer_ptr++; + } else { + /* At bottom of image, need a whole row of dummy blocks */ + xindex = 0; + } + /* Fill in any dummy blocks needed in this row. + * Dummy blocks are filled in the same way as in jccoefct.c: + * all zeroes in the AC entries, DC entries equal to previous + * block's DC value. The init routine has already zeroed the + * AC entries, so we need only set the DC entries correctly. + */ + for (; xindex < compptr->MCU_width; xindex++) { + MCU_buffer[blkn] = coef->dummy_buffer[blkn]; + MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; + blkn++; + } + } + } + /* Try to write the MCU. */ + if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->mcu_ctr = MCU_col_num; + return FALSE; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->mcu_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + coef->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +/* + * Initialize coefficient buffer controller. + * + * Each passed coefficient array must be the right size for that + * coefficient: width_in_blocks wide and height_in_blocks high, + * with unitheight at least v_samp_factor. + */ + +LOCAL(void) +transencode_coef_controller (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + my_coef_ptr coef; + JBLOCKROW buffer; + int i; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_c_coef_controller *) coef; + coef->pub.start_pass = start_pass_coef; + coef->pub.compress_data = compress_output; + + /* Save pointer to virtual arrays */ + coef->whole_image = coef_arrays; + + /* Allocate and pre-zero space for dummy DCT blocks. */ + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + coef->dummy_buffer[i] = buffer + i; + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdapimin.c b/src/dep/src/irrlicht/jpeglib/jdapimin.c new file mode 100644 index 0000000..bd1df92 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdapimin.c @@ -0,0 +1,395 @@ +/* + * jdapimin.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "minimum" API routines that may be + * needed in either the normal full-decompression case or the + * transcoding-only case. + * + * Most of the routines intended to be called directly by an application + * are in this file or in jdapistd.c. But also see jcomapi.c for routines + * shared by compression and decompression, and jdtrans.c for the transcoding + * case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Initialization of a JPEG decompression object. + * The error manager must already be set up (in case memory manager fails). + */ + +GLOBAL(void) +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) +{ + int i; + + /* Guard against version mismatches between library and caller. */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + if (version != JPEG_LIB_VERSION) + ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize != SIZEOF(struct jpeg_decompress_struct)) + ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, + (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); + + /* For debugging purposes, we zero the whole master structure. + * But the application has already set the err pointer, and may have set + * client_data, so we have to save and restore those fields. + * Note: if application hasn't set client_data, tools like Purify may + * complain here. + */ + { + struct jpeg_error_mgr * err = cinfo->err; + void * client_data = cinfo->client_data; /* ignore Purify complaint here */ + MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); + cinfo->err = err; + cinfo->client_data = client_data; + } + cinfo->is_decompressor = TRUE; + + /* Initialize a memory manager instance for this object */ + jinit_memory_mgr((j_common_ptr) cinfo); + + /* Zero out pointers to permanent structures. */ + cinfo->progress = NULL; + cinfo->src = NULL; + + for (i = 0; i < NUM_QUANT_TBLS; i++) + cinfo->quant_tbl_ptrs[i] = NULL; + + for (i = 0; i < NUM_HUFF_TBLS; i++) { + cinfo->dc_huff_tbl_ptrs[i] = NULL; + cinfo->ac_huff_tbl_ptrs[i] = NULL; + } + + /* Initialize marker processor so application can override methods + * for COM, APPn markers before calling jpeg_read_header. + */ + cinfo->marker_list = NULL; + jinit_marker_reader(cinfo); + + /* And initialize the overall input controller. */ + jinit_input_controller(cinfo); + + /* OK, I'm ready */ + cinfo->global_state = DSTATE_START; +} + + +/* + * Destruction of a JPEG decompression object + */ + +GLOBAL(void) +jpeg_destroy_decompress (j_decompress_ptr cinfo) +{ + jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Abort processing of a JPEG decompression operation, + * but don't destroy the object itself. + */ + +GLOBAL(void) +jpeg_abort_decompress (j_decompress_ptr cinfo) +{ + jpeg_abort((j_common_ptr) cinfo); /* use common routine */ +} + + +/* + * Set default decompression parameters. + */ + +LOCAL(void) +default_decompress_parms (j_decompress_ptr cinfo) +{ + /* Guess the input colorspace, and set output colorspace accordingly. */ + /* (Wish JPEG committee had provided a real way to specify this...) */ + /* Note application may override our guesses. */ + switch (cinfo->num_components) { + case 1: + cinfo->jpeg_color_space = JCS_GRAYSCALE; + cinfo->out_color_space = JCS_GRAYSCALE; + break; + + case 3: + if (cinfo->saw_JFIF_marker) { + cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ + } else if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_RGB; + break; + case 1: + cinfo->jpeg_color_space = JCS_YCbCr; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + break; + } + } else { + /* Saw no special markers, try to guess from the component IDs */ + int cid0 = cinfo->comp_info[0].component_id; + int cid1 = cinfo->comp_info[1].component_id; + int cid2 = cinfo->comp_info[2].component_id; + + if (cid0 == 1 && cid1 == 2 && cid2 == 3) + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ + else { + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + } + } + /* Always guess RGB is proper output colorspace. */ + cinfo->out_color_space = JCS_RGB; + break; + + case 4: + if (cinfo->saw_Adobe_marker) { + switch (cinfo->Adobe_transform) { + case 0: + cinfo->jpeg_color_space = JCS_CMYK; + break; + case 2: + cinfo->jpeg_color_space = JCS_YCCK; + break; + default: + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ + break; + } + } else { + /* No special markers, assume straight CMYK. */ + cinfo->jpeg_color_space = JCS_CMYK; + } + cinfo->out_color_space = JCS_CMYK; + break; + + default: + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->out_color_space = JCS_UNKNOWN; + break; + } + + /* Set defaults for other decompression parameters. */ + cinfo->scale_num = 1; /* 1:1 scaling */ + cinfo->scale_denom = 1; + cinfo->output_gamma = 1.0; + cinfo->buffered_image = FALSE; + cinfo->raw_data_out = FALSE; + cinfo->dct_method = JDCT_DEFAULT; + cinfo->do_fancy_upsampling = TRUE; + cinfo->do_block_smoothing = TRUE; + cinfo->quantize_colors = FALSE; + /* We set these in case application only sets quantize_colors. */ + cinfo->dither_mode = JDITHER_FS; +#ifdef QUANT_2PASS_SUPPORTED + cinfo->two_pass_quantize = TRUE; +#else + cinfo->two_pass_quantize = FALSE; +#endif + cinfo->desired_number_of_colors = 256; + cinfo->colormap = NULL; + /* Initialize for no mode change in buffered-image mode. */ + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; +} + + +/* + * Decompression startup: read start of JPEG datastream to see what's there. + * Need only initialize JPEG object and supply a data source before calling. + * + * This routine will read as far as the first SOS marker (ie, actual start of + * compressed data), and will save all tables and parameters in the JPEG + * object. It will also initialize the decompression parameters to default + * values, and finally return JPEG_HEADER_OK. On return, the application may + * adjust the decompression parameters and then call jpeg_start_decompress. + * (Or, if the application only wanted to determine the image parameters, + * the data need not be decompressed. In that case, call jpeg_abort or + * jpeg_destroy to release any temporary space.) + * If an abbreviated (tables only) datastream is presented, the routine will + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + * re-use the JPEG object to read the abbreviated image datastream(s). + * It is unnecessary (but OK) to call jpeg_abort in this case. + * The JPEG_SUSPENDED return code only occurs if the data source module + * requests suspension of the decompressor. In this case the application + * should load more source data and then re-call jpeg_read_header to resume + * processing. + * If a non-suspending data source is used and require_image is TRUE, then the + * return code need not be inspected since only JPEG_HEADER_OK is possible. + * + * This routine is now just a front end to jpeg_consume_input, with some + * extra error checking. + */ + +GLOBAL(int) +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) +{ + int retcode; + + if (cinfo->global_state != DSTATE_START && + cinfo->global_state != DSTATE_INHEADER) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + retcode = jpeg_consume_input(cinfo); + + switch (retcode) { + case JPEG_REACHED_SOS: + retcode = JPEG_HEADER_OK; + break; + case JPEG_REACHED_EOI: + if (require_image) /* Complain if application wanted an image */ + ERREXIT(cinfo, JERR_NO_IMAGE); + /* Reset to start state; it would be safer to require the application to + * call jpeg_abort, but we can't change it now for compatibility reasons. + * A side effect is to free any temporary memory (there shouldn't be any). + */ + jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ + retcode = JPEG_HEADER_TABLES_ONLY; + break; + case JPEG_SUSPENDED: + /* no work */ + break; + } + + return retcode; +} + + +/* + * Consume data in advance of what the decompressor requires. + * This can be called at any time once the decompressor object has + * been created and a data source has been set up. + * + * This routine is essentially a state machine that handles a couple + * of critical state-transition actions, namely initial setup and + * transition from header scanning to ready-for-start_decompress. + * All the actual input is done via the input controller's consume_input + * method. + */ + +GLOBAL(int) +jpeg_consume_input (j_decompress_ptr cinfo) +{ + int retcode = JPEG_SUSPENDED; + + /* NB: every possible DSTATE value should be listed in this switch */ + switch (cinfo->global_state) { + case DSTATE_START: + /* Start-of-datastream actions: reset appropriate modules */ + (*cinfo->inputctl->reset_input_controller) (cinfo); + /* Initialize application's data source module */ + (*cinfo->src->init_source) (cinfo); + cinfo->global_state = DSTATE_INHEADER; + /*FALLTHROUGH*/ + case DSTATE_INHEADER: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ + /* Set up default parameters based on header data */ + default_decompress_parms(cinfo); + /* Set global state: ready for start_decompress */ + cinfo->global_state = DSTATE_READY; + } + break; + case DSTATE_READY: + /* Can't advance past first SOS until start_decompress is called */ + retcode = JPEG_REACHED_SOS; + break; + case DSTATE_PRELOAD: + case DSTATE_PRESCAN: + case DSTATE_SCANNING: + case DSTATE_RAW_OK: + case DSTATE_BUFIMAGE: + case DSTATE_BUFPOST: + case DSTATE_STOPPING: + retcode = (*cinfo->inputctl->consume_input) (cinfo); + break; + default: + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + return retcode; +} + + +/* + * Have we finished reading the input file? + */ + +GLOBAL(boolean) +jpeg_input_complete (j_decompress_ptr cinfo) +{ + /* Check for valid jpeg object */ + if (cinfo->global_state < DSTATE_START || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->eoi_reached; +} + + +/* + * Is there more than one scan? + */ + +GLOBAL(boolean) +jpeg_has_multiple_scans (j_decompress_ptr cinfo) +{ + /* Only valid after jpeg_read_header completes */ + if (cinfo->global_state < DSTATE_READY || + cinfo->global_state > DSTATE_STOPPING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return cinfo->inputctl->has_multiple_scans; +} + + +/* + * Finish JPEG decompression. + * + * This will normally just verify the file trailer and release temp storage. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_decompress (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { + /* Terminate final pass of non-buffered mode */ + if (cinfo->output_scanline < cinfo->output_height) + ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state == DSTATE_BUFIMAGE) { + /* Finishing after a buffered-image operation */ + cinfo->global_state = DSTATE_STOPPING; + } else if (cinfo->global_state != DSTATE_STOPPING) { + /* STOPPING = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read until EOI */ + while (! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + /* Do final cleanup */ + (*cinfo->src->term_source) (cinfo); + /* We can use jpeg_abort to release memory and reset global_state */ + jpeg_abort((j_common_ptr) cinfo); + return TRUE; +} diff --git a/src/dep/src/irrlicht/jpeglib/jdapistd.c b/src/dep/src/irrlicht/jpeglib/jdapistd.c new file mode 100644 index 0000000..f6c7fff --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdapistd.c @@ -0,0 +1,275 @@ +/* + * jdapistd.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains application interface code for the decompression half + * of the JPEG library. These are the "standard" API routines that are + * used in the normal full-decompression case. They are not used by a + * transcoding-only application. Note that if an application links in + * jpeg_start_decompress, it will end up linking in the entire decompressor. + * We thus must separate this file from jdapimin.c to avoid linking the + * whole decompression library into a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); + + +/* + * Decompression initialization. + * jpeg_read_header must be completed before calling this. + * + * If a multipass operating mode was selected, this will do all but the + * last pass, and thus may take a great deal of time. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_start_decompress (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize master control, select active modules */ + jinit_master_decompress(cinfo); + if (cinfo->buffered_image) { + /* No more work here; expecting jpeg_start_output next */ + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; + } + cinfo->global_state = DSTATE_PRELOAD; + } + if (cinfo->global_state == DSTATE_PRELOAD) { + /* If file has multiple scans, absorb them all into the coef buffer */ + if (cinfo->inputctl->has_multiple_scans) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return FALSE; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* jdmaster underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + } + cinfo->output_scan_number = cinfo->input_scan_number; + } else if (cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Perform any dummy output passes, and set up for the final pass */ + return output_pass_setup(cinfo); +} + + +/* + * Set up for an output pass, and perform any dummy pass(es) needed. + * Common subroutine for jpeg_start_decompress and jpeg_start_output. + * Entry: global_state = DSTATE_PRESCAN only if previously suspended. + * Exit: If done, returns TRUE and sets global_state for proper output mode. + * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. + */ + +LOCAL(boolean) +output_pass_setup (j_decompress_ptr cinfo) +{ + if (cinfo->global_state != DSTATE_PRESCAN) { + /* First call: do pass setup */ + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; + cinfo->global_state = DSTATE_PRESCAN; + } + /* Loop over any required dummy passes */ + while (cinfo->master->is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Crank through the dummy pass */ + while (cinfo->output_scanline < cinfo->output_height) { + JDIMENSION last_scanline; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + /* Process some data */ + last_scanline = cinfo->output_scanline; + (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, + &cinfo->output_scanline, (JDIMENSION) 0); + if (cinfo->output_scanline == last_scanline) + return FALSE; /* No progress made, must suspend */ + } + /* Finish up dummy pass, and set up for another one */ + (*cinfo->master->finish_output_pass) (cinfo); + (*cinfo->master->prepare_for_output_pass) (cinfo); + cinfo->output_scanline = 0; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } + /* Ready for application to drive output pass through + * jpeg_read_scanlines or jpeg_read_raw_data. + */ + cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; + return TRUE; +} + + +/* + * Read some scanlines of data from the JPEG decompressor. + * + * The return value will be the number of lines actually read. + * This may be less than the number requested in several cases, + * including bottom of image, data source suspension, and operating + * modes that emit multiple scanlines at a time. + * + * Note: we warn about excess calls to jpeg_read_scanlines() since + * this likely signals an application programmer error. However, + * an oversize buffer (max_lines > scanlines remaining) is not an error. + */ + +GLOBAL(JDIMENSION) +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, + JDIMENSION max_lines) +{ + JDIMENSION row_ctr; + + if (cinfo->global_state != DSTATE_SCANNING) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Process some data */ + row_ctr = 0; + (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); + cinfo->output_scanline += row_ctr; + return row_ctr; +} + + +/* + * Alternate entry point to read raw data. + * Processes exactly one iMCU row per call, unless suspended. + */ + +GLOBAL(JDIMENSION) +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION max_lines) +{ + JDIMENSION lines_per_iMCU_row; + + if (cinfo->global_state != DSTATE_RAW_OK) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + if (cinfo->output_scanline >= cinfo->output_height) { + WARNMS(cinfo, JWRN_TOO_MUCH_DATA); + return 0; + } + + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) { + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + } + + /* Verify that at least one iMCU row can be returned. */ + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) + ERREXIT(cinfo, JERR_BUFFER_SIZE); + + /* Decompress directly into user's buffer. */ + if (! (*cinfo->coef->decompress_data) (cinfo, data)) + return 0; /* suspension forced, can do nothing more */ + + /* OK, we processed one iMCU row. */ + cinfo->output_scanline += lines_per_iMCU_row; + return lines_per_iMCU_row; +} + + +/* Additional entry points for buffered-image mode. */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Initialize for an output pass in buffered-image mode. + */ + +GLOBAL(boolean) +jpeg_start_output (j_decompress_ptr cinfo, int scan_number) +{ + if (cinfo->global_state != DSTATE_BUFIMAGE && + cinfo->global_state != DSTATE_PRESCAN) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + /* Limit scan number to valid range */ + if (scan_number <= 0) + scan_number = 1; + if (cinfo->inputctl->eoi_reached && + scan_number > cinfo->input_scan_number) + scan_number = cinfo->input_scan_number; + cinfo->output_scan_number = scan_number; + /* Perform any dummy output passes, and set up for the real pass */ + return output_pass_setup(cinfo); +} + + +/* + * Finish up after an output pass in buffered-image mode. + * + * Returns FALSE if suspended. The return value need be inspected only if + * a suspending data source is used. + */ + +GLOBAL(boolean) +jpeg_finish_output (j_decompress_ptr cinfo) +{ + if ((cinfo->global_state == DSTATE_SCANNING || + cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { + /* Terminate this pass. */ + /* We do not require the whole pass to have been completed. */ + (*cinfo->master->finish_output_pass) (cinfo); + cinfo->global_state = DSTATE_BUFPOST; + } else if (cinfo->global_state != DSTATE_BUFPOST) { + /* BUFPOST = repeat call after a suspension, anything else is error */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + } + /* Read markers looking for SOS or EOI */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) + return FALSE; /* Suspend, come back later */ + } + cinfo->global_state = DSTATE_BUFIMAGE; + return TRUE; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jdatadst.c b/src/dep/src/irrlicht/jpeglib/jdatadst.c new file mode 100644 index 0000000..2ece4e9 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdatadst.c @@ -0,0 +1,151 @@ +/* + * jdatadst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains compression data destination routines for the case of + * emitting JPEG data to a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * destination manager. + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of + * JOCTETs into 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data destination object for stdio output */ + +typedef struct { + struct jpeg_destination_mgr pub; /* public fields */ + + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ +} my_destination_mgr; + +typedef my_destination_mgr * my_dest_ptr; + +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ + + +/* + * Initialize destination --- called by jpeg_start_compress + * before any data is actually written. + */ + +METHODDEF(void) +init_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +/* + * Empty the output buffer --- called whenever buffer fills up. + * + * In typical applications, this should write the entire output buffer + * (ignoring the current state of next_output_byte & free_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been dumped. + * + * In applications that need to be able to suspend compression due to output + * overrun, a FALSE return indicates that the buffer cannot be emptied now. + * In this situation, the compressor will return to its caller (possibly with + * an indication that it has not accepted all the supplied scanlines). The + * application should resume compression after it has made more room in the + * output buffer. Note that there are substantial restrictions on the use of + * suspension --- see the documentation. + * + * When suspending, the compressor will back up to a convenient restart point + * (typically the start of the current MCU). next_output_byte & free_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point will be regenerated after resumption, so do not + * write it out when emptying the buffer externally. + */ + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != + (size_t) OUTPUT_BUF_SIZE) + ERREXIT(cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +/* + * Terminate destination --- called by jpeg_finish_compress + * after all data has been written. Usually needs to flush buffer. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_destination (j_compress_ptr cinfo) +{ + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + fflush(dest->outfile); + /* Make sure we wrote the output file OK */ + if (ferror(dest->outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Prepare for output to a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing compression. + */ + +GLOBAL(void) +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) +{ + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)); + } + + dest = (my_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; +} diff --git a/src/dep/src/irrlicht/jpeglib/jdatasrc.c b/src/dep/src/irrlicht/jpeglib/jdatasrc.c new file mode 100644 index 0000000..29b6983 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdatasrc.c @@ -0,0 +1,212 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jdcoefct.c b/src/dep/src/irrlicht/jpeglib/jdcoefct.c new file mode 100644 index 0000000..992bd10 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdcoefct.c @@ -0,0 +1,736 @@ +/* + * jdcoefct.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the coefficient buffer controller for decompression. + * This controller is the top level of the JPEG decompressor proper. + * The coefficient buffer lies between entropy decoding and inverse-DCT steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + * Also, the input side (only) is used when reading a file for transcoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +/* Block smoothing is only applicable for progressive JPEG, so: */ +#ifndef D_PROGRESSIVE_SUPPORTED +#undef BLOCK_SMOOTHING_SUPPORTED +#endif + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_coef_controller pub; /* public fields */ + + /* These variables keep track of the current location of the input side. */ + /* cinfo->input_iMCU_row is also used for this. */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* The output side's location is represented by cinfo->output_iMCU_row. */ + + /* In single-pass modes, it's sufficient to buffer just one MCU. + * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * and let the entropy decoder write into that workspace each time. + * (On 80x86, the workspace is FAR even though it's not really very big; + * this is to keep the module interfaces unchanged when a large coefficient + * buffer is necessary.) + * In multi-pass modes, this array points to the current MCU's blocks + * within the virtual arrays; it is used only by the input side. + */ + JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* In multi-pass modes, we need a virtual block array for each component. */ + jvirt_barray_ptr whole_image[MAX_COMPONENTS]; +#endif + +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* When doing block smoothing, we latch coefficient Al values here */ + int * coef_bits_latch; +#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ +#endif +} my_coef_controller; + +typedef my_coef_controller * my_coef_ptr; + +/* Forward declarations */ +METHODDEF(int) decompress_onepass + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +METHODDEF(int) decompress_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif +#ifdef BLOCK_SMOOTHING_SUPPORTED +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo)); +METHODDEF(int) decompress_smooth_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + coef->MCU_rows_per_iMCU_row = 1; + } else { + if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + coef->MCU_ctr = 0; + coef->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + cinfo->input_iMCU_row = 0; + start_iMCU_row(cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ +#ifdef BLOCK_SMOOTHING_SUPPORTED + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + + /* If multipass, check to see whether to use block smoothing on this pass */ + if (coef->pub.coef_arrays != NULL) { + if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) + coef->pub.decompress_data = decompress_smooth_data; + else + coef->pub.decompress_data = decompress_data; + } +#endif + cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the single-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Input and output must run in lockstep since we have only a one-MCU buffer. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(int) +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int blkn, ci, xindex, yindex, yoffset, useful_width; + JSAMPARRAY output_ptr; + JDIMENSION start_col, output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Loop to process as much as one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; + MCU_col_num++) { + /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ + jzero_far((void FAR *) coef->MCU_buffer[0], + (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + /* Determine where data should go in output_buf and do the IDCT thing. + * We skip dummy blocks at the right and bottom edges (but blkn gets + * incremented past them!). Note the inner loop relies on having + * allocated the MCU_buffer[] blocks sequentially. + */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) { + blkn += compptr->MCU_blocks; + continue; + } + inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; + useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width + : compptr->last_col_width; + output_ptr = output_buf[compptr->component_index] + + yoffset * compptr->DCT_scaled_size; + start_col = MCU_col_num * compptr->MCU_sample_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + if (cinfo->input_iMCU_row < last_iMCU_row || + yoffset+yindex < compptr->last_row_height) { + output_col = start_col; + for (xindex = 0; xindex < useful_width; xindex++) { + (*inverse_DCT) (cinfo, compptr, + (JCOEFPTR) coef->MCU_buffer[blkn+xindex], + output_ptr, output_col); + output_col += compptr->DCT_scaled_size; + } + } + blkn += compptr->MCU_width; + output_ptr += compptr->DCT_scaled_size; + } + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + cinfo->output_iMCU_row++; + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF(int) +dummy_consume_data (j_decompress_ptr cinfo) +{ + return JPEG_SUSPENDED; /* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image coefficient buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor block rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF(int) +consume_data (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + int blkn, ci, xindex, yindex, yoffset; + JDIMENSION start_col; + JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; + JBLOCKROW buffer_ptr; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + buffer[ci] = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], + cinfo->input_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + /* Note: entropy decoder expects buffer to be zeroed, + * but this is handled automatically by the memory manager + * because we requested a pre-zeroed array. + */ + } + + /* Loop to process one whole iMCU row */ + for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; + yoffset++) { + for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; + MCU_col_num++) { + /* Construct list of pointers to DCT blocks belonging to this MCU */ + blkn = 0; /* index of current DCT block within MCU */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + start_col = MCU_col_num * compptr->MCU_width; + for (yindex = 0; yindex < compptr->MCU_height; yindex++) { + buffer_ptr = buffer[ci][yindex+yoffset] + start_col; + for (xindex = 0; xindex < compptr->MCU_width; xindex++) { + coef->MCU_buffer[blkn++] = buffer_ptr++; + } + } + } + /* Try to fetch the MCU. */ + if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + /* Suspension forced; update state counters and exit */ + coef->MCU_vert_offset = yoffset; + coef->MCU_ctr = MCU_col_num; + return JPEG_SUSPENDED; + } + } + /* Completed an MCU row, but perhaps not an iMCU row */ + coef->MCU_ctr = 0; + } + /* Completed the iMCU row, advance counters for next one */ + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Decompress and return some data in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF(int) +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num; + int ci, block_row, block_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number < cinfo->output_scan_number || + (cinfo->input_scan_number == cinfo->output_scan_number && + cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + cinfo->output_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) + block_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + } + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + output_col = 0; + for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { + (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, + output_ptr, output_col); + buffer_ptr++; + output_col += compptr->DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +#ifdef BLOCK_SMOOTHING_SUPPORTED + +/* + * This code applies interblock smoothing as described by section K.8 + * of the JPEG standard: the first 5 AC coefficients are estimated from + * the DC values of a DCT block and its 8 neighboring blocks. + * We apply smoothing only for progressive JPEG decoding, and only if + * the coefficients it can estimate are not yet known to full precision. + */ + +/* Natural-order array positions of the first 5 zigzag-order coefficients */ +#define Q01_POS 1 +#define Q10_POS 8 +#define Q20_POS 16 +#define Q11_POS 9 +#define Q02_POS 2 + +/* + * Determine whether block smoothing is applicable and safe. + * We also latch the current states of the coef_bits[] entries for the + * AC coefficients; otherwise, if the input side of the decompressor + * advances into a new scan, we might think the coefficients are known + * more accurately than they really are. + */ + +LOCAL(boolean) +smoothing_ok (j_decompress_ptr cinfo) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + boolean smoothing_useful = FALSE; + int ci, coefi; + jpeg_component_info *compptr; + JQUANT_TBL * qtable; + int * coef_bits; + int * coef_bits_latch; + + if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) + return FALSE; + + /* Allocate latch area if not already done */ + if (coef->coef_bits_latch == NULL) + coef->coef_bits_latch = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * + (SAVED_COEFS * SIZEOF(int))); + coef_bits_latch = coef->coef_bits_latch; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* All components' quantization values must already be latched. */ + if ((qtable = compptr->quant_table) == NULL) + return FALSE; + /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ + if (qtable->quantval[0] == 0 || + qtable->quantval[Q01_POS] == 0 || + qtable->quantval[Q10_POS] == 0 || + qtable->quantval[Q20_POS] == 0 || + qtable->quantval[Q11_POS] == 0 || + qtable->quantval[Q02_POS] == 0) + return FALSE; + /* DC values must be at least partly known for all components. */ + coef_bits = cinfo->coef_bits[ci]; + if (coef_bits[0] < 0) + return FALSE; + /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ + for (coefi = 1; coefi <= 5; coefi++) { + coef_bits_latch[coefi] = coef_bits[coefi]; + if (coef_bits[coefi] != 0) + smoothing_useful = TRUE; + } + coef_bits_latch += SAVED_COEFS; + } + + return smoothing_useful; +} + + +/* + * Variant of decompress_data for use when doing block smoothing. + */ + +METHODDEF(int) +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION block_num, last_block_column; + int ci, block_row, block_rows, access_rows; + JBLOCKARRAY buffer; + JBLOCKROW buffer_ptr, prev_block_row, next_block_row; + JSAMPARRAY output_ptr; + JDIMENSION output_col; + jpeg_component_info *compptr; + inverse_DCT_method_ptr inverse_DCT; + boolean first_row, last_row; + JBLOCK workspace; + int *coef_bits; + JQUANT_TBL *quanttbl; + INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; + int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; + int Al, pred; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number <= cinfo->output_scan_number && + ! cinfo->inputctl->eoi_reached) { + if (cinfo->input_scan_number == cinfo->output_scan_number) { + /* If input is working on current scan, we ordinarily want it to + * have completed the current row. But if input scan is DC, + * we want it to keep one row ahead so that next block row's DC + * values are up to date. + */ + JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; + if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) + break; + } + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Don't bother to IDCT an uninteresting component. */ + if (! compptr->component_needed) + continue; + /* Count non-dummy DCT block rows in this iMCU row. */ + if (cinfo->output_iMCU_row < last_iMCU_row) { + block_rows = compptr->v_samp_factor; + access_rows = block_rows * 2; /* this and next iMCU row */ + last_row = FALSE; + } else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (block_rows == 0) block_rows = compptr->v_samp_factor; + access_rows = block_rows; /* this iMCU row only */ + last_row = TRUE; + } + /* Align the virtual buffer for this component. */ + if (cinfo->output_iMCU_row > 0) { + access_rows += compptr->v_samp_factor; /* prior iMCU row too */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, + (JDIMENSION) access_rows, FALSE); + buffer += compptr->v_samp_factor; /* point to current iMCU row */ + first_row = FALSE; + } else { + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr) cinfo, coef->whole_image[ci], + (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); + first_row = TRUE; + } + /* Fetch component-dependent info */ + coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + quanttbl = compptr->quant_table; + Q00 = quanttbl->quantval[0]; + Q01 = quanttbl->quantval[Q01_POS]; + Q10 = quanttbl->quantval[Q10_POS]; + Q20 = quanttbl->quantval[Q20_POS]; + Q11 = quanttbl->quantval[Q11_POS]; + Q02 = quanttbl->quantval[Q02_POS]; + inverse_DCT = cinfo->idct->inverse_DCT[ci]; + output_ptr = output_buf[ci]; + /* Loop over all DCT blocks to be processed. */ + for (block_row = 0; block_row < block_rows; block_row++) { + buffer_ptr = buffer[block_row]; + if (first_row && block_row == 0) + prev_block_row = buffer_ptr; + else + prev_block_row = buffer[block_row-1]; + if (last_row && block_row == block_rows-1) + next_block_row = buffer_ptr; + else + next_block_row = buffer[block_row+1]; + /* We fetch the surrounding DC values using a sliding-register approach. + * Initialize all nine here so as to do the right thing on narrow pics. + */ + DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; + DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; + DC7 = DC8 = DC9 = (int) next_block_row[0][0]; + output_col = 0; + last_block_column = compptr->width_in_blocks - 1; + for (block_num = 0; block_num <= last_block_column; block_num++) { + /* Fetch current DCT block into workspace so we can modify it. */ + jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); + /* Update DC values */ + if (block_num < last_block_column) { + DC3 = (int) prev_block_row[1][0]; + DC6 = (int) buffer_ptr[1][0]; + DC9 = (int) next_block_row[1][0]; + } + /* Compute coefficient estimates per K.8. + * An estimate is applied only if coefficient is still zero, + * and is not known to be fully accurate. + */ + /* AC01 */ + if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { + num = 36 * Q00 * (DC4 - DC6); + if (num >= 0) { + pred = (int) (((Q01<<7) + num) / (Q01<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q10<<7) + num) / (Q10<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q20<<7) + num) / (Q20<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q11<<7) + num) / (Q11<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { + pred = (int) (((Q02<<7) + num) / (Q02<<8)); + if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_scaled_size; + } + output_ptr += compptr->DCT_scaled_size; + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* BLOCK_SMOOTHING_SUPPORTED */ + + +/* + * Initialize coefficient buffer controller. + */ + +GLOBAL(void) +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_coef_ptr coef; + + coef = (my_coef_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_coef_controller)); + cinfo->coef = (struct jpeg_d_coef_controller *) coef; + coef->pub.start_input_pass = start_input_pass; + coef->pub.start_output_pass = start_output_pass; +#ifdef BLOCK_SMOOTHING_SUPPORTED + coef->coef_bits_latch = NULL; +#endif + + /* Create the coefficient buffer. */ + if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor DCT blocks in each direction. */ + /* Note we ask for a pre-zeroed array. */ + int ci, access_rows; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + access_rows = compptr->v_samp_factor; +#ifdef BLOCK_SMOOTHING_SUPPORTED + /* If block smoothing could be used, need a bigger window */ + if (cinfo->progressive_mode) + access_rows *= 3; +#endif + coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) access_rows); + } + coef->pub.consume_data = consume_data; + coef->pub.decompress_data = decompress_data; + coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + /* We only need a single-MCU buffer. */ + JBLOCKROW buffer; + int i; + + buffer = (JBLOCKROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { + coef->MCU_buffer[i] = buffer + i; + } + coef->pub.consume_data = dummy_consume_data; + coef->pub.decompress_data = decompress_onepass; + coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdcolor.c b/src/dep/src/irrlicht/jpeglib/jdcolor.c new file mode 100644 index 0000000..fd7b138 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdcolor.c @@ -0,0 +1,396 @@ +/* + * jdcolor.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains output colorspace conversion routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private subobject */ + +typedef struct { + struct jpeg_color_deconverter pub; /* public fields */ + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ +} my_color_deconverter; + +typedef my_color_deconverter * my_cconvert_ptr; + + +/**************** YCbCr -> RGB conversion: most common case **************/ + +/* + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less CENTERJSAMPLE. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + int i; + INT32 x; + SHIFT_TEMPS + + cconvert->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + cconvert->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + cconvert->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + cconvert->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Convert some rows of samples to the output colorspace. + * + * Note that we change from noninterleaved, one-plane-per-component format + * to interleaved-pixel format. The output buffer is therefore three times + * as wide as the input buffer. + * A starting row offset is provided only for the input buffer. The caller + * can easily adjust the passed output_buf value to accommodate any row + * offset required on that side. + */ + +METHODDEF(void) +ycc_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/**************** Cases other than YCbCr -> RGB **************/ + + +/* + * Color conversion for no colorspace change: just copy the data, + * converting from separate-planes to interleaved representation. + */ + +METHODDEF(void) +null_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION count; + register int num_components = cinfo->num_components; + JDIMENSION num_cols = cinfo->output_width; + int ci; + + while (--num_rows >= 0) { + for (ci = 0; ci < num_components; ci++) { + inptr = input_buf[ci][input_row]; + outptr = output_buf[0] + ci; + for (count = num_cols; count > 0; count--) { + *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ + outptr += num_components; + } + } + input_row++; + output_buf++; + } +} + + +/* + * Color conversion for grayscale: just copy the data. + * This also works for YCbCr -> grayscale conversion, in which + * we just copy the Y (luminance) component and ignore chrominance. + */ + +METHODDEF(void) +grayscale_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, + num_rows, cinfo->output_width); +} + + +/* + * Convert grayscale to RGB: just duplicate the graylevel three times. + * This is provided to support applications that don't want to cope + * with grayscale as a separate case. + */ + +METHODDEF(void) +gray_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr, outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr = input_buf[0][input_row++]; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; + outptr += RGB_PIXELSIZE; + } + } +} + + +/* + * Adobe-style YCCK->CMYK conversion. + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + * conversion as above, while passing K (black) unchanged. + * We assume build_ycc_rgb_table has been called. + */ + +METHODDEF(void) +ycck_cmyk_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; + register int y, cb, cr; + register JSAMPROW outptr; + register JSAMPROW inptr0, inptr1, inptr2, inptr3; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + register int * Crrtab = cconvert->Cr_r_tab; + register int * Cbbtab = cconvert->Cb_b_tab; + register INT32 * Crgtab = cconvert->Cr_g_tab; + register INT32 * Cbgtab = cconvert->Cb_g_tab; + SHIFT_TEMPS + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + inptr3 = input_buf[3][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + y = GETJSAMPLE(inptr0[col]); + cb = GETJSAMPLE(inptr1[col]); + cr = GETJSAMPLE(inptr2[col]); + /* Range-limiting is essential due to noise introduced by DCT losses. */ + outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ + outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS)))]; + outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ + /* K passes through unchanged */ + outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr += 4; + } + } +} + + +/* + * Empty method for start_pass. + */ + +METHODDEF(void) +start_pass_dcolor (j_decompress_ptr cinfo) +{ + /* no work needed */ +} + + +/* + * Module initialization routine for output colorspace conversion. + */ + +GLOBAL(void) +jinit_color_deconverter (j_decompress_ptr cinfo) +{ + my_cconvert_ptr cconvert; + int ci; + + cconvert = (my_cconvert_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_color_deconverter)); + cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; + cconvert->pub.start_pass = start_pass_dcolor; + + /* Make sure num_components agrees with jpeg_color_space */ + switch (cinfo->jpeg_color_space) { + case JCS_GRAYSCALE: + if (cinfo->num_components != 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_RGB: + case JCS_YCbCr: + if (cinfo->num_components != 3) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + case JCS_CMYK: + case JCS_YCCK: + if (cinfo->num_components != 4) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + + default: /* JCS_UNKNOWN can be anything */ + if (cinfo->num_components < 1) + ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); + break; + } + + /* Set out_color_components and conversion method based on requested space. + * Also clear the component_needed flags for any unused components, + * so that earlier pipeline stages can avoid useless computation. + */ + + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + if (cinfo->jpeg_color_space == JCS_GRAYSCALE || + cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = grayscale_convert; + /* For color->grayscale conversion, only the Y (0) component is needed */ + for (ci = 1; ci < cinfo->num_components; ci++) + cinfo->comp_info[ci].component_needed = FALSE; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_RGB: + cinfo->out_color_components = RGB_PIXELSIZE; + if (cinfo->jpeg_color_space == JCS_YCbCr) { + cconvert->pub.color_convert = ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { + cconvert->pub.color_convert = gray_rgb_convert; + } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + case JCS_CMYK: + cinfo->out_color_components = 4; + if (cinfo->jpeg_color_space == JCS_YCCK) { + cconvert->pub.color_convert = ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + } else if (cinfo->jpeg_color_space == JCS_CMYK) { + cconvert->pub.color_convert = null_convert; + } else + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + + default: + /* Permit null conversion to same output space */ + if (cinfo->out_color_space == cinfo->jpeg_color_space) { + cinfo->out_color_components = cinfo->num_components; + cconvert->pub.color_convert = null_convert; + } else /* unsupported non-null conversion */ + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); + break; + } + + if (cinfo->quantize_colors) + cinfo->output_components = 1; /* single colormapped output component */ + else + cinfo->output_components = cinfo->out_color_components; +} diff --git a/src/dep/src/irrlicht/jpeglib/jdct.h b/src/dep/src/irrlicht/jpeglib/jdct.h new file mode 100644 index 0000000..b664cab --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdct.h @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer. Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM; /* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM; /* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array. The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table. The output data is to be placed into the + * sample array starting at a specified column. (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required. We use a mask-and-table-lookup method + * to do the combined operations quickly. See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Extern declarations for the forward and inverse DCT routines. */ + +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); + +EXTERN(void) jpeg_idct_islow + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_ifast + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_float + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_4x4 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_2x2 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_1x1 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE ((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply. This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16 /* default definition */ +#define MULTIPLY16C16(var,const) ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16 /* default definition */ +#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) +#endif diff --git a/src/dep/src/irrlicht/jpeglib/jddctmgr.c b/src/dep/src/irrlicht/jpeglib/jddctmgr.c new file mode 100644 index 0000000..0e44eb1 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jddctmgr.c @@ -0,0 +1,269 @@ +/* + * jddctmgr.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the inverse-DCT management logic. + * This code selects a particular IDCT implementation to be used, + * and it performs related housekeeping chores. No code in this file + * is executed per IDCT step, only during output pass setup. + * + * Note that the IDCT routines are responsible for performing coefficient + * dequantization as well as the IDCT proper. This module sets up the + * dequantization multiplier table needed by the IDCT routine. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + + +/* + * The decompressor input side (jdinput.c) saves away the appropriate + * quantization table for each component at the start of the first scan + * involving that component. (This is necessary in order to correctly + * decode files that reuse Q-table slots.) + * When we are ready to make an output pass, the saved Q-table is converted + * to a multiplier table that will actually be used by the IDCT routine. + * The multiplier table contents are IDCT-method-dependent. To support + * application changes in IDCT method between scans, we can remake the + * multiplier tables if necessary. + * In buffered-image mode, the first output pass may occur before any data + * has been seen for some components, and thus before their Q-tables have + * been saved away. To handle this case, multiplier tables are preset + * to zeroes; the result of the IDCT will be a neutral gray level. + */ + + +/* Private subobject for this module */ + +typedef struct { + struct jpeg_inverse_dct pub; /* public fields */ + + /* This array contains the IDCT method code that each multiplier table + * is currently set up for, or -1 if it's not yet set up. + * The actual multiplier tables are pointed to by dct_table in the + * per-component comp_info structures. + */ + int cur_method[MAX_COMPONENTS]; +} my_idct_controller; + +typedef my_idct_controller * my_idct_ptr; + + +/* Allocated multiplier tables: big enough for any supported variant */ + +typedef union { + ISLOW_MULT_TYPE islow_array[DCTSIZE2]; +#ifdef DCT_IFAST_SUPPORTED + IFAST_MULT_TYPE ifast_array[DCTSIZE2]; +#endif +#ifdef DCT_FLOAT_SUPPORTED + FLOAT_MULT_TYPE float_array[DCTSIZE2]; +#endif +} multiplier_table; + + +/* The current scaled-IDCT routines require ISLOW-style multiplier tables, + * so be sure to compile that code if either ISLOW or SCALING is requested. + */ +#ifdef DCT_ISLOW_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#else +#ifdef IDCT_SCALING_SUPPORTED +#define PROVIDE_ISLOW_TABLES +#endif +#endif + + +/* + * Prepare for an output pass. + * Here we select the proper IDCT routine for each component and build + * a matching multiplier table. + */ + +METHODDEF(void) +start_pass (j_decompress_ptr cinfo) +{ + my_idct_ptr idct = (my_idct_ptr) cinfo->idct; + int ci, i; + jpeg_component_info *compptr; + int method = 0; + inverse_DCT_method_ptr method_ptr = NULL; + JQUANT_TBL * qtbl; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Select the proper IDCT routine for this component's scaling */ + switch (compptr->DCT_scaled_size) { +#ifdef IDCT_SCALING_SUPPORTED + case 1: + method_ptr = jpeg_idct_1x1; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 2: + method_ptr = jpeg_idct_2x2; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; + case 4: + method_ptr = jpeg_idct_4x4; + method = JDCT_ISLOW; /* jidctred uses islow-style table */ + break; +#endif + case DCTSIZE: + switch (cinfo->dct_method) { +#ifdef DCT_ISLOW_SUPPORTED + case JDCT_ISLOW: + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + method_ptr = jpeg_idct_float; + method = JDCT_FLOAT; + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + break; + default: + ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); + break; + } + idct->pub.inverse_DCT[ci] = method_ptr; + /* Create multiplier table from quant table. + * However, we can skip this if the component is uninteresting + * or if we already built the table. Also, if no quant table + * has yet been saved for the component, we leave the + * multiplier table all-zero; we'll be reading zeroes from the + * coefficient controller's buffer anyway. + */ + if (! compptr->component_needed || idct->cur_method[ci] == method) + continue; + qtbl = compptr->quant_table; + if (qtbl == NULL) /* happens if no data yet for component */ + continue; + idct->cur_method[ci] = method; + switch (method) { +#ifdef PROVIDE_ISLOW_TABLES + case JDCT_ISLOW: + { + /* For LL&M IDCT method, multipliers are equal to raw quantization + * coefficients, but are stored as ints to ensure access efficiency. + */ + ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; + for (i = 0; i < DCTSIZE2; i++) { + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; + } + } + break; +#endif +#ifdef DCT_IFAST_SUPPORTED + case JDCT_IFAST: + { + /* For AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * For integer operation, the multiplier table is to be scaled by + * IFAST_SCALE_BITS. + */ + IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; +#define CONST_BITS 14 + static const INT16 aanscales[DCTSIZE2] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 + }; + SHIFT_TEMPS + + for (i = 0; i < DCTSIZE2; i++) { + ifmtbl[i] = (IFAST_MULT_TYPE) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS); + } + } + break; +#endif +#ifdef DCT_FLOAT_SUPPORTED + case JDCT_FLOAT: + { + /* For float AA&N IDCT method, multipliers are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + */ + FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fmtbl[i] = (FLOAT_MULT_TYPE) + ((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col]); + i++; + } + } + } + break; +#endif + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } + } +} + + +/* + * Initialize IDCT manager. + */ + +GLOBAL(void) +jinit_inverse_dct (j_decompress_ptr cinfo) +{ + my_idct_ptr idct; + int ci; + jpeg_component_info *compptr; + + idct = (my_idct_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_idct_controller)); + cinfo->idct = (struct jpeg_inverse_dct *) idct; + idct->pub.start_pass = start_pass; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Allocate and pre-zero a multiplier table for each component */ + compptr->dct_table = + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); + /* Mark multiplier table not yet set up for any method */ + idct->cur_method[ci] = -1; + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdhuff.c b/src/dep/src/irrlicht/jpeglib/jdhuff.c new file mode 100644 index 0000000..b2ad66d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdhuff.c @@ -0,0 +1,651 @@ +/* + * jdhuff.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdphuff.c */ + + +/* + * Expanded entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcu: */ + + /* Pointers to derived tables to be used for each block within an MCU */ + d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; + /* Whether we care about the DC and AC coefficient values for each block */ + boolean dc_needed[D_MAX_BLOCKS_IN_MCU]; + boolean ac_needed[D_MAX_BLOCKS_IN_MCU]; +} huff_entropy_decoder; + +typedef huff_entropy_decoder * huff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci, blkn, dctbl, actbl; + jpeg_component_info * compptr; + + /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + * This ought to be an error condition, but we make it a warning because + * there are some baseline files out there with all zeroes in these bytes. + */ + if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || + cinfo->Ah != 0 || cinfo->Al != 0) + WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Precalculate decoding info for each block in an MCU of this scan */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + /* Precalculate which table to use for each block */ + entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Decide whether we really care about the coefficient values */ + if (compptr->component_needed) { + entropy->dc_needed[blkn] = TRUE; + /* we don't need the ACs if producing a 1/8th-size image */ + entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1); + } else { + entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; + } + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Compute the derived values for a Huffman table. + * This routine also performs some validation checks on the table. + * + * Note this is also used by jdphuff.c. + */ + +GLOBAL(void) +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl) +{ + JHUFF_TBL *htbl; + d_derived_tbl *dtbl; + int p, i, l, si, numsymbols; + int lookbits, ctr; + char huffsize[257]; + unsigned int huffcode[257]; + unsigned int code; + + /* Note that huffsize[] and huffcode[] are filled in code-length order, + * paralleling the order of the symbols themselves in htbl->huffval[]. + */ + + /* Find the input Huffman table */ + if (tblno < 0 || tblno >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + htbl = + isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; + if (htbl == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); + + /* Allocate a workspace if we haven't already done so. */ + if (*pdtbl == NULL) + *pdtbl = (d_derived_tbl *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(d_derived_tbl)); + dtbl = *pdtbl; + dtbl->pub = htbl; /* fill in back link */ + + /* Figure C.1: make table of Huffman code length for each symbol */ + + p = 0; + for (l = 1; l <= 16; l++) { + i = (int) htbl->bits[l]; + if (i < 0 || p + i > 256) /* protect against table overrun */ + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + while (i--) + huffsize[p++] = (char) l; + } + huffsize[p] = 0; + numsymbols = p; + + /* Figure C.2: generate the codes themselves */ + /* We also validate that the counts represent a legal Huffman code tree. */ + + code = 0; + si = huffsize[0]; + p = 0; + while (huffsize[p]) { + while (((int) huffsize[p]) == si) { + huffcode[p++] = code; + code++; + } + /* code is now 1 more than the last code used for codelength si; but + * it must still fit in si bits, since no code is allowed to be all ones. + */ + if (((INT32) code) >= (((INT32) 1) << si)) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + code <<= 1; + si++; + } + + /* Figure F.15: generate decoding tables for bit-sequential decoding */ + + p = 0; + for (l = 1; l <= 16; l++) { + if (htbl->bits[l]) { + /* valoffset[l] = huffval[] index of 1st symbol of code length l, + * minus the minimum code of length l + */ + dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p]; + p += htbl->bits[l]; + dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ + } else { + dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ + } + } + dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ + + /* Compute lookahead tables to speed up decoding. + * First we set all the table entries to 0, indicating "too long"; + * then we iterate through the Huffman codes that are short enough and + * fill in all the entries that correspond to bit sequences starting + * with that code. + */ + + MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); + + p = 0; + for (l = 1; l <= HUFF_LOOKAHEAD; l++) { + for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { + /* l = current code's length, p = its index in huffcode[] & huffval[]. */ + /* Generate left-justified code followed by all possible bit sequences */ + lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); + for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { + dtbl->look_nbits[lookbits] = l; + dtbl->look_sym[lookbits] = htbl->huffval[p]; + lookbits++; + } + } + } + + /* Validate symbols as being reasonable. + * For AC tables, we make no check, but accept all byte values 0..255. + * For DC tables, we require the symbols to be in range 0..15. + * (Tighter bounds could be applied depending on the data depth and mode, + * but this is sufficient to ensure safe decoding.) + */ + if (isDC) { + for (i = 0; i < numsymbols; i++) { + int sym = htbl->huffval[i]; + if (sym < 0 || sym > 15) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + } + } +} + + +/* + * Out-of-line code for bit fetching (shared with jdphuff.c). + * See jdhuff.h for info about usage. + * Note: current values of get_buffer and bits_left are passed as parameters, + * but are returned in the corresponding fields of the state struct. + * + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + * of get_buffer to be used. (On machines with wider words, an even larger + * buffer could be used.) However, on some machines 32-bit shifts are + * quite slow and take time proportional to the number of places shifted. + * (This is true with most PC compilers, for instance.) In this case it may + * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. + */ + +#ifdef SLOW_SHIFT_32 +#define MIN_GET_BITS 15 /* minimum allowable value */ +#else +#define MIN_GET_BITS (BIT_BUF_SIZE-7) +#endif + + +GLOBAL(boolean) +jpeg_fill_bit_buffer (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + int nbits) +/* Load up the bit buffer to a depth of at least nbits */ +{ + /* Copy heavily used state fields into locals (hopefully registers) */ + register const JOCTET * next_input_byte = state->next_input_byte; + register size_t bytes_in_buffer = state->bytes_in_buffer; + j_decompress_ptr cinfo = state->cinfo; + + /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ + /* (It is assumed that no request will be for more than that many bits.) */ + /* We fail to do so only if we hit a marker or are forced to suspend. */ + + if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ + while (bits_left < MIN_GET_BITS) { + register int c; + + /* Attempt to read a byte */ + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + + /* If it's 0xFF, check and discard stuffed zero byte */ + if (c == 0xFF) { + /* Loop here to discard any padding FF's on terminating marker, + * so that we can save a valid unread_marker value. NOTE: we will + * accept multiple FF's followed by a 0 as meaning a single FF data + * byte. This data pattern is not valid according to the standard. + */ + do { + if (bytes_in_buffer == 0) { + if (! (*cinfo->src->fill_input_buffer) (cinfo)) + return FALSE; + next_input_byte = cinfo->src->next_input_byte; + bytes_in_buffer = cinfo->src->bytes_in_buffer; + } + bytes_in_buffer--; + c = GETJOCTET(*next_input_byte++); + } while (c == 0xFF); + + if (c == 0) { + /* Found FF/00, which represents an FF data byte */ + c = 0xFF; + } else { + /* Oops, it's actually a marker indicating end of compressed data. + * Save the marker code for later use. + * Fine point: it might appear that we should save the marker into + * bitread working state, not straight into permanent state. But + * once we have hit a marker, we cannot need to suspend within the + * current MCU, because we will read no more bytes from the data + * source. So it is OK to update permanent state right away. + */ + cinfo->unread_marker = c; + /* See if we need to insert some fake zero bits. */ + goto no_more_bytes; + } + } + + /* OK, load c into get_buffer */ + get_buffer = (get_buffer << 8) | c; + bits_left += 8; + } /* end while */ + } else { + no_more_bytes: + /* We get here if we've read the marker that terminates the compressed + * data segment. There should be enough bits in the buffer register + * to satisfy the request; if so, no problem. + */ + if (nbits > bits_left) { + /* Uh-oh. Report corrupted data to user and stuff zeroes into + * the data stream, so that we can produce some kind of image. + * We use a nonvolatile flag to ensure that only one warning message + * appears per data segment. + */ + if (! cinfo->entropy->insufficient_data) { + WARNMS(cinfo, JWRN_HIT_MARKER); + cinfo->entropy->insufficient_data = TRUE; + } + /* Fill the buffer with zero bits */ + get_buffer <<= MIN_GET_BITS - bits_left; + bits_left = MIN_GET_BITS; + } + } + + /* Unload the local registers */ + state->next_input_byte = next_input_byte; + state->bytes_in_buffer = bytes_in_buffer; + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + return TRUE; +} + + +/* + * Out-of-line code for Huffman code decoding. + * See jdhuff.h for info about usage. + */ + +GLOBAL(int) +jpeg_huff_decode (bitread_working_state * state, + register bit_buf_type get_buffer, register int bits_left, + d_derived_tbl * htbl, int min_bits) +{ + register int l = min_bits; + register INT32 code; + + /* HUFF_DECODE has determined that the code is at least min_bits */ + /* bits long, so fetch that many bits in one swoop. */ + + CHECK_BIT_BUFFER(*state, l, return -1); + code = GET_BITS(l); + + /* Collect the rest of the Huffman code one bit at a time. */ + /* This is per Figure F.16 in the JPEG spec. */ + + while (code > htbl->maxcode[l]) { + code <<= 1; + CHECK_BIT_BUFFER(*state, 1, return -1); + code |= GET_BITS(1); + l++; + } + + /* Unload the local registers */ + state->get_buffer = get_buffer; + state->bits_left = bits_left; + + /* With garbage input we may reach the sentinel value l = 17. */ + + if (l > 16) { + WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); + return 0; /* fake a zero as the safest result */ + } + + return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +METHODDEF(boolean) +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + int blkn; + BITREAD_STATE_VARS; + savable_state state; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + JBLOCKROW block = MCU_data[blkn]; + d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; + d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; + register int s, k, r; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + if (entropy->dc_needed[blkn]) { + /* Convert DC difference to actual value, update last_dc_val */ + int ci = cinfo->MCU_membership[blkn]; + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + } + + if (entropy->ac_needed[blkn]) { + + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } + } + + } else { + + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } + } + + } + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_huff_decoder (j_decompress_ptr cinfo) +{ + huff_entropy_ptr entropy; + int i; + + entropy = (huff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_huff_decoder; + entropy->pub.decode_mcu = decode_mcu; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdhuff.h b/src/dep/src/irrlicht/jpeglib/jdhuff.h new file mode 100644 index 0000000..12c0747 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdhuff.h @@ -0,0 +1,201 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ + +typedef struct { + /* Basic tables: (element [0] of each array is unused) */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + /* valoffset[k] = huffval[] index of 1st symbol of code length k, less + * the smallest code of length k; so given a code of length k, the + * corresponding symbol is huffval[code + valoffset[k]] + */ + + /* Link to public Huffman table (needed only in jpeg_huff_decode) */ + JHUFF_TBL *pub; + + /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + * the input data stream. If the next Huffman code is no more + * than HUFF_LOOKAHEAD bits long, we can obtain its length and + * the corresponding symbol directly from these tables. + */ + int look_nbits[1< 32 bits on your machine, and shifting/masking longs is + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + * appropriately should be a win. Unfortunately we can't define the size + * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * because not all machines measure sizeof in 8-bit bytes. + */ + +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ +} bitread_perm_state; + +typedef struct { /* Bitreading working state within an MCU */ + /* Current data source location */ + /* We need a copy, rather than munging the original, in case of suspension */ + const JOCTET * next_input_byte; /* => next byte to read from source */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + /* Bit input buffer --- note these values are kept in register variables, + * not in this struct, inside the inner loops. + */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + /* Pointer needed by jpeg_fill_bit_buffer. */ + j_decompress_ptr cinfo; /* back link to decompress master record */ +} bitread_working_state; + +/* Macros to declare and load/save bitread local variables. */ +#define BITREAD_STATE_VARS \ + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state + +#define BITREAD_LOAD_STATE(cinfop,permstate) \ + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; + +#define BITREAD_SAVE_STATE(cinfop,permstate) \ + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. + * val = GET_BITS(n); + * Fetch next N bits. + * val = PEEK_BITS(n); + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ + (bits_left -= (nbits)) + +/* Load up the bit buffer to a depth of at least nbits */ +EXTERN(boolean) jpeg_fill_bit_buffer + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping. Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long. The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + * for a lookahead. In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + * more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + nb = 1; goto slowlabel; \ + } \ + } \ + look = PEEK_BITS(HUFF_LOOKAHEAD); \ + if ((nb = htbl->look_nbits[look]) != 0) { \ + DROP_BITS(nb); \ + result = htbl->look_sym[look]; \ + } else { \ + nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ + if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ + { failaction; } \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + } \ +} + +/* Out-of-line case for Huffman code fetching */ +EXTERN(int) jpeg_huff_decode + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); diff --git a/src/dep/src/irrlicht/jpeglib/jdinput.c b/src/dep/src/irrlicht/jpeglib/jdinput.c new file mode 100644 index 0000000..2d5c747 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdinput.c @@ -0,0 +1,381 @@ +/* + * jdinput.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains input control logic for the JPEG decompressor. + * These routines are concerned with controlling the decompressor's input + * processing (marker reading and coefficient decoding). The actual input + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_input_controller pub; /* public fields */ + + boolean inheaders; /* TRUE until first SOS is reached */ +} my_input_controller; + +typedef my_input_controller * my_inputctl_ptr; + + +/* Forward declarations */ +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo)); + + +/* + * Routines to calculate various quantities related to the size of the image. + */ + +LOCAL(void) +initial_setup (j_decompress_ptr cinfo) +/* Called once, when first SOS marker is reached */ +{ + int ci; + jpeg_component_info *compptr; + + /* Make sure image isn't bigger than I can handle */ + if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || + (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); + + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + + /* Check that number of components won't exceed internal array sizes */ + if (cinfo->num_components > MAX_COMPONENTS) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPONENTS); + + /* Compute maximum sampling factors; check factor validity */ + cinfo->max_h_samp_factor = 1; + cinfo->max_v_samp_factor = 1; + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || + compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) + ERREXIT(cinfo, JERR_BAD_SAMPLING); + cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, + compptr->h_samp_factor); + cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, + compptr->v_samp_factor); + } + + /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + * In the full decompressor, this will be overridden by jdmaster.c; + * but in the transcoder, jdmaster.c is not used, so we must do it here. + */ + cinfo->min_DCT_scaled_size = DCTSIZE; + + /* Compute dimensions of components */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->DCT_scaled_size = DCTSIZE; + /* Size in DCT blocks */ + compptr->width_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->height_in_blocks = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + /* downsampled_width and downsampled_height will also be overridden by + * jdmaster.c if we are doing full decompression. The transcoder library + * doesn't use these values, but the calling application might. + */ + /* Size in samples */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, + (long) cinfo->max_h_samp_factor); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, + (long) cinfo->max_v_samp_factor); + /* Mark component needed, until color conversion says otherwise */ + compptr->component_needed = TRUE; + /* Mark no quantization table yet saved for component */ + compptr->quant_table = NULL; + } + + /* Compute number of fully interleaved MCU rows. */ + cinfo->total_iMCU_rows = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + /* Decide whether file contains multiple scans */ + if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) + cinfo->inputctl->has_multiple_scans = TRUE; + else + cinfo->inputctl->has_multiple_scans = FALSE; +} + + +LOCAL(void) +per_scan_setup (j_decompress_ptr cinfo) +/* Do computations that are needed before processing a JPEG scan */ +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ +{ + int ci, mcublks, tmp; + jpeg_component_info *compptr; + + if (cinfo->comps_in_scan == 1) { + + /* Noninterleaved (single-component) scan */ + compptr = cinfo->cur_comp_info[0]; + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = compptr->width_in_blocks; + cinfo->MCU_rows_in_scan = compptr->height_in_blocks; + + /* For noninterleaved scan, always one block per MCU */ + compptr->MCU_width = 1; + compptr->MCU_height = 1; + compptr->MCU_blocks = 1; + compptr->MCU_sample_width = compptr->DCT_scaled_size; + compptr->last_col_width = 1; + /* For noninterleaved scans, it is convenient to define last_row_height + * as the number of block rows present in the last iMCU row. + */ + tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + if (tmp == 0) tmp = compptr->v_samp_factor; + compptr->last_row_height = tmp; + + /* Prepare array describing MCU composition */ + cinfo->blocks_in_MCU = 1; + cinfo->MCU_membership[0] = 0; + + } else { + + /* Interleaved (multi-component) scan */ + if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, + MAX_COMPS_IN_SCAN); + + /* Overall image size in MCUs */ + cinfo->MCUs_per_row = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, + (long) (cinfo->max_h_samp_factor*DCTSIZE)); + cinfo->MCU_rows_in_scan = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, + (long) (cinfo->max_v_samp_factor*DCTSIZE)); + + cinfo->blocks_in_MCU = 0; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Sampling factors give # of blocks of component in each MCU */ + compptr->MCU_width = compptr->h_samp_factor; + compptr->MCU_height = compptr->v_samp_factor; + compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; + /* Figure number of non-dummy blocks in last MCU column & row */ + tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + if (tmp == 0) tmp = compptr->MCU_width; + compptr->last_col_width = tmp; + tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + if (tmp == 0) tmp = compptr->MCU_height; + compptr->last_row_height = tmp; + /* Prepare array describing MCU composition */ + mcublks = compptr->MCU_blocks; + if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + while (mcublks-- > 0) { + cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + } + } + + } +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table. (The IJG encoder is not + * currently capable of doing this, but other encoders might.) Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot. If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL(void) +latch_quant_tables (j_decompress_ptr cinfo) +{ + int ci, qtblno; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* No work if we already saved Q-table for this component */ + if (compptr->quant_table != NULL) + continue; + /* Make sure specified quantization table is present */ + qtblno = compptr->quant_tbl_no; + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + /* OK, save away the quantization table */ + qtbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)); + MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr->quant_table = qtbl; + } +} + + +/* + * Initialize the input modules to read a scan of compressed data. + * The first call to this is done by jdmaster.c after initializing + * the entire decompressor (during jpeg_start_decompress). + * Subsequent calls come from consume_markers, below. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + (*cinfo->entropy->start_pass) (cinfo); + (*cinfo->coef->start_input_pass) (cinfo); + cinfo->inputctl->consume_input = cinfo->coef->consume_data; +} + + +/* + * Finish up after inputting a compressed-data scan. + * This is called by the coefficient controller after it's read all + * the expected data of the scan. + */ + +METHODDEF(void) +finish_input_pass (j_decompress_ptr cinfo) +{ + cinfo->inputctl->consume_input = consume_markers; +} + + +/* + * Read JPEG markers before, between, or after compressed-data scans. + * Change state as necessary when a new scan is reached. + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + * + * The consume_input method pointer points either here or to the + * coefficient controller's consume_data routine, depending on whether + * we are reading a compressed data segment or inter-segment markers. + */ + +METHODDEF(int) +consume_markers (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + int val; + + if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ + return JPEG_REACHED_EOI; + + val = (*cinfo->marker->read_markers) (cinfo); + + switch (val) { + case JPEG_REACHED_SOS: /* Found SOS */ + if (inputctl->inheaders) { /* 1st SOS */ + initial_setup(cinfo); + inputctl->inheaders = FALSE; + /* Note: start_input_pass must be called by jdmaster.c + * before any more input can be consumed. jdapimin.c is + * responsible for enforcing this sequencing. + */ + } else { /* 2nd or later SOS marker */ + if (! inputctl->pub.has_multiple_scans) + ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ + start_input_pass(cinfo); + } + break; + case JPEG_REACHED_EOI: /* Found EOI */ + inputctl->pub.eoi_reached = TRUE; + if (inputctl->inheaders) { /* Tables-only datastream, apparently */ + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_NO_SOS); + } else { + /* Prevent infinite loop in coef ctlr's decompress_data routine + * if user set output_scan_number larger than number of scans. + */ + if (cinfo->output_scan_number > cinfo->input_scan_number) + cinfo->output_scan_number = cinfo->input_scan_number; + } + break; + case JPEG_SUSPENDED: + break; + } + + return val; +} + + +/* + * Reset state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; + + inputctl->pub.consume_input = consume_markers; + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; + /* Reset other modules */ + (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); + (*cinfo->marker->reset_marker_reader) (cinfo); + /* Reset progression state -- would be cleaner if entropy decoder did this */ + cinfo->coef_bits = NULL; +} + + +/* + * Initialize the input controller module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_input_controller (j_decompress_ptr cinfo) +{ + my_inputctl_ptr inputctl; + + /* Create subobject in permanent pool */ + inputctl = (my_inputctl_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_input_controller)); + cinfo->inputctl = (struct jpeg_input_controller *) inputctl; + /* Initialize method pointers */ + inputctl->pub.consume_input = consume_markers; + inputctl->pub.reset_input_controller = reset_input_controller; + inputctl->pub.start_input_pass = start_input_pass; + inputctl->pub.finish_input_pass = finish_input_pass; + /* Initialize state: can't use reset_input_controller since we don't + * want to try to reset other modules yet. + */ + inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ + inputctl->pub.eoi_reached = FALSE; + inputctl->inheaders = TRUE; +} diff --git a/src/dep/src/irrlicht/jpeglib/jdmainct.c b/src/dep/src/irrlicht/jpeglib/jdmainct.c new file mode 100644 index 0000000..6b0f06f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdmainct.c @@ -0,0 +1,512 @@ +/* + * jdmainct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the main buffer controller for decompression. + * The main buffer lies between the JPEG decompressor proper and the + * post-processor; it holds downsampled data in the JPEG colorspace. + * + * Note that this code is bypassed in raw-data mode, since the application + * supplies the equivalent of the main buffer in that case. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * In the current system design, the main buffer need never be a full-image + * buffer; any full-height buffers will be found inside the coefficient or + * postprocessing controllers. Nonetheless, the main controller is not + * trivial. Its responsibility is to provide context rows for upsampling/ + * rescaling, and doing this in an efficient fashion is a bit tricky. + * + * Postprocessor input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. (We require DCT_scaled_size values to be + * chosen such that these numbers are integers. In practice DCT_scaled_size + * values will likely be powers of two, so we actually have the stronger + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * Upsampling will typically produce max_v_samp_factor pixel rows from each + * row group (times any additional scale factor that the upsampler is + * applying). + * + * The coefficient controller will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + * exactly min_DCT_scaled_size row groups. (This amount of data corresponds + * to one row of MCUs when the image is fully interleaved.) Note that the + * number of sample rows varies across components, but the number of row + * groups does not. Some garbage sample rows may be included in the last iMCU + * row at the bottom of the image. + * + * Depending on the vertical scaling algorithm used, the upsampler may need + * access to the sample row(s) above and below its current input row group. + * The upsampler is required to set need_context_rows TRUE at global selection + * time if so. When need_context_rows is FALSE, this controller can simply + * obtain one iMCU row at a time from the coefficient controller and dole it + * out as row groups to the postprocessor. + * + * When need_context_rows is TRUE, this controller guarantees that the buffer + * passed to postprocessing contains at least one row group's worth of samples + * above and below the row group(s) being processed. Note that the context + * rows "above" the first passed row group appear at negative row offsets in + * the passed buffer. At the top and bottom of the image, the required + * context rows are manufactured by duplicating the first or last real sample + * row; this avoids having special cases in the upsampling inner loops. + * + * The amount of context is fixed at one row group just because that's a + * convenient number for this controller to work with. The existing + * upsamplers really only need one sample row of context. An upsampler + * supporting arbitrary output rescaling might wish for more than one row + * group of context when shrinking the image; tough, we don't handle that. + * (This is justified by the assumption that downsizing will be handled mostly + * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * the upsample step needn't be much less than one.) + * + * To provide the desired context, we have to retain the last two row groups + * of one iMCU row while reading in the next iMCU row. (The last row group + * can't be processed until we have another row group for its below-context, + * and so we have to save the next-to-last group too for its above-context.) + * We could do this most simply by copying data around in our buffer, but + * that'd be very slow. We can avoid copying any data by creating a rather + * strange pointer structure. Here's how it works. We allocate a workspace + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * of row groups per iMCU row). We create two sets of redundant pointers to + * the workspace. Labeling the physical row groups 0 to M+1, the synthesized + * pointer lists look like this: + * M+1 M-1 + * master pointer --> 0 master pointer --> 0 + * 1 1 + * ... ... + * M-3 M-3 + * M-2 M + * M-1 M+1 + * M M-2 + * M+1 M-1 + * 0 0 + * We read alternate iMCU rows using each master pointer; thus the last two + * row groups of the previous iMCU row remain un-overwritten in the workspace. + * The pointer lists are set up so that the required context rows appear to + * be adjacent to the proper places when we pass the pointer lists to the + * upsampler. + * + * The above pictures describe the normal state of the pointer lists. + * At top and bottom of the image, we diddle the pointer lists to duplicate + * the first or last sample row as necessary (this is cheaper than copying + * sample rows around). + * + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + * situation each iMCU row provides only one row group so the buffering logic + * must be different (eg, we must read two iMCU rows before we can emit the + * first row group). For now, we simply do not support providing context + * rows when min_DCT_scaled_size is 1. That combination seems unlikely to + * be worth providing --- if someone wants a 1/8th-size preview, they probably + * want it quick and dirty, so a context-free upsampler is sufficient. + */ + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_main_controller pub; /* public fields */ + + /* Pointer to allocated workspace (M or M+2 row groups). */ + JSAMPARRAY buffer[MAX_COMPONENTS]; + + boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ + JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ + + /* Remaining fields are only used in the context case. */ + + /* These are the master pointers to the funny-order pointer lists. */ + JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ + + int whichptr; /* indicates which pointer set is now in use */ + int context_state; /* process_data state machine status */ + JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ + JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ +} my_main_controller; + +typedef my_main_controller * my_main_ptr; + +/* context_state values: */ +#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ +#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ +#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ + + +/* Forward declarations */ +METHODDEF(void) process_data_simple_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +METHODDEF(void) process_data_context_main + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) process_data_crank_post + JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); +#endif + + +LOCAL(void) +alloc_funny_pointers (j_decompress_ptr cinfo) +/* Allocate space for the funny pointer lists. + * This is done only once, not once per pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + /* Get top-level space for component array pointers. + * We alloc both arrays with one call to save a few cycles. + */ + main->xbuffer[0] = (JSAMPIMAGE) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); + main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + /* Get space for pointer lists --- M+4 row groups in each list. + * We alloc both pointer lists with one call to save a few cycles. + */ + xbuf = (JSAMPARRAY) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); + xbuf += rgroup; /* want one row group at negative offsets */ + main->xbuffer[0][ci] = xbuf; + xbuf += rgroup * (M + 4); + main->xbuffer[1][ci] = xbuf; + } +} + + +LOCAL(void) +make_funny_pointers (j_decompress_ptr cinfo) +/* Create the funny pointer lists discussed in the comments above. + * The actual workspace is already allocated (in main->buffer), + * and the space for the pointer lists is allocated too. + * This routine just fills in the curiously ordered lists. + * This will be repeated at the beginning of each pass. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY buf, xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + /* First copy the workspace pointers as-is */ + buf = main->buffer[ci]; + for (i = 0; i < rgroup * (M + 2); i++) { + xbuf0[i] = xbuf1[i] = buf[i]; + } + /* In the second list, put the last four row groups in swapped order */ + for (i = 0; i < rgroup * 2; i++) { + xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; + xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; + } + /* The wraparound pointers at top and bottom will be filled later + * (see set_wraparound_pointers, below). Initially we want the "above" + * pointers to duplicate the first actual data line. This only needs + * to happen in xbuffer[0]. + */ + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[0]; + } + } +} + + +LOCAL(void) +set_wraparound_pointers (j_decompress_ptr cinfo) +/* Set up the "wraparound" pointers at top and bottom of the pointer lists. + * This changes the pointer list state from top-of-image to the normal state. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup; + int M = cinfo->min_DCT_scaled_size; + jpeg_component_info *compptr; + JSAMPARRAY xbuf0, xbuf1; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; + for (i = 0; i < rgroup; i++) { + xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; + xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; + xbuf0[rgroup*(M+2) + i] = xbuf0[i]; + xbuf1[rgroup*(M+2) + i] = xbuf1[i]; + } + } +} + + +LOCAL(void) +set_bottom_pointers (j_decompress_ptr cinfo) +/* Change the pointer lists to duplicate the last sample row at the bottom + * of the image. whichptr indicates which xbuffer holds the final iMCU row. + * Also sets rowgroups_avail to indicate number of nondummy row groups in row. + */ +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + int ci, i, rgroup, iMCUheight, rows_left; + jpeg_component_info *compptr; + JSAMPARRAY xbuf; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Count sample rows in one iMCU row and in one row group */ + iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; + rgroup = iMCUheight / cinfo->min_DCT_scaled_size; + /* Count nondummy sample rows remaining for this component */ + rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); + if (rows_left == 0) rows_left = iMCUheight; + /* Count nondummy row groups. Should get same answer for each component, + * so we need only do it once. + */ + if (ci == 0) { + main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + } + /* Duplicate the last real sample row rgroup*2 times; this pads out the + * last partial rowgroup and ensures at least one full rowgroup of context. + */ + xbuf = main->xbuffer[main->whichptr][ci]; + for (i = 0; i < rgroup * 2; i++) { + xbuf[rows_left + i] = xbuf[rows_left-1]; + } + } +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->upsample->need_context_rows) { + main->pub.process_data = process_data_context_main; + make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ + main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main->context_state = CTX_PREPARE_FOR_IMCU; + main->iMCU_row_ctr = 0; + } else { + /* Simple case with no context needed */ + main->pub.process_data = process_data_simple_main; + } + main->buffer_full = FALSE; /* Mark buffer empty */ + main->rowgroup_ctr = 0; + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_CRANK_DEST: + /* For last pass of 2-pass quantization, just crank the postprocessor */ + main->pub.process_data = process_data_crank_post; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +/* + * Process some data. + * This handles the simple case where no context is required. + */ + +METHODDEF(void) +process_data_simple_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + JDIMENSION rowgroups_avail; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + } + + /* There are always min_DCT_scaled_size row groups in an iMCU row. */ + rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; + /* Note: at the bottom of the image, we may pass extra garbage row groups + * to the postprocessor. The postprocessor has to check for bottom + * of image anyway (at row resolution), so no point in us doing it too. + */ + + /* Feed the postprocessor */ + (*cinfo->post->post_process_data) (cinfo, main->buffer, + &main->rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ + if (main->rowgroup_ctr >= rowgroups_avail) { + main->buffer_full = FALSE; + main->rowgroup_ctr = 0; + } +} + + +/* + * Process some data. + * This handles the case where context rows must be provided. + */ + +METHODDEF(void) +process_data_context_main (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_main_ptr main = (my_main_ptr) cinfo->main; + + /* Read input data if we haven't filled the main buffer yet */ + if (! main->buffer_full) { + if (! (*cinfo->coef->decompress_data) (cinfo, + main->xbuffer[main->whichptr])) + return; /* suspension forced, can do nothing more */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->iMCU_row_ctr++; /* count rows received */ + } + + /* Postprocessor typically will not swallow all the input data it is handed + * in one call (due to filling the output buffer first). Must be prepared + * to exit and restart. This switch lets us keep track of how far we got. + * Note that each case falls through to the next on successful completion. + */ + switch (main->context_state) { + case CTX_POSTPONED_ROW: + /* Call postprocessor using previously set pointers for postponed row */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + main->context_state = CTX_PREPARE_FOR_IMCU; + if (*out_row_ctr >= out_rows_avail) + return; /* Postprocessor exactly filled output buf */ + /*FALLTHROUGH*/ + case CTX_PREPARE_FOR_IMCU: + /* Prepare to process first M-1 row groups of this iMCU row */ + main->rowgroup_ctr = 0; + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + /* Check for bottom of image: if so, tweak pointers to "duplicate" + * the last sample row, and adjust rowgroups_avail to ignore padding rows. + */ + if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) + set_bottom_pointers(cinfo); + main->context_state = CTX_PROCESS_IMCU; + /*FALLTHROUGH*/ + case CTX_PROCESS_IMCU: + /* Call postprocessor using previously set pointers */ + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main->rowgroup_ctr < main->rowgroups_avail) + return; /* Need to suspend */ + /* After the first iMCU, change wraparound pointers to normal state */ + if (main->iMCU_row_ctr == 1) + set_wraparound_pointers(cinfo); + /* Prepare to load new iMCU row using other xbuffer list */ + main->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main->buffer_full = FALSE; + /* Still need to process last row group of this iMCU row, */ + /* which is saved at index M+1 of the other xbuffer */ + main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); + main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); + main->context_state = CTX_POSTPONED_ROW; + } +} + + +/* + * Process some data. + * Final pass of two-pass quantization: just call the postprocessor. + * Source data will be the postprocessor controller's internal buffer. + */ + +#ifdef QUANT_2PASS_SUPPORTED + +METHODDEF(void) +process_data_crank_post (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, + (JDIMENSION *) NULL, (JDIMENSION) 0, + output_buf, out_row_ctr, out_rows_avail); +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize main buffer controller. + */ + +GLOBAL(void) +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_main_ptr main; + int ci, rgroup, ngroups; + jpeg_component_info *compptr; + + main = (my_main_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_main_controller)); + cinfo->main = (struct jpeg_d_main_controller *) main; + main->pub.start_pass = start_pass_main; + + if (need_full_buffer) /* shouldn't happen */ + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + + /* Allocate the workspace. + * ngroups is the number of row groups we need. + */ + if (cinfo->upsample->need_context_rows) { + if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ + ERREXIT(cinfo, JERR_NOTIMPL); + alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ + ngroups = cinfo->min_DCT_scaled_size + 2; + } else { + ngroups = cinfo->min_DCT_scaled_size; + } + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; /* height of a row group of component */ + main->buffer[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + compptr->width_in_blocks * compptr->DCT_scaled_size, + (JDIMENSION) (rgroup * ngroups)); + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdmarker.c b/src/dep/src/irrlicht/jpeglib/jdmarker.c new file mode 100644 index 0000000..9811761 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdmarker.c @@ -0,0 +1,1360 @@ +/* + * jdmarker.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to decode JPEG datastream markers. + * Most of the complexity arises from our desire to support input + * suspension: if not all of the data for a marker is available, + * we must exit back to the application. On resumption, we reprocess + * the marker. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +typedef enum { /* JPEG marker codes */ + M_SOF0 = 0xc0, + M_SOF1 = 0xc1, + M_SOF2 = 0xc2, + M_SOF3 = 0xc3, + + M_SOF5 = 0xc5, + M_SOF6 = 0xc6, + M_SOF7 = 0xc7, + + M_JPG = 0xc8, + M_SOF9 = 0xc9, + M_SOF10 = 0xca, + M_SOF11 = 0xcb, + + M_SOF13 = 0xcd, + M_SOF14 = 0xce, + M_SOF15 = 0xcf, + + M_DHT = 0xc4, + + M_DAC = 0xcc, + + M_RST0 = 0xd0, + M_RST1 = 0xd1, + M_RST2 = 0xd2, + M_RST3 = 0xd3, + M_RST4 = 0xd4, + M_RST5 = 0xd5, + M_RST6 = 0xd6, + M_RST7 = 0xd7, + + M_SOI = 0xd8, + M_EOI = 0xd9, + M_SOS = 0xda, + M_DQT = 0xdb, + M_DNL = 0xdc, + M_DRI = 0xdd, + M_DHP = 0xde, + M_EXP = 0xdf, + + M_APP0 = 0xe0, + M_APP1 = 0xe1, + M_APP2 = 0xe2, + M_APP3 = 0xe3, + M_APP4 = 0xe4, + M_APP5 = 0xe5, + M_APP6 = 0xe6, + M_APP7 = 0xe7, + M_APP8 = 0xe8, + M_APP9 = 0xe9, + M_APP10 = 0xea, + M_APP11 = 0xeb, + M_APP12 = 0xec, + M_APP13 = 0xed, + M_APP14 = 0xee, + M_APP15 = 0xef, + + M_JPG0 = 0xf0, + M_JPG13 = 0xfd, + M_COM = 0xfe, + + M_TEM = 0x01, + + M_ERROR = 0x100 +} JPEG_MARKER; + + +/* Private state */ + +typedef struct { + struct jpeg_marker_reader pub; /* public fields */ + + /* Application-overridable marker processing methods */ + jpeg_marker_parser_method process_COM; + jpeg_marker_parser_method process_APPn[16]; + + /* Limit on marker data length to save for each marker type */ + unsigned int length_limit_COM; + unsigned int length_limit_APPn[16]; + + /* Status of COM/APPn marker saving */ + jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ + unsigned int bytes_read; /* data bytes read so far in marker */ + /* Note: cur_marker is not linked into marker_list until it's all read. */ +} my_marker_reader; + +typedef my_marker_reader * my_marker_ptr; + + +/* + * Macros for fetching data from the data source module. + * + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect + * the current restart point; we update them only when we have reached a + * suitable place to restart if a suspension occurs. + */ + +/* Declare and initialize local copies of input pointer/count */ +#define INPUT_VARS(cinfo) \ + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo) \ + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) + +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ +#define INPUT_RELOAD(cinfo) \ + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action) \ + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } + +/* Read a byte into variable V. + * If must suspend, take the specified action (typically "return FALSE"). + */ +#define INPUT_BYTE(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V += GETJOCTET(*next_input_byte++); ) + + +/* + * Routines to process JPEG markers. + * + * Entry condition: JPEG marker itself has been read and its code saved + * in cinfo->unread_marker; input restart point is just after the marker. + * + * Exit: if return TRUE, have read and processed any parameters, and have + * updated the restart point to point after the parameters. + * If return FALSE, was forced to suspend before reaching end of + * marker parameters; restart point has not been moved. Same routine + * will be called again after application supplies more input data. + * + * This approach to suspension assumes that all of a marker's parameters + * can fit into a single input bufferload. This should hold for "normal" + * markers. Some COM/APPn markers might have large parameter segments + * that might not fit. If we are simply dropping such a marker, we use + * skip_input_data to get past it, and thereby put the problem on the + * source manager's shoulders. If we are saving the marker's contents + * into memory, we use a slightly different convention: when forced to + * suspend, the marker processor updates the restart point to the end of + * what it's consumed (ie, the end of the buffer) before returning FALSE. + * On resumption, cinfo->unread_marker still contains the marker code, + * but the data source will point to the next chunk of marker data. + * The marker processor must retain internal state to deal with this. + * + * Note that we don't bother to avoid duplicate trace messages if a + * suspension occurs within marker parameters. Other side effects + * require more care. + */ + + +LOCAL(boolean) +get_soi (j_decompress_ptr cinfo) +/* Process an SOI marker */ +{ + int i; + + TRACEMS(cinfo, 1, JTRC_SOI); + + if (cinfo->marker->saw_SOI) + ERREXIT(cinfo, JERR_SOI_DUPLICATE); + + /* Reset all parameters that are defined to be reset by SOI */ + + for (i = 0; i < NUM_ARITH_TBLS; i++) { + cinfo->arith_dc_L[i] = 0; + cinfo->arith_dc_U[i] = 1; + cinfo->arith_ac_K[i] = 5; + } + cinfo->restart_interval = 0; + + /* Set initial assumptions for colorspace etc */ + + cinfo->jpeg_color_space = JCS_UNKNOWN; + cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ + + cinfo->saw_JFIF_marker = FALSE; + cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ + cinfo->JFIF_minor_version = 1; + cinfo->density_unit = 0; + cinfo->X_density = 1; + cinfo->Y_density = 1; + cinfo->saw_Adobe_marker = FALSE; + cinfo->Adobe_transform = 0; + + cinfo->marker->saw_SOI = TRUE; + + return TRUE; +} + + +LOCAL(boolean) +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +/* Process a SOFn marker */ +{ + INT32 length; + int c, ci; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + cinfo->progressive_mode = is_prog; + cinfo->arith_code = is_arith; + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); + INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); + INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); + + length -= 8; + + TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, + (int) cinfo->image_width, (int) cinfo->image_height, + cinfo->num_components); + + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_DUPLICATE); + + /* We don't support files in which the image height is initially specified */ + /* as 0 and is later redefined by DNL. As long as we have to check that, */ + /* might as well have a general sanity check. */ + if (cinfo->image_height <= 0 || cinfo->image_width <= 0 + || cinfo->num_components <= 0) + ERREXIT(cinfo, JERR_EMPTY_IMAGE); + + if (length != (cinfo->num_components * 3)) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + if (cinfo->comp_info == NULL) /* do only once, even if suspend */ + cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * SIZEOF(jpeg_component_info)); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + compptr->component_index = ci; + INPUT_BYTE(cinfo, compptr->component_id, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + compptr->h_samp_factor = (c >> 4) & 15; + compptr->v_samp_factor = (c ) & 15; + INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); + + TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, + compptr->component_id, compptr->h_samp_factor, + compptr->v_samp_factor, compptr->quant_tbl_no); + } + + cinfo->marker->saw_SOF = TRUE; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_sos (j_decompress_ptr cinfo) +/* Process a SOS marker */ +{ + INT32 length; + int i, ci, n, c, cc; + jpeg_component_info * compptr; + INPUT_VARS(cinfo); + + if (! cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOS_NO_SOF); + + INPUT_2BYTES(cinfo, length, return FALSE); + + INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ + + TRACEMS1(cinfo, 1, JTRC_SOS, n); + + if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + cinfo->comps_in_scan = n; + + /* Collect the component-spec parameters */ + + for (i = 0; i < n; i++) { + INPUT_BYTE(cinfo, cc, return FALSE); + INPUT_BYTE(cinfo, c, return FALSE); + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + if (cc == compptr->component_id) + goto id_found; + } + + ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo->cur_comp_info[i] = compptr; + compptr->dc_tbl_no = (c >> 4) & 15; + compptr->ac_tbl_no = (c ) & 15; + + TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, + compptr->dc_tbl_no, compptr->ac_tbl_no); + } + + /* Collect the additional scan parameters Ss, Se, Ah/Al. */ + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ss = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Se = c; + INPUT_BYTE(cinfo, c, return FALSE); + cinfo->Ah = (c >> 4) & 15; + cinfo->Al = (c ) & 15; + + TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, + cinfo->Ah, cinfo->Al); + + /* Prepare to scan data & restart markers */ + cinfo->marker->next_restart_num = 0; + + /* Count another SOS marker */ + cinfo->input_scan_number++; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +#ifdef D_ARITH_CODING_SUPPORTED + +LOCAL(boolean) +get_dac (j_decompress_ptr cinfo) +/* Process a DAC marker */ +{ + INT32 length; + int index, val; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, index, return FALSE); + INPUT_BYTE(cinfo, val, return FALSE); + + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_DAC, index, val); + + if (index < 0 || index >= (2*NUM_ARITH_TBLS)) + ERREXIT1(cinfo, JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) { /* define AC table */ + cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; + } else { /* define DC table */ + cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); + cinfo->arith_dc_U[index] = (UINT8) (val >> 4); + if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) + ERREXIT1(cinfo, JERR_DAC_VALUE, val); + } + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + +#else /* ! D_ARITH_CODING_SUPPORTED */ + +#define get_dac(cinfo) skip_variable(cinfo) + +#endif /* D_ARITH_CODING_SUPPORTED */ + + +LOCAL(boolean) +get_dht (j_decompress_ptr cinfo) +/* Process a DHT marker */ +{ + INT32 length; + UINT8 bits[17]; + UINT8 huffval[256]; + int i, index, count; + JHUFF_TBL **htblptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 16) { + INPUT_BYTE(cinfo, index, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DHT, index); + + bits[0] = 0; + count = 0; + for (i = 1; i <= 16; i++) { + INPUT_BYTE(cinfo, bits[i], return FALSE); + count += bits[i]; + } + + length -= 1 + 16; + + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(cinfo, 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + + /* Here we just do minimal validation of the counts to avoid walking + * off the end of our table space. jdhuff.c will check more carefully. + */ + if (count > 256 || ((INT32) count) > length) + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); + + for (i = 0; i < count; i++) + INPUT_BYTE(cinfo, huffval[i], return FALSE); + + length -= count; + + if (index & 0x10) { /* AC table definition */ + index -= 0x10; + htblptr = &cinfo->ac_huff_tbl_ptrs[index]; + } else { /* DC table definition */ + htblptr = &cinfo->dc_huff_tbl_ptrs[index]; + } + + if (index < 0 || index >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_DHT_INDEX, index); + + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + + MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); + MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dqt (j_decompress_ptr cinfo) +/* Process a DQT marker */ +{ + INT32 length; + int n, i, prec; + unsigned int tmp; + JQUANT_TBL *quant_ptr; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + while (length > 0) { + INPUT_BYTE(cinfo, n, return FALSE); + prec = n >> 4; + n &= 0x0F; + + TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); + + if (n >= NUM_QUANT_TBLS) + ERREXIT1(cinfo, JERR_DQT_INDEX, n); + + if (cinfo->quant_tbl_ptrs[n] == NULL) + cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); + quant_ptr = cinfo->quant_tbl_ptrs[n]; + + for (i = 0; i < DCTSIZE2; i++) { + if (prec) + INPUT_2BYTES(cinfo, tmp, return FALSE); + else + INPUT_BYTE(cinfo, tmp, return FALSE); + /* We convert the zigzag-order table to natural array order. */ + quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; + } + + if (cinfo->err->trace_level >= 2) { + for (i = 0; i < DCTSIZE2; i += 8) { + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + } + } + + length -= DCTSIZE2+1; + if (prec) length -= DCTSIZE2; + } + + if (length != 0) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +get_dri (j_decompress_ptr cinfo) +/* Process a DRI marker */ +{ + INT32 length; + unsigned int tmp; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + + if (length != 4) + ERREXIT(cinfo, JERR_BAD_LENGTH); + + INPUT_2BYTES(cinfo, tmp, return FALSE); + + TRACEMS1(cinfo, 1, JTRC_DRI, tmp); + + cinfo->restart_interval = tmp; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Routines for processing APPn and COM markers. + * These are either saved in memory or discarded, per application request. + * APP0 and APP14 are specially checked to see if they are + * JFIF and Adobe markers, respectively. + */ + +#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ +#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ +#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ + + +LOCAL(void) +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP0. + * Take appropriate action if it is a JFIF marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + INT32 totallen = (INT32) datalen + remaining; + + if (datalen >= APP0_DATA_LEN && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x49 && + GETJOCTET(data[3]) == 0x46 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF APP0 marker: save info */ + cinfo->saw_JFIF_marker = TRUE; + cinfo->JFIF_major_version = GETJOCTET(data[5]); + cinfo->JFIF_minor_version = GETJOCTET(data[6]); + cinfo->density_unit = GETJOCTET(data[7]); + cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); + cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); + /* Check version. + * Major version must be 1, anything else signals an incompatible change. + * (We used to treat this as an error, but now it's a nonfatal warning, + * because some bozo at Hijaak couldn't read the spec.) + * Minor version should be 0..2, but process anyway if newer. + */ + if (cinfo->JFIF_major_version != 1) + WARNMS2(cinfo, JWRN_JFIF_MAJOR, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version); + /* Generate trace messages */ + TRACEMS5(cinfo, 1, JTRC_JFIF, + cinfo->JFIF_major_version, cinfo->JFIF_minor_version, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + /* Validate thumbnail dimensions and issue appropriate messages */ + if (GETJOCTET(data[12]) | GETJOCTET(data[13])) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + totallen -= APP0_DATA_LEN; + if (totallen != + ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) + TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); + } else if (datalen >= 6 && + GETJOCTET(data[0]) == 0x4A && + GETJOCTET(data[1]) == 0x46 && + GETJOCTET(data[2]) == 0x58 && + GETJOCTET(data[3]) == 0x58 && + GETJOCTET(data[4]) == 0) { + /* Found JFIF "JFXX" extension APP0 marker */ + /* The library doesn't actually do anything with these, + * but we try to produce a helpful trace message. + */ + switch (GETJOCTET(data[5])) { + case 0x10: + TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen); + break; + case 0x11: + TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen); + break; + case 0x13: + TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen); + break; + default: + TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), (int) totallen); + break; + } + } else { + /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen); + } +} + + +LOCAL(void) +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, + unsigned int datalen, INT32 remaining) +/* Examine first few bytes from an APP14. + * Take appropriate action if it is an Adobe marker. + * datalen is # of bytes at data[], remaining is length of rest of marker data. + */ +{ + unsigned int version, flags0, flags1, transform; + + if (datalen >= APP14_DATA_LEN && + GETJOCTET(data[0]) == 0x41 && + GETJOCTET(data[1]) == 0x64 && + GETJOCTET(data[2]) == 0x6F && + GETJOCTET(data[3]) == 0x62 && + GETJOCTET(data[4]) == 0x65) { + /* Found Adobe APP14 marker */ + version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); + flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); + flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); + transform = GETJOCTET(data[11]); + TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); + cinfo->saw_Adobe_marker = TRUE; + cinfo->Adobe_transform = (UINT8) transform; + } else { + /* Start of APP14 does not match "Adobe", or too short */ + TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining)); + } +} + + +METHODDEF(boolean) +get_interesting_appn (j_decompress_ptr cinfo) +/* Process an APP0 or APP14 marker without saving it */ +{ + INT32 length; + JOCTET b[APPN_DATA_LEN]; + unsigned int i, numtoread; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + /* get the interesting part of the marker data */ + if (length >= APPN_DATA_LEN) + numtoread = APPN_DATA_LEN; + else if (length > 0) + numtoread = (unsigned int) length; + else + numtoread = 0; + for (i = 0; i < numtoread; i++) + INPUT_BYTE(cinfo, b[i], return FALSE); + length -= numtoread; + + /* process it */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + case M_APP14: + examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length); + break; + default: + /* can't get here unless jpeg_save_markers chooses wrong processor */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +#ifdef SAVE_MARKERS_SUPPORTED + +METHODDEF(boolean) +save_marker (j_decompress_ptr cinfo) +/* Save an APPn or COM marker into the marker list */ +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + jpeg_saved_marker_ptr cur_marker = marker->cur_marker; + unsigned int bytes_read, data_length; + JOCTET FAR * data; + INT32 length = 0; + INPUT_VARS(cinfo); + + if (cur_marker == NULL) { + /* begin reading a marker */ + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + if (length >= 0) { /* watch out for bogus length word */ + /* figure out how much we want to save */ + unsigned int limit; + if (cinfo->unread_marker == (int) M_COM) + limit = marker->length_limit_COM; + else + limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; + if ((unsigned int) length < limit) + limit = (unsigned int) length; + /* allocate and initialize the marker item */ + cur_marker = (jpeg_saved_marker_ptr) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_struct) + limit); + cur_marker->next = NULL; + cur_marker->marker = (UINT8) cinfo->unread_marker; + cur_marker->original_length = (unsigned int) length; + cur_marker->data_length = limit; + /* data area is just beyond the jpeg_marker_struct */ + data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1); + marker->cur_marker = cur_marker; + marker->bytes_read = 0; + bytes_read = 0; + data_length = limit; + } else { + /* deal with bogus length word */ + bytes_read = data_length = 0; + data = NULL; + } + } else { + /* resume reading a marker */ + bytes_read = marker->bytes_read; + data_length = cur_marker->data_length; + data = cur_marker->data + bytes_read; + } + + while (bytes_read < data_length) { + INPUT_SYNC(cinfo); /* move the restart point to here */ + marker->bytes_read = bytes_read; + /* If there's not at least one byte in buffer, suspend */ + MAKE_BYTE_AVAIL(cinfo, return FALSE); + /* Copy bytes with reasonable rapidity */ + while (bytes_read < data_length && bytes_in_buffer > 0) { + *data++ = *next_input_byte++; + bytes_in_buffer--; + bytes_read++; + } + } + + /* Done reading what we want to read */ + if (cur_marker != NULL) { /* will be NULL if bogus length word */ + /* Add new marker to end of list */ + if (cinfo->marker_list == NULL) { + cinfo->marker_list = cur_marker; + } else { + jpeg_saved_marker_ptr prev = cinfo->marker_list; + while (prev->next != NULL) + prev = prev->next; + prev->next = cur_marker; + } + /* Reset pointer & calc remaining data length */ + data = cur_marker->data; + length = cur_marker->original_length - data_length; + } + /* Reset to initial state for next marker */ + marker->cur_marker = NULL; + + /* Process the marker if interesting; else just make a generic trace msg */ + switch (cinfo->unread_marker) { + case M_APP0: + examine_app0(cinfo, data, data_length, length); + break; + case M_APP14: + examine_app14(cinfo, data, data_length, length); + break; + default: + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, + (int) (data_length + length)); + break; + } + + /* skip any remaining data -- could be lots */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +METHODDEF(boolean) +skip_variable (j_decompress_ptr cinfo) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + INT32 length; + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); + + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) + (*cinfo->src->skip_input_data) (cinfo, (long) length); + + return TRUE; +} + + +/* + * Find the next JPEG marker, save it in cinfo->unread_marker. + * Returns FALSE if had to suspend before reaching a marker; + * in that case cinfo->unread_marker is unchanged. + * + * Note that the result might not be a valid marker code, + * but it will never be 0 or FF. + */ + +LOCAL(boolean) +next_marker (j_decompress_ptr cinfo) +{ + int c; + INPUT_VARS(cinfo); + + for (;;) { + INPUT_BYTE(cinfo, c, return FALSE); + /* Skip any non-FF bytes. + * This may look a bit inefficient, but it will not occur in a valid file. + * We sync after each discarded byte so that a suspending data source + * can discard the byte from its buffer. + */ + while (c != 0xFF) { + cinfo->marker->discarded_bytes++; + INPUT_SYNC(cinfo); + INPUT_BYTE(cinfo, c, return FALSE); + } + /* This loop swallows any duplicate FF bytes. Extra FFs are legal as + * pad bytes, so don't count them in discarded_bytes. We assume there + * will not be so many consecutive FF bytes as to overflow a suspending + * data source's input buffer. + */ + do { + INPUT_BYTE(cinfo, c, return FALSE); + } while (c == 0xFF); + if (c != 0) + break; /* found a valid marker, exit loop */ + /* Reach here if we found a stuffed-zero data sequence (FF/00). + * Discard it and loop back to try again. + */ + cinfo->marker->discarded_bytes += 2; + INPUT_SYNC(cinfo); + } + + if (cinfo->marker->discarded_bytes != 0) { + WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); + cinfo->marker->discarded_bytes = 0; + } + + cinfo->unread_marker = c; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +LOCAL(boolean) +first_marker (j_decompress_ptr cinfo) +/* Like next_marker, but used to obtain the initial SOI marker. */ +/* For this marker, we do not allow preceding garbage or fill; otherwise, + * we might well scan an entire input file before realizing it ain't JPEG. + * If an application wants to process non-JFIF files, it must seek to the + * SOI before calling the JPEG library. + */ +{ + int c, c2; + INPUT_VARS(cinfo); + + INPUT_BYTE(cinfo, c, return FALSE); + INPUT_BYTE(cinfo, c2, return FALSE); + if (c != 0xFF || c2 != (int) M_SOI) + ERREXIT2(cinfo, JERR_NO_SOI, c, c2); + + cinfo->unread_marker = c2; + + INPUT_SYNC(cinfo); + return TRUE; +} + + +/* + * Read markers until SOS or EOI. + * + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + +METHODDEF(int) +read_markers (j_decompress_ptr cinfo) +{ + /* Outer loop repeats once for each marker. */ + for (;;) { + /* Collect the marker proper, unless we already did. */ + /* NB: first_marker() enforces the requirement that SOI appear first. */ + if (cinfo->unread_marker == 0) { + if (! cinfo->marker->saw_SOI) { + if (! first_marker(cinfo)) + return JPEG_SUSPENDED; + } else { + if (! next_marker(cinfo)) + return JPEG_SUSPENDED; + } + } + /* At this point cinfo->unread_marker contains the marker code and the + * input point is just past the marker proper, but before any parameters. + * A suspension will cause us to return with this state still true. + */ + switch (cinfo->unread_marker) { + case M_SOI: + if (! get_soi(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + if (! get_sof(cinfo, FALSE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF2: /* Progressive, Huffman */ + if (! get_sof(cinfo, TRUE, FALSE)) + return JPEG_SUSPENDED; + break; + + case M_SOF9: /* Extended sequential, arithmetic */ + if (! get_sof(cinfo, FALSE, TRUE)) + return JPEG_SUSPENDED; + break; + + case M_SOF10: /* Progressive, arithmetic */ + if (! get_sof(cinfo, TRUE, TRUE)) + return JPEG_SUSPENDED; + break; + + /* Currently unsupported SOFn types */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_JPG: /* Reserved for JPEG extensions */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); + break; + + case M_SOS: + if (! get_sos(cinfo)) + return JPEG_SUSPENDED; + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_SOS; + + case M_EOI: + TRACEMS(cinfo, 1, JTRC_EOI); + cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_REACHED_EOI; + + case M_DAC: + if (! get_dac(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DHT: + if (! get_dht(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DQT: + if (! get_dqt(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_DRI: + if (! get_dri(cinfo)) + return JPEG_SUSPENDED; + break; + + case M_APP0: + case M_APP1: + case M_APP2: + case M_APP3: + case M_APP4: + case M_APP5: + case M_APP6: + case M_APP7: + case M_APP8: + case M_APP9: + case M_APP10: + case M_APP11: + case M_APP12: + case M_APP13: + case M_APP14: + case M_APP15: + if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ + cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_COM: + if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) + return JPEG_SUSPENDED; + break; + + case M_RST0: /* these are all parameterless */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); + break; + + case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ + if (! skip_variable(cinfo)) + return JPEG_SUSPENDED; + break; + + default: /* must be DHP, EXP, JPGn, or RESn */ + /* For now, we treat the reserved markers as fatal errors since they are + * likely to be used to signal incompatible JPEG Part 3 extensions. + * Once the JPEG 3 version-number marker is well defined, this code + * ought to change! + */ + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); + break; + } + /* Successfully processed marker, so reset state variable */ + cinfo->unread_marker = 0; + } /* end loop */ +} + + +/* + * Read a restart marker, which is expected to appear next in the datastream; + * if the marker is not there, take appropriate recovery action. + * Returns FALSE if suspension is required. + * + * This is called by the entropy decoder after it has read an appropriate + * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder + * has already read a marker from the data source. Under normal conditions + * cinfo->unread_marker will be reset to 0 before returning; if not reset, + * it holds a marker which the decoder will be unable to read past. + */ + +METHODDEF(boolean) +read_restart_marker (j_decompress_ptr cinfo) +{ + /* Obtain a marker unless we already did. */ + /* Note that next_marker will complain if it skips any data. */ + if (cinfo->unread_marker == 0) { + if (! next_marker(cinfo)) + return FALSE; + } + + if (cinfo->unread_marker == + ((int) M_RST0 + cinfo->marker->next_restart_num)) { + /* Normal case --- swallow the marker and let entropy decoder continue */ + TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); + cinfo->unread_marker = 0; + } else { + /* Uh-oh, the restart markers have been messed up. */ + /* Let the data source manager determine how to resync. */ + if (! (*cinfo->src->resync_to_restart) (cinfo, + cinfo->marker->next_restart_num)) + return FALSE; + } + + /* Update next-restart state */ + cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; + + return TRUE; +} + + +/* + * This is the default resync_to_restart method for data source managers + * to use if they don't have any better approach. Some data source managers + * may be able to back up, or may have additional knowledge about the data + * which permits a more intelligent recovery strategy; such managers would + * presumably supply their own resync method. + * + * read_restart_marker calls resync_to_restart if it finds a marker other than + * the restart marker it was expecting. (This code is *not* used unless + * a nonzero restart interval has been declared.) cinfo->unread_marker is + * the marker code actually found (might be anything, except 0 or FF). + * The desired restart marker number (0..7) is passed as a parameter. + * This routine is supposed to apply whatever error recovery strategy seems + * appropriate in order to position the input stream to the next data segment. + * Note that cinfo->unread_marker is treated as a marker appearing before + * the current data-source input point; usually it should be reset to zero + * before returning. + * Returns FALSE if suspension is required. + * + * This implementation is substantially constrained by wanting to treat the + * input as a data stream; this means we can't back up. Therefore, we have + * only the following actions to work with: + * 1. Simply discard the marker and let the entropy decoder resume at next + * byte of file. + * 2. Read forward until we find another marker, discarding intervening + * data. (In theory we could look ahead within the current bufferload, + * without having to discard data if we don't find the desired marker. + * This idea is not implemented here, in part because it makes behavior + * dependent on buffer size and chance buffer-boundary positions.) + * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). + * This will cause the entropy decoder to process an empty data segment, + * inserting dummy zeroes, and then we will reprocess the marker. + * + * #2 is appropriate if we think the desired marker lies ahead, while #3 is + * appropriate if the found marker is a future restart marker (indicating + * that we have missed the desired restart marker, probably because it got + * corrupted). + * We apply #2 or #3 if the found marker is a restart marker no more than + * two counts behind or ahead of the expected one. We also apply #2 if the + * found marker is not a legal JPEG marker code (it's certainly bogus data). + * If the found marker is a restart marker more than 2 counts away, we do #1 + * (too much risk that the marker is erroneous; with luck we will be able to + * resync at some future point). + * For any valid non-restart JPEG marker, we apply #3. This keeps us from + * overrunning the end of a scan. An implementation limited to single-scan + * files might find it better to apply #2 for markers other than EOI, since + * any other marker would have to be bogus data in that case. + */ + +GLOBAL(boolean) +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) +{ + int marker = cinfo->unread_marker; + int action = 1; + + /* Always put up a warning. */ + WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); + + /* Outer loop handles repeated decision after scanning forward. */ + for (;;) { + if (marker < (int) M_SOF0) + action = 2; /* invalid marker */ + else if (marker < (int) M_RST0 || marker > (int) M_RST7) + action = 3; /* valid non-restart marker */ + else { + if (marker == ((int) M_RST0 + ((desired+1) & 7)) || + marker == ((int) M_RST0 + ((desired+2) & 7))) + action = 3; /* one of the next two expected restarts */ + else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || + marker == ((int) M_RST0 + ((desired-2) & 7))) + action = 2; /* a prior restart, so advance */ + else + action = 1; /* desired restart or too far away */ + } + TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); + switch (action) { + case 1: + /* Discard marker and let entropy decoder resume processing. */ + cinfo->unread_marker = 0; + return TRUE; + case 2: + /* Scan to the next marker, and repeat the decision loop. */ + if (! next_marker(cinfo)) + return FALSE; + marker = cinfo->unread_marker; + break; + case 3: + /* Return without advancing past this marker. */ + /* Entropy decoder will be forced to process an empty segment. */ + return TRUE; + } + } /* end loop */ +} + + +/* + * Reset marker processing state to begin a fresh datastream. + */ + +METHODDEF(void) +reset_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + cinfo->comp_info = NULL; /* until allocated by get_sof */ + cinfo->input_scan_number = 0; /* no SOS seen yet */ + cinfo->unread_marker = 0; /* no pending marker */ + marker->pub.saw_SOI = FALSE; /* set internal state too */ + marker->pub.saw_SOF = FALSE; + marker->pub.discarded_bytes = 0; + marker->cur_marker = NULL; +} + + +/* + * Initialize the marker reader module. + * This is called only once, when the decompression object is created. + */ + +GLOBAL(void) +jinit_marker_reader (j_decompress_ptr cinfo) +{ + my_marker_ptr marker; + int i; + + /* Create subobject in permanent pool */ + marker = (my_marker_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_marker_reader)); + cinfo->marker = (struct jpeg_marker_reader *) marker; + /* Initialize public method pointers */ + marker->pub.reset_marker_reader = reset_marker_reader; + marker->pub.read_markers = read_markers; + marker->pub.read_restart_marker = read_restart_marker; + /* Initialize COM/APPn processing. + * By default, we examine and then discard APP0 and APP14, + * but simply discard COM and all other APPn. + */ + marker->process_COM = skip_variable; + marker->length_limit_COM = 0; + for (i = 0; i < 16; i++) { + marker->process_APPn[i] = skip_variable; + marker->length_limit_APPn[i] = 0; + } + marker->process_APPn[0] = get_interesting_appn; + marker->process_APPn[14] = get_interesting_appn; + /* Reset marker processing state */ + reset_marker_reader(cinfo); +} + + +/* + * Control saving of COM and APPn markers into marker_list. + */ + +#ifdef SAVE_MARKERS_SUPPORTED + +GLOBAL(void) +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + long maxlength; + jpeg_marker_parser_method processor; + + /* Length limit mustn't be larger than what we can allocate + * (should only be a concern in a 16-bit environment). + */ + maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct); + if (((long) length_limit) > maxlength) + length_limit = (unsigned int) maxlength; + + /* Choose processor routine to use. + * APP0/APP14 have special requirements. + */ + if (length_limit) { + processor = save_marker; + /* If saving APP0/APP14, save at least enough for our internal use. */ + if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN) + length_limit = APP0_DATA_LEN; + else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN) + length_limit = APP14_DATA_LEN; + } else { + processor = skip_variable; + /* If discarding APP0/APP14, use our regular on-the-fly processor. */ + if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14) + processor = get_interesting_appn; + } + + if (marker_code == (int) M_COM) { + marker->process_COM = processor; + marker->length_limit_COM = length_limit; + } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) { + marker->process_APPn[marker_code - (int) M_APP0] = processor; + marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit; + } else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} + +#endif /* SAVE_MARKERS_SUPPORTED */ + + +/* + * Install a special processing method for COM or APPn markers. + */ + +GLOBAL(void) +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine) +{ + my_marker_ptr marker = (my_marker_ptr) cinfo->marker; + + if (marker_code == (int) M_COM) + marker->process_COM = routine; + else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) + marker->process_APPn[marker_code - (int) M_APP0] = routine; + else + ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); +} diff --git a/src/dep/src/irrlicht/jpeglib/jdmaster.c b/src/dep/src/irrlicht/jpeglib/jdmaster.c new file mode 100644 index 0000000..eda4b3f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdmaster.c @@ -0,0 +1,557 @@ +/* + * jdmaster.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains master control logic for the JPEG decompressor. + * These routines are concerned with selecting the modules to be executed + * and with determining the number of passes and the work to be done in each + * pass. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private state */ + +typedef struct { + struct jpeg_decomp_master pub; /* public fields */ + + int pass_number; /* # of passes completed */ + + boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ + + /* Saved references to initialized quantizer modules, + * in case we need to switch modes. + */ + struct jpeg_color_quantizer * quantizer_1pass; + struct jpeg_color_quantizer * quantizer_2pass; +} my_decomp_master; + +typedef my_decomp_master * my_master_ptr; + + +/* + * Determine whether merged upsample/color conversion should be used. + * CRUCIAL: this must match the actual capabilities of jdmerge.c! + */ + +LOCAL(boolean) +use_merged_upsample (j_decompress_ptr cinfo) +{ +#ifdef UPSAMPLE_MERGING_SUPPORTED + /* Merging is the equivalent of plain box-filter upsampling */ + if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) + return FALSE; + /* jdmerge.c only supports YCC=>RGB color conversion */ + if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || + cinfo->out_color_space != JCS_RGB || + cinfo->out_color_components != RGB_PIXELSIZE) + return FALSE; + /* and it only handles 2h1v or 2h2v sampling ratios */ + if (cinfo->comp_info[0].h_samp_factor != 2 || + cinfo->comp_info[1].h_samp_factor != 1 || + cinfo->comp_info[2].h_samp_factor != 1 || + cinfo->comp_info[0].v_samp_factor > 2 || + cinfo->comp_info[1].v_samp_factor != 1 || + cinfo->comp_info[2].v_samp_factor != 1) + return FALSE; + /* furthermore, it doesn't work if we've scaled the IDCTs differently */ + if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || + cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) + return FALSE; + /* ??? also need to test for upsample-time rescaling, when & if supported */ + return TRUE; /* by golly, it'll work... */ +#else + return FALSE; +#endif +} + + +/* + * Compute output image dimensions and related values. + * NOTE: this is exported for possible use by application. + * Hence it mustn't do anything that can't be done twice. + * Also note that it may be called before the master module is initialized! + */ + +GLOBAL(void) +jpeg_calc_output_dimensions (j_decompress_ptr cinfo) +/* Do computations that are needed before master selection phase */ +{ +#ifdef IDCT_SCALING_SUPPORTED + int ci; + jpeg_component_info *compptr; +#endif + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_READY) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + +#ifdef IDCT_SCALING_SUPPORTED + + /* Compute actual output image dimensions and DCT scaling choices. */ + if (cinfo->scale_num * 8 <= cinfo->scale_denom) { + /* Provide 1/8 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 8L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 8L); + cinfo->min_DCT_scaled_size = 1; + } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { + /* Provide 1/4 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 4L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 4L); + cinfo->min_DCT_scaled_size = 2; + } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { + /* Provide 1/2 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 2L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 2L); + cinfo->min_DCT_scaled_size = 4; + } else { + /* Provide 1/1 scaling */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + cinfo->min_DCT_scaled_size = DCTSIZE; + } + /* In selecting the actual DCT scaling for each component, we try to + * scale up the chroma components via IDCT scaling rather than upsampling. + * This saves time if the upsampler gets to use 1:1 scaling. + * Note this code assumes that the supported DCT scalings are powers of 2. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + int ssize = cinfo->min_DCT_scaled_size; + while (ssize < DCTSIZE && + (compptr->h_samp_factor * ssize * 2 <= + cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && + (compptr->v_samp_factor * ssize * 2 <= + cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { + ssize = ssize * 2; + } + compptr->DCT_scaled_size = ssize; + } + + /* Recompute downsampled dimensions of components; + * application needs to know these if using raw downsampled data. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Size in samples, after IDCT scaling */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * + (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * + (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + } + +#else /* !IDCT_SCALING_SUPPORTED */ + + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + * and has computed unscaled downsampled_width and downsampled_height. + */ + +#endif /* IDCT_SCALING_SUPPORTED */ + + /* Report number of components in selected colorspace. */ + /* Probably this should be in the color conversion module... */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + break; + case JCS_RGB: +#if RGB_PIXELSIZE != 3 + cinfo->out_color_components = RGB_PIXELSIZE; + break; +#endif /* else share code with YCbCr */ + case JCS_YCbCr: + cinfo->out_color_components = 3; + break; + case JCS_CMYK: + case JCS_YCCK: + cinfo->out_color_components = 4; + break; + default: /* else must be same colorspace as in file */ + cinfo->out_color_components = cinfo->num_components; + break; + } + cinfo->output_components = (cinfo->quantize_colors ? 1 : + cinfo->out_color_components); + + /* See if upsampler will want to emit more than one row at a time */ + if (use_merged_upsample(cinfo)) + cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; + else + cinfo->rec_outbuf_height = 1; +} + + +/* + * Several decompression processes need to range-limit values to the range + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range + * due to noise introduced by quantization, roundoff error, etc. These + * processes are inner loops and need to be as fast as possible. On most + * machines, particularly CPUs with pipelines or instruction prefetch, + * a (subscript-check-less) C table lookup + * x = sample_range_limit[x]; + * is faster than explicit tests + * if (x < 0) x = 0; + * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; + * These processes all use a common table prepared by the routine below. + * + * For most steps we can mathematically guarantee that the initial value + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + * limiting step (just after the IDCT), a wildly out-of-range value is + * possible if the input data is corrupt. To avoid any chance of indexing + * off the end of memory and getting a bad-pointer trap, we perform the + * post-IDCT limiting thus: + * x = range_limit[x & MASK]; + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + * samples. Under normal circumstances this is more than enough range and + * a correct output will be generated; with bogus input data the mask will + * cause wraparound, and we will safely generate a bogus-but-in-range output. + * For the post-IDCT step, we want to convert the data from signed to unsigned + * representation by adding CENTERJSAMPLE at the same time that we limit it. + * So the post-IDCT limiting table ends up looking like this: + * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + * 0,1,...,CENTERJSAMPLE-1 + * Negative inputs select values from the upper half of the table after + * masking. + * + * We can save some space by overlapping the start of the post-IDCT table + * with the simpler range limiting table. The post-IDCT table begins at + * sample_range_limit + CENTERJSAMPLE. + * + * Note that the table is allocated in near data space on PCs; it's small + * enough and used often enough to justify this. + */ + +LOCAL(void) +prepare_range_limit_table (j_decompress_ptr cinfo) +/* Allocate and fill in the sample_range_limit table */ +{ + JSAMPLE * table; + int i; + + table = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ + cinfo->sample_range_limit = table; + /* First segment of "simple" table: limit[x] = 0 for x < 0 */ + MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + /* Main part of "simple" table: limit[x] = x */ + for (i = 0; i <= MAXJSAMPLE; i++) + table[i] = (JSAMPLE) i; + table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ + /* End of simple table, rest of first half of post-IDCT table */ + for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) + table[i] = MAXJSAMPLE; + /* Second half of post-IDCT table */ + MEMZERO(table + (2 * (MAXJSAMPLE+1)), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), + cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); +} + + +/* + * Master selection of decompression modules. + * This is done once at jpeg_start_decompress time. We determine + * which modules will be used and give them appropriate initialization calls. + * We also initialize the decompressor input side to begin consuming data. + * + * Since jpeg_read_header has finished, we know what is in the SOF + * and (first) SOS markers. We also have all the application parameter + * settings. + */ + +LOCAL(void) +master_selection (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + boolean use_c_buffer; + long samplesperrow; + JDIMENSION jd_samplesperrow; + + /* Initialize dimensions and other stuff */ + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + /* Width of an output scanline must be representable as JDIMENSION. */ + samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; + jd_samplesperrow = (JDIMENSION) samplesperrow; + if ((long) jd_samplesperrow != samplesperrow) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + + /* Initialize my private state */ + master->pass_number = 0; + master->using_merged_upsample = use_merged_upsample(cinfo); + + /* Color quantizer selection */ + master->quantizer_1pass = NULL; + master->quantizer_2pass = NULL; + /* No mode changes if not using buffered-image mode. */ + if (! cinfo->quantize_colors || ! cinfo->buffered_image) { + cinfo->enable_1pass_quant = FALSE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + } + if (cinfo->quantize_colors) { + if (cinfo->raw_data_out) + ERREXIT(cinfo, JERR_NOTIMPL); + /* 2-pass quantizer only works in 3-component color space. */ + if (cinfo->out_color_components != 3) { + cinfo->enable_1pass_quant = TRUE; + cinfo->enable_external_quant = FALSE; + cinfo->enable_2pass_quant = FALSE; + cinfo->colormap = NULL; + } else if (cinfo->colormap != NULL) { + cinfo->enable_external_quant = TRUE; + } else if (cinfo->two_pass_quantize) { + cinfo->enable_2pass_quant = TRUE; + } else { + cinfo->enable_1pass_quant = TRUE; + } + + if (cinfo->enable_1pass_quant) { +#ifdef QUANT_1PASS_SUPPORTED + jinit_1pass_quantizer(cinfo); + master->quantizer_1pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + + /* We use the 2-pass code to map to external colormaps. */ + if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { +#ifdef QUANT_2PASS_SUPPORTED + jinit_2pass_quantizer(cinfo); + master->quantizer_2pass = cinfo->cquantize; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } + /* If both quantizers are initialized, the 2-pass one is left active; + * this is necessary for starting with quantization to an external map. + */ + } + + /* Post-processing: in particular, color conversion first */ + if (! cinfo->raw_data_out) { + if (master->using_merged_upsample) { +#ifdef UPSAMPLE_MERGING_SUPPORTED + jinit_merged_upsampler(cinfo); /* does color conversion too */ +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + } + jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); + } + /* Inverse DCT */ + jinit_inverse_dct(cinfo); + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Initialize principal buffer controllers. */ + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (! cinfo->raw_data_out) + jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* If jpeg_start_decompress will read the whole file, initialize + * progress monitoring appropriately. The input step is counted + * as one pass. + */ + if (cinfo->progress != NULL && ! cinfo->buffered_image && + cinfo->inputctl->has_multiple_scans) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); + /* Count the input pass as done */ + master->pass_number++; + } +#endif /* D_MULTISCAN_FILES_SUPPORTED */ +} + + +/* + * Per-pass setup. + * This is called at the beginning of each output pass. We determine which + * modules will be active during this pass and give them appropriate + * start_pass calls. We also set is_dummy_pass to indicate whether this + * is a "real" output pass or a dummy pass for color quantization. + * (In the latter case, jdapistd.c will crank the pass to completion.) + */ + +METHODDEF(void) +prepare_for_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (master->pub.is_dummy_pass) { +#ifdef QUANT_2PASS_SUPPORTED + /* Final pass of 2-pass quantization */ + master->pub.is_dummy_pass = FALSE; + (*cinfo->cquantize->start_pass) (cinfo, FALSE); + (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); + (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + if (cinfo->quantize_colors && cinfo->colormap == NULL) { + /* Select new quantization method */ + if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { + cinfo->cquantize = master->quantizer_2pass; + master->pub.is_dummy_pass = TRUE; + } else if (cinfo->enable_1pass_quant) { + cinfo->cquantize = master->quantizer_1pass; + } else { + ERREXIT(cinfo, JERR_MODE_CHANGE); + } + } + (*cinfo->idct->start_pass) (cinfo); + (*cinfo->coef->start_output_pass) (cinfo); + if (! cinfo->raw_data_out) { + if (! master->using_merged_upsample) + (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->upsample->start_pass) (cinfo); + if (cinfo->quantize_colors) + (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); + (*cinfo->post->start_pass) (cinfo, + (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); + } + } + + /* Set up progress monitor's pass info if present */ + if (cinfo->progress != NULL) { + cinfo->progress->completed_passes = master->pass_number; + cinfo->progress->total_passes = master->pass_number + + (master->pub.is_dummy_pass ? 2 : 1); + /* In buffered-image mode, we assume one more output pass if EOI not + * yet reached, but no more passes if EOI has been reached. + */ + if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { + cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); + } + } +} + + +/* + * Finish up at end of an output pass. + */ + +METHODDEF(void) +finish_output_pass (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + if (cinfo->quantize_colors) + (*cinfo->cquantize->finish_pass) (cinfo); + master->pass_number++; +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Switch to a new external colormap between output passes. + */ + +GLOBAL(void) +jpeg_new_colormap (j_decompress_ptr cinfo) +{ + my_master_ptr master = (my_master_ptr) cinfo->master; + + /* Prevent application from calling me at wrong times */ + if (cinfo->global_state != DSTATE_BUFIMAGE) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + if (cinfo->quantize_colors && cinfo->enable_external_quant && + cinfo->colormap != NULL) { + /* Select 2-pass quantizer for external colormap use */ + cinfo->cquantize = master->quantizer_2pass; + /* Notify quantizer of colormap change */ + (*cinfo->cquantize->new_color_map) (cinfo); + master->pub.is_dummy_pass = FALSE; /* just in case */ + } else + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize master decompression control and select active modules. + * This is performed at the start of jpeg_start_decompress. + */ + +GLOBAL(void) +jinit_master_decompress (j_decompress_ptr cinfo) +{ + my_master_ptr master; + + master = (my_master_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_decomp_master)); + cinfo->master = (struct jpeg_decomp_master *) master; + master->pub.prepare_for_output_pass = prepare_for_output_pass; + master->pub.finish_output_pass = finish_output_pass; + + master->pub.is_dummy_pass = FALSE; + + master_selection(cinfo); +} diff --git a/src/dep/src/irrlicht/jpeglib/jdmerge.c b/src/dep/src/irrlicht/jpeglib/jdmerge.c new file mode 100644 index 0000000..9e3a595 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdmerge.c @@ -0,0 +1,400 @@ +/* + * jdmerge.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains code for merged upsampling/color conversion. + * + * This file combines functions from jdsample.c and jdcolor.c; + * read those files first to understand what's going on. + * + * When the chroma components are to be upsampled by simple replication + * (ie, box filtering), we can save some work in color conversion by + * calculating all the output pixels corresponding to a pair of chroma + * samples at one time. In the conversion equations + * R = Y + K1 * Cr + * G = Y + K2 * Cb + K3 * Cr + * B = Y + K4 * Cb + * only the Y term varies among the group of pixels corresponding to a pair + * of chroma samples, so the rest of the terms can be calculated just once. + * At typical sampling ratios, this eliminates half or three-quarters of the + * multiplications needed for color conversion. + * + * This file currently provides implementations for the following cases: + * YCbCr => RGB color conversion only. + * Sampling ratios of 2h1v or 2h2v. + * No scaling needed at upsample time. + * Corner-aligned (non-CCIR601) sampling alignment. + * Other special cases could be added, but in most applications these are + * the only common cases. (For uncommon cases we fall back on the more + * general code in jdsample.c and jdcolor.c.) + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef UPSAMPLE_MERGING_SUPPORTED + + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Pointer to routine to do actual upsampling/conversion of one row group */ + JMETHOD(void, upmethod, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf)); + + /* Private state for YCC->RGB conversion */ + int * Cr_r_tab; /* => table for Cr to R conversion */ + int * Cb_b_tab; /* => table for Cb to B conversion */ + INT32 * Cr_g_tab; /* => table for Cr to G conversion */ + INT32 * Cb_g_tab; /* => table for Cb to G conversion */ + + /* For 2:1 vertical sampling, we produce two output rows at a time. + * We need a "spare" row buffer to hold the second output row if the + * application provides just a one-row buffer; we also use the spare + * to discard the dummy last row if the image height is odd. + */ + JSAMPROW spare_row; + boolean spare_full; /* T if spare buffer is occupied */ + + JDIMENSION out_row_width; /* samples per output row */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + +#define SCALEBITS 16 /* speediest right-shift on some machines */ +#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) +#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. + * This is taken directly from jdcolor.c; see that file for more info. + */ + +LOCAL(void) +build_ycc_rgb_table (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int i; + INT32 x; + SHIFT_TEMPS + + upsample->Cr_r_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cb_b_tab = (int *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)); + upsample->Cr_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + upsample->Cb_g_tab = (INT32 *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)); + + for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { + /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ + /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + /* Cr=>R value is nearest int to 1.40200 * x */ + upsample->Cr_r_tab[i] = (int) + RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); + /* Cb=>B value is nearest int to 1.77200 * x */ + upsample->Cb_b_tab[i] = (int) + RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); + /* Cr=>G value is scaled-up -0.71414 * x */ + upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x; + /* Cb=>G value is scaled-up -0.34414 * x */ + /* We also add in ONE_HALF so that need not do it in inner loop */ + upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; + } +} + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_merged_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the spare buffer empty */ + upsample->spare_full = FALSE; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * The control routine just handles the row buffering considerations. + */ + +METHODDEF(void) +merged_2v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 2:1 vertical sampling case: may need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPROW work_ptrs[2]; + JDIMENSION num_rows; /* number of rows returned to caller */ + + if (upsample->spare_full) { + /* If we have a spare row saved from a previous cycle, just return it. */ + jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, + 1, upsample->out_row_width); + num_rows = 1; + upsample->spare_full = FALSE; + } else { + /* Figure number of rows to return to caller. */ + num_rows = 2; + /* Not more than the distance to the end of the image. */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + /* Create output pointer array for upsampler. */ + work_ptrs[0] = output_buf[*out_row_ctr]; + if (num_rows > 1) { + work_ptrs[1] = output_buf[*out_row_ctr + 1]; + } else { + work_ptrs[1] = upsample->spare_row; + upsample->spare_full = TRUE; + } + /* Now do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); + } + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (! upsample->spare_full) + (*in_row_group_ctr)++; +} + + +METHODDEF(void) +merged_1v_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +/* 1:1 vertical sampling case: much easier, never need a spare row. */ +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Just do the upsampling. */ + (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, + output_buf + *out_row_ctr); + /* Adjust counts */ + (*out_row_ctr)++; + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by the control routines to do + * the actual upsampling/conversion. One row group is processed per call. + * + * Note: since we may be writing directly into application-supplied buffers, + * we have to be honest about the output width; we can't assume the buffer + * has been rounded up to an even width. + */ + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. + */ + +METHODDEF(void) +h2v1_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr0 = input_buf[0][in_row_group_ctr]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr = output_buf[0]; + /* Loop for each pair of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 2 Y values and emit 2 pixels */ + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr0++); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr0); + outptr[RGB_RED] = range_limit[y + cred]; + outptr[RGB_GREEN] = range_limit[y + cgreen]; + outptr[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. + */ + +METHODDEF(void) +h2v2_merged_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, + JSAMPARRAY output_buf) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + register int y, cred, cgreen, cblue; + int cb, cr; + register JSAMPROW outptr0, outptr1; + JSAMPROW inptr00, inptr01, inptr1, inptr2; + JDIMENSION col; + /* copy these pointers into registers if possible */ + register JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = upsample->Cr_r_tab; + int * Cbbtab = upsample->Cb_b_tab; + INT32 * Crgtab = upsample->Cr_g_tab; + INT32 * Cbgtab = upsample->Cb_g_tab; + SHIFT_TEMPS + + inptr00 = input_buf[0][in_row_group_ctr*2]; + inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; + inptr1 = input_buf[1][in_row_group_ctr]; + inptr2 = input_buf[2][in_row_group_ctr]; + outptr0 = output_buf[0]; + outptr1 = output_buf[1]; + /* Loop for each group of output pixels */ + for (col = cinfo->output_width >> 1; col > 0; col--) { + /* Do the chroma part of the calculation */ + cb = GETJSAMPLE(*inptr1++); + cr = GETJSAMPLE(*inptr2++); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + /* Fetch 4 Y values and emit 4 pixels */ + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr00++); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + outptr0 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + y = GETJSAMPLE(*inptr01++); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + outptr1 += RGB_PIXELSIZE; + } + /* If image width is odd, do the last output column separately */ + if (cinfo->output_width & 1) { + cb = GETJSAMPLE(*inptr1); + cr = GETJSAMPLE(*inptr2); + cred = Crrtab[cr]; + cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); + cblue = Cbbtab[cb]; + y = GETJSAMPLE(*inptr00); + outptr0[RGB_RED] = range_limit[y + cred]; + outptr0[RGB_GREEN] = range_limit[y + cgreen]; + outptr0[RGB_BLUE] = range_limit[y + cblue]; + y = GETJSAMPLE(*inptr01); + outptr1[RGB_RED] = range_limit[y + cred]; + outptr1[RGB_GREEN] = range_limit[y + cgreen]; + outptr1[RGB_BLUE] = range_limit[y + cblue]; + } +} + + +/* + * Module initialization routine for merged upsampling/color conversion. + * + * NB: this is called under the conditions determined by use_merged_upsample() + * in jdmaster.c. That routine MUST correspond to the actual capabilities + * of this module; no safety checks are made here. + */ + +GLOBAL(void) +jinit_merged_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_merged_upsample; + upsample->pub.need_context_rows = FALSE; + + upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; + + if (cinfo->max_v_samp_factor == 2) { + upsample->pub.upsample = merged_2v_upsample; + upsample->upmethod = h2v2_merged_upsample; + /* Allocate a spare row buffer */ + upsample->spare_row = (JSAMPROW) + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); + } else { + upsample->pub.upsample = merged_1v_upsample; + upsample->upmethod = h2v1_merged_upsample; + /* No spare row needed */ + upsample->spare_row = NULL; + } + + build_ycc_rgb_table(cinfo); +} + +#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jdphuff.c b/src/dep/src/irrlicht/jpeglib/jdphuff.c new file mode 100644 index 0000000..2404743 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdphuff.c @@ -0,0 +1,668 @@ +/* + * jdphuff.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for progressive JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdhuff.h" /* Declarations shared with jdhuff.c */ + + +#ifdef D_PROGRESSIVE_SUPPORTED + +/* + * Expanded entropy decoder object for progressive Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).EOBRUN = (src).EOBRUN, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + struct jpeg_entropy_decoder pub; /* public fields */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + bitread_perm_state bitstate; /* Bit buffer at start of MCU */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ +} phuff_entropy_decoder; + +typedef phuff_entropy_decoder * phuff_entropy_ptr; + +/* Forward declarations */ +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + boolean is_DC_band, bad; + int ci, coefi, tbl; + int *coef_bit_ptr; + jpeg_component_info * compptr; + + is_DC_band = (cinfo->Ss == 0); + + /* Validate scan parameters */ + bad = FALSE; + if (is_DC_band) { + if (cinfo->Se != 0) + bad = TRUE; + } else { + /* need not check Ss/Se < 0 since they came from unsigned bytes */ + if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) + bad = TRUE; + /* AC scans may have only one component */ + if (cinfo->comps_in_scan != 1) + bad = TRUE; + } + if (cinfo->Ah != 0) { + /* Successive approximation refinement scan: must have Al = Ah-1. */ + if (cinfo->Al != cinfo->Ah-1) + bad = TRUE; + } + if (cinfo->Al > 13) /* need not check for < 0 */ + bad = TRUE; + /* Arguably the maximum Al value should be less than 13 for 8-bit precision, + * but the spec doesn't say so, and we try to be liberal about what we + * accept. Note: large Al values could result in out-of-range DC + * coefficients during early scans, leading to bizarre displays due to + * overflows in the IDCT math. But we won't crash. + */ + if (bad) + ERREXIT4(cinfo, JERR_BAD_PROGRESSION, + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + /* Update progression status, and verify that scan order is legal. + * Note that inter-scan inconsistencies are treated as warnings + * not fatal errors ... not clear if this is right way to behave. + */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + int cindex = cinfo->cur_comp_info[ci]->component_index; + coef_bit_ptr = & cinfo->coef_bits[cindex][0]; + if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { + int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; + if (cinfo->Ah != expected) + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr[coefi] = cinfo->Al; + } + } + + /* Select MCU decoding routine */ + if (cinfo->Ah == 0) { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_first; + else + entropy->pub.decode_mcu = decode_mcu_AC_first; + } else { + if (is_DC_band) + entropy->pub.decode_mcu = decode_mcu_DC_refine; + else + entropy->pub.decode_mcu = decode_mcu_AC_refine; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* Make sure requested tables are present, and compute derived tables. + * We may build same derived table more than once, but it's not expensive. + */ + if (is_DC_band) { + if (cinfo->Ah == 0) { /* DC refinement needs no table */ + tbl = compptr->dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + & entropy->derived_tbls[tbl]); + } + } else { + tbl = compptr->ac_tbl_no; + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, + & entropy->derived_tbls[tbl]); + /* remember the single active table */ + entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->pub.insufficient_data = FALSE; + + /* Initialize private state variables */ + entropy->saved.EOBRUN = 0; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Re-init EOB run count, too */ + entropy->saved.EOBRUN = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->pub.insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Huffman MCU decoding. + * Each of these routines decodes and returns one MCU's worth of + * Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + * + * We return FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * spectral selection, since we'll just re-assign them on the next call. + * Successive approximation AC refinement has to be more careful, however.) + */ + +/* + * MCU decoding for DC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Al = cinfo->Al; + register int s, r; + int blkn, ci; + JBLOCKROW block; + BITREAD_STATE_VARS; + savable_state state; + d_derived_tbl * tbl; + jpeg_component_info * compptr; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + tbl = entropy->derived_tbls[compptr->dc_tbl_no]; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, tbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + /* Convert DC difference to actual value, update last_dc_val */ + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ + (*block)[0] = (JCOEF) (s << Al); + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC initial scan (either spectral selection, + * or first pass of successive approximation). + */ + +METHODDEF(boolean) +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int Al = cinfo->Al; + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state. + * We can avoid loading/saving bitread state if in an EOB run. + */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ + else { + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + for (k = cinfo->Ss; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } + } + } + + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + } + + /* Completed MCU, so update state */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for DC successive approximation refinement scan. + * Note: we assume such scans can be multi-component, although the spec + * is not very clear on the point. + */ + +METHODDEF(boolean) +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int blkn; + JBLOCKROW block; + BITREAD_STATE_VARS; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* Not worth the cycles to check insufficient_data here, + * since we will not change the data anyway if we read zeroes. + */ + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + block = MCU_data[blkn]; + + /* Encoded data is simply the next bit of the two's-complement DC value */ + CHECK_BIT_BUFFER(br_state, 1, return FALSE); + if (GET_BITS(1)) + (*block)[0] |= p1; + /* Note: since we use |=, repeating the assignment later is safe */ + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * MCU decoding for AC successive approximation refinement scan. + */ + +METHODDEF(boolean) +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + int Se = cinfo->Se; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ + register int s, k, r; + unsigned int EOBRUN; + JBLOCKROW block; + JCOEFPTR thiscoef; + BITREAD_STATE_VARS; + d_derived_tbl * tbl; + int num_newnz; + int newnz_pos[DCTSIZE2]; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, don't modify the MCU. + */ + if (! entropy->pub.insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + + /* There is always only one block per MCU */ + block = MCU_data[0]; + tbl = entropy->ac_derived_tbl; + + /* If we are forced to suspend, we must undo the assignments to any newly + * nonzero coefficients in the block, because otherwise we'd get confused + * next time about which coefficients were already nonzero. + * But we need not undo addition of bits to already-nonzero coefficients; + * instead, we can test the current bit to see if we already did it. + */ + num_newnz = 0; + + /* initialize coefficient loop counter to start of band */ + k = cinfo->Ss; + + if (EOBRUN == 0) { + for (; k <= Se; k++) { + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ + } + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; + } + } + } + + if (EOBRUN > 0) { + /* Scan any remaining coefficient positions after the end-of-band + * (the last newly nonzero coefficient, if any). Append a correction + * bit to each already-nonzero coefficient. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + for (; k <= Se; k++) { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } + } + /* Count one block completed in EOB run */ + EOBRUN--; + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; + +undoit: + /* Re-zero any output coefficients that we made newly nonzero */ + while (num_newnz > 0) + (*block)[newnz_pos[--num_newnz]] = 0; + + return FALSE; +} + + +/* + * Module initialization routine for progressive Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_phuff_decoder (j_decompress_ptr cinfo) +{ + phuff_entropy_ptr entropy; + int *coef_bit_ptr; + int ci, i; + + entropy = (phuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)); + cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; + entropy->pub.start_pass = start_pass_phuff_decoder; + + /* Mark derived tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + } + + /* Create progression status table */ + cinfo->coef_bits = (int (*)[DCTSIZE2]) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components*DCTSIZE2*SIZEOF(int)); + coef_bit_ptr = & cinfo->coef_bits[0][0]; + for (ci = 0; ci < cinfo->num_components; ci++) + for (i = 0; i < DCTSIZE2; i++) + *coef_bit_ptr++ = -1; +} + +#endif /* D_PROGRESSIVE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jdpostct.c b/src/dep/src/irrlicht/jpeglib/jdpostct.c new file mode 100644 index 0000000..7ba9eed --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdpostct.c @@ -0,0 +1,290 @@ +/* + * jdpostct.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the decompression postprocessing controller. + * This controller manages the upsampling, color conversion, and color + * quantization/reduction steps; specifically, it controls the buffering + * between upsample/color conversion and color quantization/reduction. + * + * If no color quantization/reduction is required, then this module has no + * work to do, and it just hands off to the upsample/color conversion code. + * An integrated upsample/convert/quantize process would replace this module + * entirely. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Private buffer controller object */ + +typedef struct { + struct jpeg_d_post_controller pub; /* public fields */ + + /* Color quantization source buffer: this holds output data from + * the upsample/color conversion step to be passed to the quantizer. + * For two-pass color quantization, we need a full-image buffer; + * for one-pass operation, a strip buffer is sufficient. + */ + jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ + JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ + JDIMENSION strip_height; /* buffer size in rows */ + /* for two-pass mode only: */ + JDIMENSION starting_row; /* row # of first row in current strip */ + JDIMENSION next_row; /* index of next row to fill/empty in strip */ +} my_post_controller; + +typedef my_post_controller * my_post_ptr; + + +/* Forward declarations */ +METHODDEF(void) post_process_1pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#ifdef QUANT_2PASS_SUPPORTED +METHODDEF(void) post_process_prepass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +METHODDEF(void) post_process_2pass + JPP((j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +#endif + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (cinfo->quantize_colors) { + /* Single-pass processing with color quantization. */ + post->pub.post_process_data = post_process_1pass; + /* We could be doing buffered-image output before starting a 2-pass + * color quantization; in that case, jinit_d_post_controller did not + * allocate a strip buffer. Use the virtual-array buffer as workspace. + */ + if (post->buffer == NULL) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + (JDIMENSION) 0, post->strip_height, TRUE); + } + } else { + /* For single-pass processing without color quantization, + * I have no work to do; just call the upsampler directly. + */ + post->pub.post_process_data = cinfo->upsample->upsample; + } + break; +#ifdef QUANT_2PASS_SUPPORTED + case JBUF_SAVE_AND_PASS: + /* First pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_prepass; + break; + case JBUF_CRANK_DEST: + /* Second pass of 2-pass quantization */ + if (post->whole_image == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + post->pub.post_process_data = post_process_2pass; + break; +#endif /* QUANT_2PASS_SUPPORTED */ + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } + post->starting_row = post->next_row = 0; +} + + +/* + * Process some data in the one-pass (strip buffer) case. + * This is used for color precision reduction as well as one-pass quantization. + */ + +METHODDEF(void) +post_process_1pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Fill the buffer, but not more than what we can dump out in one go. */ + /* Note we rely on the upsampler to detect bottom of image. */ + max_rows = out_rows_avail - *out_row_ctr; + if (max_rows > post->strip_height) + max_rows = post->strip_height; + num_rows = 0; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &num_rows, max_rows); + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer, output_buf + *out_row_ctr, (int) num_rows); + *out_row_ctr += num_rows; +} + + +#ifdef QUANT_2PASS_SUPPORTED + +/* + * Process some data in the first pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_prepass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION old_next_row, num_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, TRUE); + } + + /* Upsample some data (up to a strip height's worth). */ + old_next_row = post->next_row; + (*cinfo->upsample->upsample) (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post->buffer, &post->next_row, post->strip_height); + + /* Allow quantizer to scan new data. No data is emitted, */ + /* but we advance out_row_ctr so outer loop can tell when we're done. */ + if (post->next_row > old_next_row) { + num_rows = post->next_row - old_next_row; + (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, + (JSAMPARRAY) NULL, (int) num_rows); + *out_row_ctr += num_rows; + } + + /* Advance if we filled the strip. */ + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + + +/* + * Process some data in the second pass of 2-pass quantization. + */ + +METHODDEF(void) +post_process_2pass (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_post_ptr post = (my_post_ptr) cinfo->post; + JDIMENSION num_rows, max_rows; + + /* Reposition virtual buffer if at start of strip. */ + if (post->next_row == 0) { + post->buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, post->whole_image, + post->starting_row, post->strip_height, FALSE); + } + + /* Determine number of rows to emit. */ + num_rows = post->strip_height - post->next_row; /* available in strip */ + max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ + if (num_rows > max_rows) + num_rows = max_rows; + /* We have to check bottom of image here, can't depend on upsampler. */ + max_rows = cinfo->output_height - post->starting_row; + if (num_rows > max_rows) + num_rows = max_rows; + + /* Quantize and emit data. */ + (*cinfo->cquantize->color_quantize) (cinfo, + post->buffer + post->next_row, output_buf + *out_row_ctr, + (int) num_rows); + *out_row_ctr += num_rows; + + /* Advance if we filled the strip. */ + post->next_row += num_rows; + if (post->next_row >= post->strip_height) { + post->starting_row += post->strip_height; + post->next_row = 0; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ + + +/* + * Initialize postprocessing controller. + */ + +GLOBAL(void) +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + my_post_ptr post; + + post = (my_post_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_post_controller)); + cinfo->post = (struct jpeg_d_post_controller *) post; + post->pub.start_pass = start_pass_dpost; + post->whole_image = NULL; /* flag for no virtual arrays */ + post->buffer = NULL; /* flag for no strip buffer */ + + /* Create the quantization buffer, if needed */ + if (cinfo->quantize_colors) { + /* The buffer strip height is max_v_samp_factor, which is typically + * an efficient number of rows for upsampling to return. + * (In the presence of output rescaling, we might want to be smarter?) + */ + post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; + if (need_full_buffer) { + /* Two-pass color quantization: need full-image storage. */ + /* We round up the number of rows to a multiple of the strip height. */ +#ifdef QUANT_2PASS_SUPPORTED + post->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + cinfo->output_width * cinfo->out_color_components, + (JDIMENSION) jround_up((long) cinfo->output_height, + (long) post->strip_height), + post->strip_height); +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif /* QUANT_2PASS_SUPPORTED */ + } else { + /* One-pass color quantization: just make a strip buffer. */ + post->buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->out_color_components, + post->strip_height); + } + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdsample.c b/src/dep/src/irrlicht/jpeglib/jdsample.c new file mode 100644 index 0000000..e0d9040 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdsample.c @@ -0,0 +1,478 @@ +/* + * jdsample.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains upsampling routines. + * + * Upsampling input data is counted in "row groups". A row group + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * sample rows of each component. Upsampling will normally produce + * max_v_samp_factor pixel rows from each row group (but this could vary + * if the upsampler is applying a scale factor of its own). + * + * An excellent reference for image resampling is + * Digital Image Warping, George Wolberg, 1990. + * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Pointer to routine to upsample a single component */ +typedef JMETHOD(void, upsample1_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); + +/* Private subobject */ + +typedef struct { + struct jpeg_upsampler pub; /* public fields */ + + /* Color conversion buffer. When using separate upsampling and color + * conversion steps, this buffer holds one upsampled row group until it + * has been color converted and output. + * Note: we do not allocate any storage for component(s) which are full-size, + * ie do not need rescaling. The corresponding entry of color_buf[] is + * simply set to point to the input data array, thereby avoiding copying. + */ + JSAMPARRAY color_buf[MAX_COMPONENTS]; + + /* Per-component upsampling method pointers */ + upsample1_ptr methods[MAX_COMPONENTS]; + + int next_row_out; /* counts rows emitted from color_buf */ + JDIMENSION rows_to_go; /* counts rows remaining in image */ + + /* Height of an input row group for each component. */ + int rowgroup_height[MAX_COMPONENTS]; + + /* These arrays save pixel expansion factors so that int_expand need not + * recompute them each time. They are unused for other upsampling methods. + */ + UINT8 h_expand[MAX_COMPONENTS]; + UINT8 v_expand[MAX_COMPONENTS]; +} my_upsampler; + +typedef my_upsampler * my_upsample_ptr; + + +/* + * Initialize for an upsampling pass. + */ + +METHODDEF(void) +start_pass_upsample (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + + /* Mark the conversion buffer empty */ + upsample->next_row_out = cinfo->max_v_samp_factor; + /* Initialize total-height counter for detecting bottom of image */ + upsample->rows_to_go = cinfo->output_height; +} + + +/* + * Control routine to do upsampling (and color conversion). + * + * In this version we upsample each component independently. + * We upsample one row group into the conversion buffer, then apply + * color conversion a row at a time. + */ + +METHODDEF(void) +sep_upsample (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + int ci; + jpeg_component_info * compptr; + JDIMENSION num_rows; + + /* Fill the conversion buffer, if it's empty */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) { + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Invoke per-component upsample method. Notice we pass a POINTER + * to color_buf[ci], so that fullsize_upsample can change it. + */ + (*upsample->methods[ci]) (cinfo, compptr, + input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), + upsample->color_buf + ci); + } + upsample->next_row_out = 0; + } + + /* Color-convert and emit rows */ + + /* How many we have in the buffer: */ + num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); + /* Not more than the distance to the end of the image. Need this test + * in case the image height is not a multiple of max_v_samp_factor: + */ + if (num_rows > upsample->rows_to_go) + num_rows = upsample->rows_to_go; + /* And not more than what the client can accept: */ + out_rows_avail -= *out_row_ctr; + if (num_rows > out_rows_avail) + num_rows = out_rows_avail; + + (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, + (JDIMENSION) upsample->next_row_out, + output_buf + *out_row_ctr, + (int) num_rows); + + /* Adjust counts */ + *out_row_ctr += num_rows; + upsample->rows_to_go -= num_rows; + upsample->next_row_out += num_rows; + /* When the buffer is emptied, declare this input row group consumed */ + if (upsample->next_row_out >= cinfo->max_v_samp_factor) + (*in_row_group_ctr)++; +} + + +/* + * These are the routines invoked by sep_upsample to upsample pixel values + * of a single component. One row group is processed per call. + */ + + +/* + * For full-size components, we just make color_buf[ci] point at the + * input buffer, and thus avoid copying any data. Note that this is + * safe only because sep_upsample doesn't declare the input row group + * "consumed" until we are done color converting and emitting it. + */ + +METHODDEF(void) +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = input_data; +} + + +/* + * This is a no-op version used for "uninteresting" components. + * These components will not be referenced by color conversion. + */ + +METHODDEF(void) +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + *output_data_ptr = NULL; /* safety check */ +} + + +/* + * This version handles any integral sampling ratios. + * This is not used for typical JPEG files, so it need not be fast. + * Nor, for that matter, is it particularly accurate: the algorithm is + * simple replication of the input pixel onto the corresponding output + * pixels. The hi-falutin sampling literature refers to this as a + * "box filter". A box filter tends to introduce visible artifacts, + * so if you are actually going to use 3:1 or 4:1 sampling ratios + * you would be well advised to improve this code. + */ + +METHODDEF(void) +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + register int h; + JSAMPROW outend; + int h_expand, v_expand; + int inrow, outrow; + + h_expand = upsample->h_expand[compptr->component_index]; + v_expand = upsample->v_expand[compptr->component_index]; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + /* Generate one output row with proper horizontal expansion */ + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + for (h = h_expand; h > 0; h--) { + *outptr++ = invalue; + } + } + /* Generate any additional output rows by duplicating the first one */ + if (v_expand > 1) { + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo->output_width); + } + inrow++; + outrow += v_expand; + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + } +} + + +/* + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + * It's still a box filter. + */ + +METHODDEF(void) +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register JSAMPLE invalue; + JSAMPROW outend; + int inrow, outrow; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + inptr = input_data[inrow]; + outptr = output_data[outrow]; + outend = outptr + cinfo->output_width; + while (outptr < outend) { + invalue = *inptr++; /* don't need GETJSAMPLE() here */ + *outptr++ = invalue; + *outptr++ = invalue; + } + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo->output_width); + inrow++; + outrow += 2; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + * + * The upsampling algorithm is linear interpolation between pixel centers, + * also known as a "triangle filter". This is a good compromise between + * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + * of the way between input pixel centers. + * + * A note about the "bias" calculations: when rounding fractional values to + * integer, we do not want to always round 0.5 up to the next integer. + * If we did that, we'd introduce a noticeable bias towards larger values. + * Instead, this code is arranged so that 0.5 will be rounded up or down at + * alternate pixel locations (a simple ordered dither pattern). + */ + +METHODDEF(void) +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr, outptr; + register int invalue; + register JDIMENSION colctr; + int inrow; + + for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { + inptr = input_data[inrow]; + outptr = output_data[inrow]; + /* Special case for first column */ + invalue = GETJSAMPLE(*inptr++); + *outptr++ = (JSAMPLE) invalue; + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ + invalue = GETJSAMPLE(*inptr++) * 3; + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); + *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); + } + + /* Special case for last column */ + invalue = GETJSAMPLE(*inptr); + *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); + *outptr++ = (JSAMPLE) invalue; + } +} + + +/* + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + * Again a triangle filter; see comments for h2v1 case, above. + * + * It is OK for us to reference the adjacent input rows because we demanded + * context from the main buffer controller (see initialization code). + */ + +METHODDEF(void) +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) +{ + JSAMPARRAY output_data = *output_data_ptr; + register JSAMPROW inptr0, inptr1, outptr; +#if BITS_IN_JSAMPLE == 8 + register int thiscolsum, lastcolsum, nextcolsum; +#else + register INT32 thiscolsum, lastcolsum, nextcolsum; +#endif + register JDIMENSION colctr; + int inrow, outrow, v; + + inrow = outrow = 0; + while (outrow < cinfo->max_v_samp_factor) { + for (v = 0; v < 2; v++) { + /* inptr0 points to nearest input row, inptr1 points to next nearest */ + inptr0 = input_data[inrow]; + if (v == 0) /* next nearest is row above */ + inptr1 = input_data[inrow-1]; + else /* next nearest is row below */ + inptr1 = input_data[inrow+1]; + outptr = output_data[outrow++]; + + /* Special case for first column */ + thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + + for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { + /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ + /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ + nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); + lastcolsum = thiscolsum; thiscolsum = nextcolsum; + } + + /* Special case for last column */ + *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); + *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); + } + inrow++; + } +} + + +/* + * Module initialization routine for upsampling. + */ + +GLOBAL(void) +jinit_upsampler (j_decompress_ptr cinfo) +{ + my_upsample_ptr upsample; + int ci; + jpeg_component_info * compptr; + boolean need_buffer, do_fancy; + int h_in_group, v_in_group, h_out_group, v_out_group; + + upsample = (my_upsample_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_upsampler)); + cinfo->upsample = (struct jpeg_upsampler *) upsample; + upsample->pub.start_pass = start_pass_upsample; + upsample->pub.upsample = sep_upsample; + upsample->pub.need_context_rows = FALSE; /* until we find out differently */ + + if (cinfo->CCIR601_sampling) /* this isn't supported */ + ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); + + /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, + * so don't ask for it. + */ + do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + + /* Verify we can handle the sampling factors, select per-component methods, + * and create storage as needed. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Compute size of an "input group" after IDCT scaling. This many samples + * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. + */ + h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / + cinfo->min_DCT_scaled_size; + h_out_group = cinfo->max_h_samp_factor; + v_out_group = cinfo->max_v_samp_factor; + upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ + need_buffer = TRUE; + if (! compptr->component_needed) { + /* Don't bother to upsample an uninteresting component. */ + upsample->methods[ci] = noop_upsample; + need_buffer = FALSE; + } else if (h_in_group == h_out_group && v_in_group == v_out_group) { + /* Fullsize components can be processed without any work. */ + upsample->methods[ci] = fullsize_upsample; + need_buffer = FALSE; + } else if (h_in_group * 2 == h_out_group && + v_in_group == v_out_group) { + /* Special cases for 2h1v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) + upsample->methods[ci] = h2v1_fancy_upsample; + else + upsample->methods[ci] = h2v1_upsample; + } else if (h_in_group * 2 == h_out_group && + v_in_group * 2 == v_out_group) { + /* Special cases for 2h2v upsampling */ + if (do_fancy && compptr->downsampled_width > 2) { + upsample->methods[ci] = h2v2_fancy_upsample; + upsample->pub.need_context_rows = TRUE; + } else + upsample->methods[ci] = h2v2_upsample; + } else if ((h_out_group % h_in_group) == 0 && + (v_out_group % v_in_group) == 0) { + /* Generic integral-factors upsampling method */ + upsample->methods[ci] = int_upsample; + upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); + upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); + } else + ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) { + upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) cinfo->output_width, + (long) cinfo->max_h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); + } + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jdtrans.c b/src/dep/src/irrlicht/jpeglib/jdtrans.c new file mode 100644 index 0000000..12c193c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jdtrans.c @@ -0,0 +1,143 @@ +/* + * jdtrans.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains library routines for transcoding decompression, + * that is, reading raw DCT coefficient arrays from an input JPEG file. + * The routines in jdapimin.c will also be needed by a transcoder. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* Forward declarations */ +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo)); + + +/* + * Read the coefficient arrays from a JPEG file. + * jpeg_read_header must be completed before calling this. + * + * The entire image is read into a set of virtual coefficient-block arrays, + * one per component. The return value is a pointer to the array of + * virtual-array descriptors. These can be manipulated directly via the + * JPEG memory manager, or handed off to jpeg_write_coefficients(). + * To release the memory occupied by the virtual arrays, call + * jpeg_finish_decompress() when done with the data. + * + * An alternative usage is to simply obtain access to the coefficient arrays + * during a buffered-image-mode decompression operation. This is allowed + * after any jpeg_finish_output() call. The arrays can be accessed until + * jpeg_finish_decompress() is called. (Note that any call to the library + * may reposition the arrays, so don't rely on access_virt_barray() results + * to stay valid across library calls.) + * + * Returns NULL if suspended. This case need be checked only if + * a suspending data source is used. + */ + +GLOBAL(jvirt_barray_ptr *) +jpeg_read_coefficients (j_decompress_ptr cinfo) +{ + if (cinfo->global_state == DSTATE_READY) { + /* First call: initialize active modules */ + transdecode_master_selection(cinfo); + cinfo->global_state = DSTATE_RDCOEFS; + } + if (cinfo->global_state == DSTATE_RDCOEFS) { + /* Absorb whole file into the coef buffer */ + for (;;) { + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return NULL; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } + } + /* Set state so that jpeg_finish_decompress does the right thing */ + cinfo->global_state = DSTATE_STOPPING; + } + /* At this point we should be in state DSTATE_STOPPING if being used + * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + * to the coefficients during a full buffered-image-mode decompression. + */ + if ((cinfo->global_state == DSTATE_STOPPING || + cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { + return cinfo->coef->coef_arrays; + } + /* Oops, improper usage */ + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + return NULL; /* keep compiler happy */ +} + + +/* + * Master selection of decompression modules for transcoding. + * This substitutes for jdmaster.c's initialization of the full decompressor. + */ + +LOCAL(void) +transdecode_master_selection (j_decompress_ptr cinfo) +{ + /* This is effectively a buffered-image operation. */ + cinfo->buffered_image = TRUE; + + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); + } else { + if (cinfo->progressive_mode) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_huff_decoder(cinfo); + } + + /* Always get a full-image coefficient buffer. */ + jinit_d_coef_controller(cinfo, TRUE); + + /* We can now tell the memory manager to allocate virtual arrays. */ + (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); + + /* Initialize input side of decompressor to consume first scan. */ + (*cinfo->inputctl->start_input_pass) (cinfo); + + /* Initialize progress monitoring. */ + if (cinfo->progress != NULL) { + int nscans; + /* Estimate number of scans to set pass_limit. */ + if (cinfo->progressive_mode) { + /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ + nscans = 2 + 3 * cinfo->num_components; + } else if (cinfo->inputctl->has_multiple_scans) { + /* For a nonprogressive multiscan file, estimate 1 scan per component. */ + nscans = cinfo->num_components; + } else { + nscans = 1; + } + cinfo->progress->pass_counter = 0L; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; + cinfo->progress->completed_passes = 0; + cinfo->progress->total_passes = 1; + } +} diff --git a/src/dep/src/irrlicht/jpeglib/jerror.c b/src/dep/src/irrlicht/jpeglib/jerror.c new file mode 100644 index 0000000..c98aed7 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jerror.c @@ -0,0 +1,252 @@ +/* + * jerror.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains simple error-reporting and trace-message routines. + * These are suitable for Unix-like systems and others where writing to + * stderr is the right thing to do. Many applications will want to replace + * some or all of these routines. + * + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, + * you get a Windows-specific hack to display error messages in a dialog box. + * It ain't much, but it beats dropping error messages into the bit bucket, + * which is what happens to output to stderr under most Windows C compilers. + * + * These routines are used by both the compression and decompression code. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jversion.h" +#include "jerror.h" + +#ifdef USE_WINDOWS_MESSAGEBOX +#include +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif + + +/* + * Create the message string table. + * We do this from the master message list in jerror.h by re-reading + * jerror.h with a suitable definition for macro JMESSAGE. + * The message table is made an external symbol just in case any applications + * want to refer to it directly. + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_message_table jMsgTable +#endif + +#define JMESSAGE(code,string) string , + +const char * const jpeg_std_message_table[] = { +#include "jerror.h" + NULL +}; + + +/* + * Error exit handler: must not return to caller. + * + * Applications may override this if they want to get control back after + * an error. Typically one would longjmp somewhere instead of exiting. + * The setjmp buffer can be made a private field within an expanded error + * handler object. Note that the info needed to generate an error message + * is stored in the error object, so you can generate the message now or + * later, at your convenience. + * You should make sure that the JPEG object is cleaned up (with jpeg_abort + * or jpeg_destroy) at some point. + */ + +METHODDEF(void) +error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + exit(EXIT_FAILURE); +} + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +/* + * Fill in the standard error-handling methods in a jpeg_error_mgr object. + * Typical call is: + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; + * + * cinfo.err = jpeg_std_error(&err); + * after which the application may override some of the methods. + */ + +GLOBAL(struct jpeg_error_mgr *) +jpeg_std_error (struct jpeg_error_mgr * err) +{ + err->error_exit = error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/src/dep/src/irrlicht/jpeglib/jerror.h b/src/dep/src/irrlicht/jpeglib/jerror.h new file mode 100644 index 0000000..79084f2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/src/dep/src/irrlicht/jpeglib/jfdctflt.c b/src/dep/src/irrlicht/jpeglib/jfdctflt.c new file mode 100644 index 0000000..7ccfb38 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jfdctflt.c @@ -0,0 +1,168 @@ +/* + * jfdctflt.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * forward DCT (Discrete Cosine Transform). + * + * This implementation should be more accurate than either of the integer + * DCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_float (FAST_FLOAT * data) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; + FAST_FLOAT *dataptr; + int ctr; + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ + z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jfdctfst.c b/src/dep/src/irrlicht/jpeglib/jfdctfst.c new file mode 100644 index 0000000..005a74f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jfdctfst.c @@ -0,0 +1,224 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jfdctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * Again to save a few shifts, the intermediate results between pass 1 and + * pass 2 are not upscaled, but are represented only to integral precision. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#define CONST_BITS 8 + + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ +#else +#define FIX_0_382683433 FIX(0.382683433) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_707106781 FIX(0.707106781) +#define FIX_1_306562965 FIX(1.306562965) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_ifast (DCTELEM * data) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jfdctint.c b/src/dep/src/irrlicht/jpeglib/jfdctint.c new file mode 100644 index 0000000..d626927 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jfdctint.c @@ -0,0 +1,283 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (For 12-bit sample data, the intermediate + * array is INT32 anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +jpeg_fdct_islow (DCTELEM * data) +{ + INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true DCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); + dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jidctflt.c b/src/dep/src/irrlicht/jpeglib/jidctflt.c new file mode 100644 index 0000000..5fea54c --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jidctflt.c @@ -0,0 +1,242 @@ +/* + * jidctflt.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a floating-point implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * This implementation should be more accurate than either of the integer + * IDCT implementations. However, it may not give the same results on all + * machines because of differences in roundoff behavior. Speed will depend + * on the hardware's floating point capacity. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with a fixed-point + * implementation, accuracy is lost due to imprecise representation of the + * scaled quantization values. However, that problem does not arise if + * we use floating point arithmetic. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_FLOAT_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a float result. + */ + +#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FAST_FLOAT tmp10, tmp11, tmp12, tmp13; + FAST_FLOAT z5, z10, z11, z12, z13; + JCOEFPTR inptr; + FLOAT_MULT_TYPE * quantptr; + FAST_FLOAT * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = tmp0 + tmp7; + wsptr[DCTSIZE*7] = tmp0 - tmp7; + wsptr[DCTSIZE*1] = tmp1 + tmp6; + wsptr[DCTSIZE*6] = tmp1 - tmp6; + wsptr[DCTSIZE*2] = tmp2 + tmp5; + wsptr[DCTSIZE*5] = tmp2 - tmp5; + wsptr[DCTSIZE*4] = tmp3 + tmp4; + wsptr[DCTSIZE*3] = tmp3 - tmp4; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * And testing floats for zero is relatively expensive, so we don't bother. + */ + + /* Even part */ + + tmp10 = wsptr[0] + wsptr[4]; + tmp11 = wsptr[0] - wsptr[4]; + + tmp13 = wsptr[2] + wsptr[6]; + tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = wsptr[5] + wsptr[3]; + z10 = wsptr[5] - wsptr[3]; + z11 = wsptr[1] + wsptr[7]; + z12 = wsptr[1] - wsptr[7]; + + tmp7 = z11 + z13; + tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); + + z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ + tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ + tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jidctfst.c b/src/dep/src/irrlicht/jpeglib/jidctfst.c new file mode 100644 index 0000000..078b8c4 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jidctfst.c @@ -0,0 +1,368 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_IFAST_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jidctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * The dequantized coefficients are not integers because the AA&N scaling + * factors have been incorporated. We represent them scaled up by PASS1_BITS, + * so that the first and second IDCT rounds have the same input scaling. + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + * avoid a descaling shift; this compromises accuracy rather drastically + * for small quantization table entries, but it saves a lot of shifts. + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + * so we use a much larger scaling factor to preserve accuracy. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 8 +#define PASS1_BITS 2 +#else +#define CONST_BITS 8 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ +#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ +#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ +#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ +#else +#define FIX_1_082392200 FIX(1.082392200) +#define FIX_1_414213562 FIX(1.414213562) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_613125930 FIX(2.613125930) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + * multiplication will do. For 12-bit data, the multiplier table is + * declared INT32, so a 32-bit multiply will be used. + */ + +#if BITS_IN_JSAMPLE == 8 +#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) +#else +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +#endif + + +/* Like DESCALE, but applies to a DCTELEM and produces an int. + * We assume that int right shift is unsigned if INT32 right shift is. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define ISHIFT_TEMPS DCTELEM ishift_temp; +#if BITS_IN_JSAMPLE == 8 +#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ +#else +#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ +#endif +#define IRIGHT_SHIFT(x,shft) \ + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ + (ishift_temp >> (shft))) +#else +#define ISHIFT_TEMPS +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + +#ifdef USE_ACCURATE_ROUNDING +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n)) +#else +#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n)) +#endif + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + DCTELEM tmp10, tmp11, tmp12, tmp13; + DCTELEM z5, z10, z11, z12, z13; + JCOEFPTR inptr; + IFAST_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp11 = tmp0 - tmp2; + + tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ + + tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + + z13 = tmp6 + tmp5; /* phase 6 */ + z10 = tmp6 - tmp5; + z11 = tmp4 + tmp7; + z12 = tmp4 - tmp7; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); + wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); + wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); + wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); + wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); + wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); + wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); + wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); + tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); + + tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); + tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) + - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + /* Odd part */ + + z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; + z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; + z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; + z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; + + tmp7 = z11 + z13; /* phase 5 */ + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ + + tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + /* Final output stage: scale down by a factor of 8 and range-limit */ + + outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_IFAST_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jidctint.c b/src/dep/src/irrlicht/jpeglib/jidctint.c new file mode 100644 index 0000000..4f47fe8 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jidctint.c @@ -0,0 +1,389 @@ +/* + * jidctint.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time). Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + * larger than the true IDCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D IDCT, + * because the y0 and y4 inputs need not be divided by sqrt(N). + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (To scale up 12-bit sample data further, an + * intermediate INT32 array would be needed.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ + +GLOBAL(void) +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp1, tmp2, tmp3; + INT32 tmp10, tmp11, tmp12, tmp13; + INT32 z1, z2, z3, z4, z5; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; ctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any column in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * column DCT calculations can be simplified this way. + */ + + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { + /* AC terms all zero */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + wsptr[DCTSIZE*4] = dcval; + wsptr[DCTSIZE*5] = dcval; + wsptr[DCTSIZE*6] = dcval; + wsptr[DCTSIZE*7] = dcval; + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); + + tmp0 = (z2 + z3) << CONST_BITS; + tmp1 = (z2 - z3) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); + wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); + + inptr++; /* advance pointers to next column */ + quantptr++; + wsptr++; + } + + /* Pass 2: process rows from work array, store into output array. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + wsptr = workspace; + for (ctr = 0; ctr < DCTSIZE; ctr++) { + outptr = output_buf[ctr] + output_col; + /* Rows of zeroes can be exploited in the same way as we did with columns. + * However, the column calculation has created many nonzero AC terms, so + * the simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + outptr[4] = dcval; + outptr[5] = dcval; + outptr[6] = dcval; + outptr[7] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + + z2 = (INT32) wsptr[2]; + z3 = (INT32) wsptr[6]; + + z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS; + tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + tmp0 = (INT32) wsptr[7]; + tmp1 = (INT32) wsptr[5]; + tmp2 = (INT32) wsptr[3]; + tmp3 = (INT32) wsptr[1]; + + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + z4 = tmp1 + tmp3; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jidctred.c b/src/dep/src/irrlicht/jpeglib/jidctred.c new file mode 100644 index 0000000..911899b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jidctred.c @@ -0,0 +1,398 @@ +/* + * jidctred.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains inverse-DCT routines that produce reduced-size output: + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + * + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + * with an 8-to-4 step that produces the four averages of two adjacent outputs + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + * These steps were derived by computing the corresponding values at the end + * of the normal LL&M code, then simplifying as much as possible. + * + * 1x1 is trivial: just take the DC coefficient divided by 8. + * + * See jidctint.c for additional comments. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jdct.h" /* Private declarations for DCT subsystem */ + +#ifdef IDCT_SCALING_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling is the same as in jidctint.c. */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 2 +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ +#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ +#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ +#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ +#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ +#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ +#else +#define FIX_0_211164243 FIX(0.211164243) +#define FIX_0_509795579 FIX(0.509795579) +#define FIX_0_601344887 FIX(0.601344887) +#define FIX_0_720959822 FIX(0.720959822) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_850430095 FIX(0.850430095) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_061594337 FIX(1.061594337) +#define FIX_1_272758580 FIX(1.272758580) +#define FIX_1_451774981 FIX(1.451774981) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_2_172734803 FIX(2.172734803) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_624509785 FIX(3.624509785) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce an int result. In this module, both inputs and result + * are 16 bits or less, so either int or short multiply will work. + */ + +#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 4x4 output block. + */ + +GLOBAL(void) +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp2, tmp10, tmp12; + INT32 z1, z2, z3, z4; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*4]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process column 4, because second pass won't use it */ + if (ctr == DCTSIZE-4) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && + inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine term 4 for 4x4 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + wsptr[DCTSIZE*2] = dcval; + wsptr[DCTSIZE*3] = dcval; + + continue; + } + + /* Even part */ + + tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp0 <<= (CONST_BITS+1); + + z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); + z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); + + tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1); + wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1); + } + + /* Pass 2: process 4 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 4; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + outptr[2] = dcval; + outptr[3] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); + + tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) + + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); + + tmp10 = tmp0 + tmp2; + tmp12 = tmp0 - tmp2; + + /* Odd part */ + + z1 = (INT32) wsptr[7]; + z2 = (INT32) wsptr[5]; + z3 = (INT32) wsptr[3]; + z4 = (INT32) wsptr[1]; + + tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 2x2 output block. + */ + +GLOBAL(void) +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + INT32 tmp0, tmp10, z1; + JCOEFPTR inptr; + ISLOW_MULT_TYPE * quantptr; + int * wsptr; + JSAMPROW outptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + int ctr; + int workspace[DCTSIZE*2]; /* buffers data between passes */ + SHIFT_TEMPS + + /* Pass 1: process columns from input, store into work array. */ + + inptr = coef_block; + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + wsptr = workspace; + for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { + /* Don't bother to process columns 2,4,6 */ + if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) + continue; + if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { + /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ + int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; + + wsptr[DCTSIZE*0] = dcval; + wsptr[DCTSIZE*1] = dcval; + + continue; + } + + /* Even part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); + tmp10 = z1 << (CONST_BITS+2); + + /* Odd part */ + + z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); + tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); + tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); + tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */ + z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); + tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2); + wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2); + } + + /* Pass 2: process 2 rows from work array, store into output array. */ + + wsptr = workspace; + for (ctr = 0; ctr < 2; ctr++) { + outptr = output_buf[ctr] + output_col; + /* It's not clear whether a zero row test is worthwhile here ... */ + +#ifndef NO_ZERO_ROW_TEST + if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) { + /* AC terms all zero */ + JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) + & RANGE_MASK]; + + outptr[0] = dcval; + outptr[1] = dcval; + + wsptr += DCTSIZE; /* advance pointer to next row */ + continue; + } +#endif + + /* Even part */ + + tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2); + + /* Odd part */ + + tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ + + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ + + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + /* Final output stage */ + + outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; + + wsptr += DCTSIZE; /* advance pointer to next row */ + } +} + + +/* + * Perform dequantization and inverse DCT on one block of coefficients, + * producing a reduced-size 1x1 output block. + */ + +GLOBAL(void) +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) +{ + int dcval; + ISLOW_MULT_TYPE * quantptr; + JSAMPLE *range_limit = IDCT_range_limit(cinfo); + SHIFT_TEMPS + + /* We hardly need an inverse DCT routine for this: just take the + * average pixel value, which is one-eighth of the DC coefficient. + */ + quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; + dcval = DEQUANTIZE(coef_block[0], quantptr[0]); + dcval = (int) DESCALE((INT32) dcval, 3); + + output_buf[0][output_col] = range_limit[dcval & RANGE_MASK]; +} + +#endif /* IDCT_SCALING_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jinclude.h b/src/dep/src/irrlicht/jpeglib/jinclude.h new file mode 100644 index 0000000..5ff60fe --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jinclude.h @@ -0,0 +1,91 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include . + * Otherwise, we get them from or ; we may have to + * pull in as well. + * Note that the core JPEG library does not require ; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without . + */ + +#ifdef HAVE_STDDEF_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef NEED_SYS_TYPES_H +#include +#endif + +#include + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in . + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in . + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof(). However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long. To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object) ((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros. On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/src/dep/src/irrlicht/jpeglib/jmemansi.c b/src/dep/src/irrlicht/jpeglib/jmemansi.c new file mode 100644 index 0000000..b5da474 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemansi.c @@ -0,0 +1,167 @@ +/* + * jmemansi.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a simple generic implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that you have the ANSI-standard library routine tmpfile(). + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); + /* Since this implementation uses tmpfile() to create the file, + * no explicit file deletion is needed. + */ +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses tmpfile(), which constructs a suitable file name + * behind the scenes. We don't have to use info->temp_name[] at all; + * indeed, we can't even find out the actual name of the temp file. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + if ((info->temp_file = tmpfile()) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemdos.c b/src/dep/src/irrlicht/jpeglib/jmemdos.c new file mode 100644 index 0000000..0955047 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemdos.c @@ -0,0 +1,638 @@ +/* + * jmemdos.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides an MS-DOS-compatible implementation of the system- + * dependent portion of the JPEG memory manager. Temporary data can be + * stored in extended or expanded memory as well as in regular DOS files. + * + * If you use this file, you must be sure that NEED_FAR_POINTERS is defined + * if you compile in a small-data memory model; it should NOT be defined if + * you use a large-data memory model. This file is not recommended if you + * are using a flat-memory-space 386 environment such as DJGCC or Watcom C. + * Also, this code will NOT work if struct fields are aligned on greater than + * 2-byte boundaries. + * + * Based on code contributed by Ge' Weijers. + */ + +/* + * If you have both extended and expanded memory, you may want to change the + * order in which they are tried in jopen_backing_store. On a 286 machine + * expanded memory is usually faster, since extended memory access involves + * an expensive protected-mode-and-back switch. On 386 and better, extended + * memory is usually faster. As distributed, the code tries extended memory + * first (what? not everyone has a 386? :-). + * + * You can disable use of extended/expanded memory entirely by altering these + * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0). + */ + +#ifndef XMS_SUPPORTED +#define XMS_SUPPORTED 1 +#endif +#ifndef EMS_SUPPORTED +#define EMS_SUPPORTED 1 +#endif + + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare these */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +extern char * getenv JPP((const char * name)); +#endif + +#ifdef NEED_FAR_POINTERS + +#ifdef __TURBOC__ +/* These definitions work for Borland C (Turbo C) */ +#include /* need farmalloc(), farfree() */ +#define far_malloc(x) farmalloc(x) +#define far_free(x) farfree(x) +#else +/* These definitions work for Microsoft C and compatible compilers */ +#include /* need _fmalloc(), _ffree() */ +#define far_malloc(x) _fmalloc(x) +#define far_free(x) _ffree(x) +#endif + +#else /* not NEED_FAR_POINTERS */ + +#define far_malloc(x) malloc(x) +#define far_free(x) free(x) + +#endif /* NEED_FAR_POINTERS */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#else +#define READ_BINARY "rb" +#endif + +#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */ + You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */ +#endif + +#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ + MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ +#endif + + +/* + * Declarations for assembly-language support routines (see jmemdosa.asm). + * + * The functions are declared "far" as are all their pointer arguments; + * this ensures the assembly source code will work regardless of the + * compiler memory model. We assume "short" is 16 bits, "long" is 32. + */ + +typedef void far * XMSDRIVER; /* actually a pointer to code */ +typedef struct { /* registers for calling XMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } XMScontext; +typedef struct { /* registers for calling EMS driver */ + unsigned short ax, dx, bx; + void far * ds_si; + } EMScontext; + +extern short far jdos_open JPP((short far * handle, char far * filename)); +extern short far jdos_close JPP((short handle)); +extern short far jdos_seek JPP((short handle, long offset)); +extern short far jdos_read JPP((short handle, void far * buffer, + unsigned short count)); +extern short far jdos_write JPP((short handle, void far * buffer, + unsigned short count)); +extern void far jxms_getdriver JPP((XMSDRIVER far *)); +extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); +extern short far jems_available JPP((void)); +extern void far jems_calldriver JPP((EMScontext far *)); + + +/* + * Selection of a file name for a temporary file. + * This is highly system-dependent, and you may want to customize it. + */ + +static int next_file_num; /* to distinguish among several temp files */ + +LOCAL(void) +select_file_name (char * fname) +{ + const char * env; + char * ptr; + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + /* Get temp directory name from environment TMP or TEMP variable; + * if none, use "." + */ + if ((env = (const char *) getenv("TMP")) == NULL) + if ((env = (const char *) getenv("TEMP")) == NULL) + env = "."; + if (*env == '\0') /* null string means "." */ + env = "."; + ptr = fname; /* copy name to fname */ + while (*env != '\0') + *ptr++ = *env++; + if (ptr[-1] != '\\' && ptr[-1] != '/') + *ptr++ = '\\'; /* append backslash if not in env variable */ + /* Append a suitable file name */ + next_file_num++; /* advance counter */ + sprintf(ptr, "JPG%03d.TMP", next_file_num); + /* Probe to see if file name is already in use */ + if ((tfile = fopen(fname, READ_BINARY)) == NULL) + break; + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + + +/* + * Near-memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are allocated in far memory, if possible + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) far_malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + far_free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + +/* + * For MS-DOS we support three types of backing storage: + * 1. Conventional DOS files. We access these by direct DOS calls rather + * than via the stdio package. This provides a bit better performance, + * but the real reason is that the buffers to be read or written are FAR. + * The stdio library for small-data memory models can't cope with that. + * 2. Extended memory, accessed per the XMS V2.0 specification. + * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. + * You'll need copies of those specs to make sense of the related code. + * The specs are available by Internet FTP from the SIMTEL archives + * (oak.oakland.edu and its various mirror sites). See files + * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. + */ + + +/* + * Access methods for a DOS file. + */ + + +METHODDEF(void) +read_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_read(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_file_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (jdos_seek(info->handle.file_handle, file_offset)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ + if (byte_count > 65535L) /* safety check */ + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if (jdos_write(info->handle.file_handle, buffer_address, + (unsigned short) byte_count)) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_file_store (j_common_ptr cinfo, backing_store_ptr info) +{ + jdos_close(info->handle.file_handle); /* close the file */ + remove(info->temp_name); /* delete the file */ +/* If your system doesn't have remove(), try unlink() instead. + * remove() is the ANSI-standard name for this function, but + * unlink() was more common in pre-ANSI systems. + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +LOCAL(boolean) +open_file_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + short handle; + + select_file_name(info->temp_name); + if (jdos_open((short far *) & handle, (char far *) info->temp_name)) { + /* might as well exit since jpeg_open_backing_store will fail anyway */ + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + return FALSE; + } + info->handle.file_handle = handle; + info->read_backing_store = read_file_store; + info->write_backing_store = write_file_store; + info->close_backing_store = close_file_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); + return TRUE; /* succeeded */ +} + + +/* + * Access methods for extended memory. + */ + +#if XMS_SUPPORTED + +static XMSDRIVER xms_driver; /* saved address of XMS driver */ + +typedef union { /* either long offset or real-mode pointer */ + long offset; + void far * ptr; + } XMSPTR; + +typedef struct { /* XMS move specification structure */ + long length; + XMSH src_handle; + XMSPTR src; + XMSH dst_handle; + XMSPTR dst; + } XMSspec; + +#define ODD(X) (((X) & 1L) != 0) + + +METHODDEF(void) +read_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = info->handle.xms_handle; + spec.src.offset = file_offset; + spec.dst_handle = 0; + spec.dst.ptr = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_READ); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0]; + } +} + + +METHODDEF(void) +write_xms_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + XMScontext ctx; + XMSspec spec; + char endbuffer[2]; + + /* The XMS driver can't cope with an odd length, so handle the last byte + * specially if byte_count is odd. We don't expect this to be common. + */ + + spec.length = byte_count & (~ 1L); + spec.src_handle = 0; + spec.src.ptr = buffer_address; + spec.dst_handle = info->handle.xms_handle; + spec.dst.offset = file_offset; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x0b00; /* EMB move */ + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + ERREXIT(cinfo, JERR_XMS_WRITE); + + if (ODD(byte_count)) { + read_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L]; + write_xms_store(cinfo, info, (void FAR *) endbuffer, + file_offset + byte_count - 1L, 2L); + } +} + + +METHODDEF(void) +close_xms_store (j_common_ptr cinfo, backing_store_ptr info) +{ + XMScontext ctx; + + ctx.dx = info->handle.xms_handle; + ctx.ax = 0x0a00; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL(boolean) +open_xms_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + XMScontext ctx; + + /* Get address of XMS driver */ + jxms_getdriver((XMSDRIVER far *) & xms_driver); + if (xms_driver == NULL) + return FALSE; /* no driver to be had */ + + /* Get version number, must be >= 2.00 */ + ctx.ax = 0x0000; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax < (unsigned short) 0x0200) + return FALSE; + + /* Try to get space (expressed in kilobytes) */ + ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10); + ctx.ax = 0x0900; + jxms_calldriver(xms_driver, (XMScontext far *) & ctx); + if (ctx.ax != 1) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.xms_handle = ctx.dx; + info->read_backing_store = read_xms_store; + info->write_backing_store = write_xms_store; + info->close_backing_store = close_xms_store; + TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* XMS_SUPPORTED */ + + +/* + * Access methods for expanded memory. + */ + +#if EMS_SUPPORTED + +/* The EMS move specification structure requires word and long fields aligned + * at odd byte boundaries. Some compilers will align struct fields at even + * byte boundaries. While it's usually possible to force byte alignment, + * that causes an overall performance penalty and may pose problems in merging + * JPEG into a larger application. Instead we accept some rather dirty code + * here. Note this code would fail if the hardware did not allow odd-byte + * word & long accesses, but all 80x86 CPUs do. + */ + +typedef void far * EMSPTR; + +typedef union { /* EMS move specification structure */ + long length; /* It's easy to access first 4 bytes */ + char bytes[18]; /* Misaligned fields in here! */ + } EMSspec; + +/* Macros for accessing misaligned fields */ +#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset]))) +#define SRC_TYPE(spec) FIELD_AT(spec,4,char) +#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH) +#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short) +#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short) +#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR) +#define DST_TYPE(spec) FIELD_AT(spec,11,char) +#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH) +#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short) +#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short) +#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR) + +#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */ + +#define HIBYTE(W) (((W) >> 8) & 0xFF) +#define LOBYTE(W) ((W) & 0xFF) + + +METHODDEF(void) +read_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 1; + SRC_HANDLE(spec) = info->handle.ems_handle; + SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + DST_TYPE(spec) = 0; + DST_HANDLE(spec) = 0; + DST_PTR(spec) = buffer_address; + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_READ); +} + + +METHODDEF(void) +write_ems_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + EMScontext ctx; + EMSspec spec; + + spec.length = byte_count; + SRC_TYPE(spec) = 0; + SRC_HANDLE(spec) = 0; + SRC_PTR(spec) = buffer_address; + DST_TYPE(spec) = 1; + DST_HANDLE(spec) = info->handle.ems_handle; + DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); + DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); + + ctx.ds_si = (void far *) & spec; + ctx.ax = 0x5700; /* move memory region */ + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + ERREXIT(cinfo, JERR_EMS_WRITE); +} + + +METHODDEF(void) +close_ems_store (j_common_ptr cinfo, backing_store_ptr info) +{ + EMScontext ctx; + + ctx.ax = 0x4500; + ctx.dx = info->handle.ems_handle; + jems_calldriver((EMScontext far *) & ctx); + TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle); + /* we ignore any error return from the driver */ +} + + +LOCAL(boolean) +open_ems_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + EMScontext ctx; + + /* Is EMS driver there? */ + if (! jems_available()) + return FALSE; + + /* Get status, make sure EMS is OK */ + ctx.ax = 0x4000; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Get version, must be >= 4.0 */ + ctx.ax = 0x4600; + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40) + return FALSE; + + /* Try to allocate requested space */ + ctx.ax = 0x4300; + ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE); + jems_calldriver((EMScontext far *) & ctx); + if (HIBYTE(ctx.ax) != 0) + return FALSE; + + /* Succeeded, save the handle and away we go */ + info->handle.ems_handle = ctx.dx; + info->read_backing_store = read_ems_store; + info->write_backing_store = write_ems_store; + info->close_backing_store = close_ems_store; + TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); + return TRUE; /* succeeded */ +} + +#endif /* EMS_SUPPORTED */ + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + /* Try extended memory, then expanded memory, then regular file. */ +#if XMS_SUPPORTED + if (open_xms_store(cinfo, info, total_bytes_needed)) + return; +#endif +#if EMS_SUPPORTED + if (open_ems_store(cinfo, info, total_bytes_needed)) + return; +#endif + if (open_file_store(cinfo, info, total_bytes_needed)) + return; + ERREXITS(cinfo, JERR_TFILE_CREATE, ""); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* Microsoft C, at least in v6.00A, will not successfully reclaim freed + * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: + */ +#ifdef NEED_FHEAPMIN + _fheapmin(); +#endif +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemdosa.asm b/src/dep/src/irrlicht/jpeglib/jmemdosa.asm new file mode 100644 index 0000000..c6ec48b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemdosa.asm @@ -0,0 +1,379 @@ +; +; jmemdosa.asm +; +; Copyright (C) 1992, Thomas G. Lane. +; This file is part of the Independent JPEG Group's software. +; For conditions of distribution and use, see the accompanying README file. +; +; This file contains low-level interface routines to support the MS-DOS +; backing store manager (jmemdos.c). Routines are provided to access disk +; files through direct DOS calls, and to access XMS and EMS drivers. +; +; This file should assemble with Microsoft's MASM or any compatible +; assembler (including Borland's Turbo Assembler). If you haven't got +; a compatible assembler, better fall back to jmemansi.c or jmemname.c. +; +; To minimize dependence on the C compiler's register usage conventions, +; we save and restore all 8086 registers, even though most compilers only +; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return +; values, which everybody returns in AX. +; +; Based on code contributed by Ge' Weijers. +; + +JMEMDOSA_TXT segment byte public 'CODE' + + assume cs:JMEMDOSA_TXT + + public _jdos_open + public _jdos_close + public _jdos_seek + public _jdos_read + public _jdos_write + public _jxms_getdriver + public _jxms_calldriver + public _jems_available + public _jems_calldriver + +; +; short far jdos_open (short far * handle, char far * filename) +; +; Create and open a temporary file +; +_jdos_open proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov cx,0 ; normal file attributes + lds dx,dword ptr [bp+10] ; get filename pointer + mov ah,3ch ; create file + int 21h + jc open_err ; if failed, return error code + lds bx,dword ptr [bp+6] ; get handle pointer + mov word ptr [bx],ax ; save the handle + xor ax,ax ; return zero for OK +open_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_open endp + + +; +; short far jdos_close (short handle) +; +; Close the file handle +; +_jdos_close proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + mov ah,3eh ; close file + int 21h + jc close_err ; if failed, return error code + xor ax,ax ; return zero for OK +close_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_close endp + + +; +; short far jdos_seek (short handle, long offset) +; +; Set file position +; +_jdos_seek proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + mov dx,word ptr [bp+8] ; LS offset + mov cx,word ptr [bp+10] ; MS offset + mov ax,4200h ; absolute seek + int 21h + jc seek_err ; if failed, return error code + xor ax,ax ; return zero for OK +seek_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_seek endp + + +; +; short far jdos_read (short handle, void far * buffer, unsigned short count) +; +; Read from file +; +_jdos_read proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + lds dx,dword ptr [bp+8] ; buffer address + mov cx,word ptr [bp+12] ; number of bytes + mov ah,3fh ; read file + int 21h + jc read_err ; if failed, return error code + cmp ax,word ptr [bp+12] ; make sure all bytes were read + je read_ok + mov ax,1 ; else return 1 for not OK + jmp short read_err +read_ok: xor ax,ax ; return zero for OK +read_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_read endp + + +; +; short far jdos_write (short handle, void far * buffer, unsigned short count) +; +; Write to file +; +_jdos_write proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov bx,word ptr [bp+6] ; file handle + lds dx,dword ptr [bp+8] ; buffer address + mov cx,word ptr [bp+12] ; number of bytes + mov ah,40h ; write file + int 21h + jc write_err ; if failed, return error code + cmp ax,word ptr [bp+12] ; make sure all bytes written + je write_ok + mov ax,1 ; else return 1 for not OK + jmp short write_err +write_ok: xor ax,ax ; return zero for OK +write_err: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jdos_write endp + + +; +; void far jxms_getdriver (XMSDRIVER far *) +; +; Get the address of the XMS driver, or NULL if not available +; +_jxms_getdriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov ax,4300h ; call multiplex interrupt with + int 2fh ; a magic cookie, hex 4300 + cmp al,80h ; AL should contain hex 80 + je xmsavail + xor dx,dx ; no XMS driver available + xor ax,ax ; return a nil pointer + jmp short xmsavail_done +xmsavail: mov ax,4310h ; fetch driver address with + int 2fh ; another magic cookie + mov dx,es ; copy address to dx:ax + mov ax,bx +xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value + mov word ptr es:[bx],ax + mov word ptr es:[bx+2],dx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jxms_getdriver endp + + +; +; void far jxms_calldriver (XMSDRIVER, XMScontext far *) +; +; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers. +; These are loaded, the XMS call is performed, and the new values of the +; AX,DX,BX registers are written back to the context structure. +; +_jxms_calldriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + les bx,dword ptr [bp+10] ; get XMScontext pointer + mov ax,word ptr es:[bx] ; load registers + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + call dword ptr [bp+6] ; call the driver + mov cx,bx ; save returned BX for a sec + les bx,dword ptr [bp+10] ; get XMScontext pointer + mov word ptr es:[bx],ax ; put back ax,dx,bx + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jxms_calldriver endp + + +; +; short far jems_available (void) +; +; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs) +; +_jems_available proc far + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + mov ax,3567h ; get interrupt vector 67h + int 21h + push cs + pop ds + mov di,000ah ; check offs 10 in returned seg + lea si,ASCII_device_name ; against literal string + mov cx,8 + cld + repe cmpsb + jne no_ems + mov ax,1 ; match, it's there + jmp short avail_done +no_ems: xor ax,ax ; it's not there +avail_done: pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + ret + +ASCII_device_name db "EMMXXXX0" + +_jems_available endp + + +; +; void far jems_calldriver (EMScontext far *) +; +; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. +; These are loaded, the EMS trap is performed, and the new values of the +; AX,DX,BX registers are written back to the context structure. +; +_jems_calldriver proc far + push bp ; linkage + mov bp,sp + push si ; save all registers for safety + push di + push bx + push cx + push dx + push es + push ds + les bx,dword ptr [bp+6] ; get EMScontext pointer + mov ax,word ptr es:[bx] ; load registers + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + int 67h ; call the EMS driver + mov cx,bx ; save returned BX for a sec + les bx,dword ptr [bp+6] ; get EMScontext pointer + mov word ptr es:[bx],ax ; put back ax,dx,bx + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds ; restore registers and exit + pop es + pop dx + pop cx + pop bx + pop di + pop si + pop bp + ret +_jems_calldriver endp + +JMEMDOSA_TXT ends + + end diff --git a/src/dep/src/irrlicht/jpeglib/jmemmac.c b/src/dep/src/irrlicht/jpeglib/jmemmac.c new file mode 100644 index 0000000..a6f043e --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemmac.c @@ -0,0 +1,289 @@ +/* + * jmemmac.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * jmemmac.c provides an Apple Macintosh implementation of the system- + * dependent portion of the JPEG memory manager. + * + * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the + * JPEG_INTERNALS part of jconfig.h. + * + * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr + * instead of malloc and free. It accurately determines the amount of + * memory available by using CompactMem. Notice that if left to its + * own devices, this code can chew up all available space in the + * application's zone, with the exception of the rather small "slop" + * factor computed in jpeg_mem_available(). The application can ensure + * that more space is left over by reducing max_memory_to_use. + * + * Large images are swapped to disk using temporary files and System 7.0+'s + * temporary folder functionality. + * + * Note that jmemmac.c depends on two features of MacOS that were first + * introduced in System 7: FindFolder and the FSSpec-based calls. + * If your application uses jmemmac.c and is run under System 6 or earlier, + * and the jpeg library decides it needs a temporary file, it will abort, + * printing error messages about requiring System 7. (If no temporary files + * are created, it will run fine.) + * + * If you want to use jmemmac.c in an application that might be used with + * System 6 or earlier, then you should remove dependencies on FindFolder + * and the FSSpec calls. You will need to replace FindFolder with some + * other mechanism for finding a place to put temporary files, and you + * should replace the FSSpec calls with their HFS equivalents: + * + * FSpDelete -> HDelete + * FSpGetFInfo -> HGetFInfo + * FSpCreate -> HCreate + * FSpOpenDF -> HOpen *** Note: not HOpenDF *** + * FSMakeFSSpec -> (fill in spec by hand.) + * + * (Use HOpen instead of HOpenDF. HOpen is just a glue-interface to PBHOpen, + * which is on all HFS macs. HOpenDF is a System 7 addition which avoids the + * ages-old problem of names starting with a period.) + * + * Contributed by Sam Bushell (jsam@iagu.on.net) and + * Dan Gildor (gyld@in-touch.com). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef USE_MAC_MEMMGR /* make sure user got configuration right */ + You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */ +#endif + +#include /* we use the MacOS memory manager */ +#include /* we use the MacOS File stuff */ +#include /* we use the MacOS HFS stuff */ +#include /* for smSystemScript */ +#include /* we use Gestalt to test for specific functionality */ + +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "JPG%03d.TMP" +#endif + +static int next_file_num; /* to distinguish among several temp files */ + + +/* + * Memory allocation and freeing are controlled by the MacOS library + * routines NewPtr() and DisposePtr(), which allocate fixed-address + * storage. Unfortunately, the IJG library isn't smart enough to cope + * with relocatable storage. + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) NewPtr(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + DisposePtr((Ptr) object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: we include FAR keywords in the routine declarations simply for + * consistency with the rest of the IJG code; FAR should expand to empty + * on rational architectures like the Mac. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) NewPtr(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + DisposePtr((Ptr) object); +} + + +/* + * This routine computes the total memory space available for allocation. + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + long limit = cinfo->mem->max_memory_to_use - already_allocated; + long slop, mem; + + /* Don't ask for more than what application has told us we may use */ + if (max_bytes_needed > limit && limit > 0) + max_bytes_needed = limit; + /* Find whether there's a big enough free block in the heap. + * CompactMem tries to create a contiguous block of the requested size, + * and then returns the size of the largest free block (which could be + * much more or much less than we asked for). + * We add some slop to ensure we don't use up all available memory. + */ + slop = max_bytes_needed / 16 + 32768L; + mem = CompactMem(max_bytes_needed + slop) - slop; + if (mem < 0) + mem = 0; /* sigh, couldn't even get the slop */ + /* Don't take more than the application says we can have */ + if (mem > limit && limit > 0) + mem = limit; + return mem; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + long bytes = byte_count; + long retVal; + + if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) + ERREXIT(cinfo, JERR_TFILE_SEEK); + + retVal = FSRead ( info->temp_file, &bytes, + (unsigned char *) buffer_address ); + if ( retVal != noErr || bytes != byte_count ) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + long bytes = byte_count; + long retVal; + + if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr ) + ERREXIT(cinfo, JERR_TFILE_SEEK); + + retVal = FSWrite ( info->temp_file, &bytes, + (unsigned char *) buffer_address ); + if ( retVal != noErr || bytes != byte_count ) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + FSClose ( info->temp_file ); + FSpDelete ( &(info->tempSpec) ); +} + + +/* + * Initial opening of a backing-store object. + * + * This version uses FindFolder to find the Temporary Items folder, + * and puts the temporary file in there. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + short tmpRef, vRefNum; + long dirID; + FInfo finderInfo; + FSSpec theSpec; + Str255 fName; + OSErr osErr; + long gestaltResponse = 0; + + /* Check that FSSpec calls are available. */ + osErr = Gestalt( gestaltFSAttr, &gestaltResponse ); + if ( ( osErr != noErr ) + || !( gestaltResponse & (1<temp_name, TEMP_FILE_NAME, next_file_num); + strcpy ( (Ptr)fName+1, info->temp_name ); + *fName = strlen (info->temp_name); + osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec ); + + if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr ) + break; + } + + osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript ); + if ( osErr != noErr ) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + + osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) ); + if ( osErr != noErr ) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + + info->tempSpec = theSpec; + + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; + + /* max_memory_to_use will be initialized to FreeMem()'s result; + * the calling application might later reduce it, for example + * to leave room to invoke multiple JPEG objects. + * Note that FreeMem returns the total number of free bytes; + * it may not be possible to allocate a single block of this size. + */ + return FreeMem(); +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemmgr.c b/src/dep/src/irrlicht/jpeglib/jmemmgr.c new file mode 100644 index 0000000..b636f1b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemmgr.c @@ -0,0 +1,1118 @@ +/* + * jmemmgr.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the JPEG system-independent memory management + * routines. This code is usable across a wide variety of machines; most + * of the system dependencies have been isolated in a separate file. + * The major functions provided here are: + * * pool-based allocation and freeing of memory; + * * policy decisions about how to divide available memory among the + * virtual arrays; + * * control logic for swapping virtual arrays between main memory and + * backing storage. + * The separate system-dependent file provides the actual backing-storage + * access code, and it contains the policy decision about how much total + * main memory to use. + * This file is system-dependent in the sense that some of its functions + * are unnecessary in some systems. For example, if there is enough virtual + * memory so that backing storage will never be used, much of the virtual + * array control logic could be removed. (Of course, if you have that much + * memory then you shouldn't care about a little bit of unused code...) + */ + +#define JPEG_INTERNALS +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef NO_GETENV +#ifndef HAVE_STDLIB_H /* should declare getenv() */ +extern char * getenv JPP((const char * name)); +#endif +#endif + + +/* + * Some important notes: + * The allocation routines provided here must never return NULL. + * They should exit to error_exit if unsuccessful. + * + * It's not a good idea to try to merge the sarray and barray routines, + * even though they are textually almost the same, because samples are + * usually stored as bytes while coefficients are shorts or ints. Thus, + * in machines where byte pointers have a different representation from + * word pointers, the resulting machine code could not be the same. + */ + + +/* + * Many machines require storage alignment: longs must start on 4-byte + * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + * always returns pointers that are multiples of the worst-case alignment + * requirement, and we had better do so too. + * There isn't any really portable way to determine the worst-case alignment + * requirement. This module assumes that the alignment requirement is + * multiples of sizeof(ALIGN_TYPE). + * By default, we define ALIGN_TYPE as double. This is necessary on some + * workstations (where doubles really do need 8-byte alignment) and will work + * fine on nearly everything. If your machine has lesser alignment needs, + * you can save a few bytes by making ALIGN_TYPE smaller. + * The only place I know of where this will NOT work is certain Macintosh + * 680x0 compilers that define double as a 10-byte IEEE extended float. + * Doing 10-byte alignment is counterproductive because longwords won't be + * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + * such a compiler. + */ + +#ifndef ALIGN_TYPE /* so can override from jconfig.h */ +#define ALIGN_TYPE double +#endif + + +/* + * We allocate objects from "pools", where each pool is gotten with a single + * request to jpeg_get_small() or jpeg_get_large(). There is no per-object + * overhead within a pool, except for alignment padding. Each pool has a + * header with a link to the next pool of the same class. + * Small and large pool headers are identical except that the latter's + * link pointer must be FAR on 80x86 machines. + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + * of the alignment requirement of ALIGN_TYPE. + */ + +typedef union small_pool_struct * small_pool_ptr; + +typedef union small_pool_struct { + struct { + small_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} small_pool_hdr; + +typedef union large_pool_struct FAR * large_pool_ptr; + +typedef union large_pool_struct { + struct { + large_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ + } hdr; + ALIGN_TYPE dummy; /* included in union to ensure alignment */ +} large_pool_hdr; + + +/* + * Here is the full definition of a memory manager object. + */ + +typedef struct { + struct jpeg_memory_mgr pub; /* public fields */ + + /* Each pool identifier (lifetime class) names a linked list of pools. */ + small_pool_ptr small_list[JPOOL_NUMPOOLS]; + large_pool_ptr large_list[JPOOL_NUMPOOLS]; + + /* Since we only have one lifetime class of virtual arrays, only one + * linked list is necessary (for each datatype). Note that the virtual + * array control blocks being linked together are actually stored somewhere + * in the small-pool list. + */ + jvirt_sarray_ptr virt_sarray_list; + jvirt_barray_ptr virt_barray_list; + + /* This counts total space obtained from jpeg_get_small/large */ + long total_space_allocated; + + /* alloc_sarray and alloc_barray set this value for use by virtual + * array routines. + */ + JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ +} my_memory_mgr; + +typedef my_memory_mgr * my_mem_ptr; + + +/* + * The control blocks for virtual arrays. + * Note that these blocks are allocated in the "small" pool area. + * System-dependent info for the associated backing store (if any) is hidden + * inside the backing_store_info struct. + */ + +struct jvirt_sarray_control { + JSAMPARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_sarray_ptr next; /* link to next virtual sarray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + +struct jvirt_barray_control { + JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_barray_ptr next; /* link to next virtual barray control block */ + backing_store_info b_s_info; /* System-dependent control info */ +}; + + +#ifdef MEM_STATS /* optional extra stuff for statistics */ + +LOCAL(void) +print_mem_stats (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + + /* Since this is only a debugging stub, we can cheat a little by using + * fprintf directly rather than going through the trace message code. + * This is helpful because message parm array can't handle longs. + */ + fprintf(stderr, "Freeing pool %d, total space = %ld\n", + pool_id, mem->total_space_allocated); + + for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; + lhdr_ptr = lhdr_ptr->hdr.next) { + fprintf(stderr, " Large chunk used %ld\n", + (long) lhdr_ptr->hdr.bytes_used); + } + + for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; + shdr_ptr = shdr_ptr->hdr.next) { + fprintf(stderr, " Small chunk used %ld free %ld\n", + (long) shdr_ptr->hdr.bytes_used, + (long) shdr_ptr->hdr.bytes_left); + } +} + +#endif /* MEM_STATS */ + + +LOCAL(void) +out_of_memory (j_common_ptr cinfo, int which) +/* Report an out-of-memory error and stop execution */ +/* If we compiled MEM_STATS support, report alloc requests before dying */ +{ +#ifdef MEM_STATS + cinfo->err->trace_level = 2; /* force self_destruct to report stats */ +#endif + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +} + + +/* + * Allocation of "small" objects. + * + * For these, we use pooled storage. When a new pool must be created, + * we try to get enough space for the current request plus a "slop" factor, + * where the slop will be the amount of leftover space in the new pool. + * The speed vs. space tradeoff is largely determined by the slop values. + * A different slop value is provided for each pool class (lifetime), + * and we also distinguish the first pool of a class from later ones. + * NOTE: the values given work fairly well on both 16- and 32-bit-int + * machines, but may be too small if longs are 64 bits or more. + */ + +static const size_t first_pool_slop[JPOOL_NUMPOOLS] = +{ + 1600, /* first PERMANENT pool */ + 16000 /* first IMAGE pool */ +}; + +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = +{ + 0, /* additional PERMANENT pools */ + 5000 /* additional IMAGE pools */ +}; + +#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ + + +METHODDEF(void *) +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "small" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr hdr_ptr, prev_hdr_ptr; + char * data_ptr; + size_t odd_bytes, min_request, slop; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) + out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* See if space is available in any existing pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + prev_hdr_ptr = NULL; + hdr_ptr = mem->small_list[pool_id]; + while (hdr_ptr != NULL) { + if (hdr_ptr->hdr.bytes_left >= sizeofobject) + break; /* found pool with enough space */ + prev_hdr_ptr = hdr_ptr; + hdr_ptr = hdr_ptr->hdr.next; + } + + /* Time to make a new pool? */ + if (hdr_ptr == NULL) { + /* min_request is what we need now, slop is what will be leftover */ + min_request = sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr == NULL) /* first pool in class? */ + slop = first_pool_slop[pool_id]; + else + slop = extra_pool_slop[pool_id]; + /* Don't ask for more than MAX_ALLOC_CHUNK */ + if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) + slop = (size_t) (MAX_ALLOC_CHUNK-min_request); + /* Try to get space, if fail reduce slop and try again */ + for (;;) { + hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); + if (hdr_ptr != NULL) + break; + slop /= 2; + if (slop < MIN_SLOP) /* give up when it gets real small */ + out_of_memory(cinfo, 2); /* jpeg_get_small failed */ + } + mem->total_space_allocated += min_request + slop; + /* Success, initialize the new pool header and add to end of list */ + hdr_ptr->hdr.next = NULL; + hdr_ptr->hdr.bytes_used = 0; + hdr_ptr->hdr.bytes_left = sizeofobject + slop; + if (prev_hdr_ptr == NULL) /* first pool in class? */ + mem->small_list[pool_id] = hdr_ptr; + else + prev_hdr_ptr->hdr.next = hdr_ptr; + } + + /* OK, allocate the object from the current pool */ + data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ + data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ + hdr_ptr->hdr.bytes_used += sizeofobject; + hdr_ptr->hdr.bytes_left -= sizeofobject; + + return (void *) data_ptr; +} + + +/* + * Allocation of "large" objects. + * + * The external semantics of these are the same as "small" objects, + * except that FAR pointers are used on 80x86. However the pool + * management heuristics are quite different. We assume that each + * request is large enough that it may as well be passed directly to + * jpeg_get_large; the pool management just links everything together + * so that we can free it all on demand. + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + * structures. The routines that create these structures (see below) + * deliberately bunch rows together to ensure a large request size. + */ + +METHODDEF(void FAR *) +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) +/* Allocate a "large" object */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + large_pool_ptr hdr_ptr; + size_t odd_bytes; + + /* Check for unsatisfiable request (do now to ensure no overflow below) */ + if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) + out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ + + /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ + odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) + sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; + + /* Always make a new pool */ + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr)); + if (hdr_ptr == NULL) + out_of_memory(cinfo, 4); /* jpeg_get_large failed */ + mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); + + /* Success, initialize the new pool header and add to list */ + hdr_ptr->hdr.next = mem->large_list[pool_id]; + /* We maintain space counts in each pool header for statistical purposes, + * even though they are not needed for allocation. + */ + hdr_ptr->hdr.bytes_used = sizeofobject; + hdr_ptr->hdr.bytes_left = 0; + mem->large_list[pool_id] = hdr_ptr; + + return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ +} + + +/* + * Creation of 2-D sample arrays. + * The pointers are in near heap, the samples themselves in FAR heap. + * + * To minimize allocation overhead and to allow I/O of large contiguous + * blocks, we allocate the sample rows in groups of as many rows as possible + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + * NB: the virtual array control routines, later in this file, know about + * this chunking of rows. The rowsperchunk value is left in the mem manager + * object so that it can be saved away if this sarray is the workspace for + * a virtual array. + */ + +METHODDEF(JSAMPARRAY) +alloc_sarray (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +/* Allocate a 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JSAMPARRAY result; + JSAMPROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) samplesperrow * SIZEOF(JSAMPLE)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JSAMPARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JSAMPROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JSAMPROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow + * SIZEOF(JSAMPLE))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += samplesperrow; + } + } + + return result; +} + + +/* + * Creation of 2-D coefficient-block arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF(JBLOCKARRAY) +alloc_barray (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, JDIMENSION numrows) +/* Allocate a 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JBLOCKARRAY result; + JBLOCKROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) blocksperrow * SIZEOF(JBLOCK)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JBLOCKROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow + * SIZEOF(JBLOCK))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += blocksperrow; + } + } + + return result; +} + + +/* + * About virtual array management: + * + * The above "normal" array routines are only used to allocate strip buffers + * (as wide as the image, but just a few rows high). Full-image-sized buffers + * are handled as "virtual" arrays. The array is still accessed a strip at a + * time, but the memory manager must save the whole array for repeated + * accesses. The intended implementation is that there is a strip buffer in + * memory (as high as is possible given the desired memory limit), plus a + * backing file that holds the rest of the array. + * + * The request_virt_array routines are told the total size of the image and + * the maximum number of rows that will be accessed at once. The in-memory + * buffer must be at least as large as the maxaccess value. + * + * The request routines create control blocks but not the in-memory buffers. + * That is postponed until realize_virt_arrays is called. At that time the + * total amount of space needed is known (approximately, anyway), so free + * memory can be divided up fairly. + * + * The access_virt_array routines are responsible for making a specific strip + * area accessible (after reading or writing the backing file, if necessary). + * Note that the access routines are told whether the caller intends to modify + * the accessed strip; during a read-only pass this saves having to rewrite + * data to disk. The access routines are also responsible for pre-zeroing + * any newly accessed rows, if pre-zeroing was requested. + * + * In current usage, the access requests are usually for nonoverlapping + * strips; that is, successive access start_row numbers differ by exactly + * num_rows = maxaccess. This means we can get good performance with simple + * buffer dump/reload logic, by making the in-memory buffer be a multiple + * of the access height; then there will never be accesses across bufferload + * boundaries. The code will still work with overlapping access requests, + * but it doesn't handle bufferload overlaps very efficiently. + */ + + +METHODDEF(jvirt_sarray_ptr) +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION samplesperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D sample array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_sarray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_sarray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->samplesperrow = samplesperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ + mem->virt_sarray_list = result; + + return result; +} + + +METHODDEF(jvirt_barray_ptr) +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, + JDIMENSION blocksperrow, JDIMENSION numrows, + JDIMENSION maxaccess) +/* Request a virtual 2-D coefficient-block array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + jvirt_barray_ptr result; + + /* Only IMAGE-lifetime virtual arrays are currently supported */ + if (pool_id != JPOOL_IMAGE) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + + /* get control block */ + result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, + SIZEOF(struct jvirt_barray_control)); + + result->mem_buffer = NULL; /* marks array not yet realized */ + result->rows_in_array = numrows; + result->blocksperrow = blocksperrow; + result->maxaccess = maxaccess; + result->pre_zero = pre_zero; + result->b_s_open = FALSE; /* no associated backing-store object */ + result->next = mem->virt_barray_list; /* add to list of virtual arrays */ + mem->virt_barray_list = result; + + return result; +} + + +METHODDEF(void) +realize_virt_arrays (j_common_ptr cinfo) +/* Allocate the in-memory buffers for any unrealized virtual arrays */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + long space_per_minheight, maximum_space, avail_mem; + long minheights, max_minheights; + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + /* Compute the minimum space needed (maxaccess rows in each buffer) + * and the maximum space needed (full image height in each buffer). + * These may be of use to the system-dependent jpeg_mem_available routine. + */ + space_per_minheight = 0; + maximum_space = 0; + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) sptr->maxaccess * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + maximum_space += (long) sptr->rows_in_array * + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + } + } + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + space_per_minheight += (long) bptr->maxaccess * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + maximum_space += (long) bptr->rows_in_array * + (long) bptr->blocksperrow * SIZEOF(JBLOCK); + } + } + + if (space_per_minheight <= 0) + return; /* no unrealized arrays, no work */ + + /* Determine amount of memory to actually use; this is system-dependent. */ + avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem->total_space_allocated); + + /* If the maximum space needed is available, make all the buffers full + * height; otherwise parcel it out with the same number of minheights + * in each buffer. + */ + if (avail_mem >= maximum_space) + max_minheights = 1000000000L; + else { + max_minheights = avail_mem / space_per_minheight; + /* If there doesn't seem to be enough space, try to get the minimum + * anyway. This allows a "stub" implementation of jpeg_mem_available(). + */ + if (max_minheights <= 0) + max_minheights = 1; + } + + /* Allocate the in-memory buffers and initialize backing store as needed. */ + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + sptr->rows_in_mem = sptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); + jpeg_open_backing_store(cinfo, & sptr->b_s_info, + (long) sptr->rows_in_array * + (long) sptr->samplesperrow * + (long) SIZEOF(JSAMPLE)); + sptr->b_s_open = TRUE; + } + sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, + sptr->samplesperrow, sptr->rows_in_mem); + sptr->rowsperchunk = mem->last_rowsperchunk; + sptr->cur_start_row = 0; + sptr->first_undef_row = 0; + sptr->dirty = FALSE; + } + } + + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->mem_buffer == NULL) { /* if not realized yet */ + minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; + if (minheights <= max_minheights) { + /* This buffer fits in memory */ + bptr->rows_in_mem = bptr->rows_in_array; + } else { + /* It doesn't fit in memory, create backing store. */ + bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); + jpeg_open_backing_store(cinfo, & bptr->b_s_info, + (long) bptr->rows_in_array * + (long) bptr->blocksperrow * + (long) SIZEOF(JBLOCK)); + bptr->b_s_open = TRUE; + } + bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, + bptr->blocksperrow, bptr->rows_in_mem); + bptr->rowsperchunk = mem->last_rowsperchunk; + bptr->cur_start_row = 0; + bptr->first_undef_row = 0; + bptr->dirty = FALSE; + } + } +} + + +LOCAL(void) +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual sample array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +LOCAL(void) +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) +/* Do backing store read or write of a virtual coefficient-block array */ +{ + long bytesperrow, file_offset, byte_count, rows, thisrow, i; + + bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); + file_offset = ptr->cur_start_row * bytesperrow; + /* Loop to read or write each allocation chunk in mem_buffer */ + for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { + /* One chunk, but check for short chunk at end of buffer */ + rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); + /* Transfer no more than is currently defined */ + thisrow = (long) ptr->cur_start_row + i; + rows = MIN(rows, (long) ptr->first_undef_row - thisrow); + /* Transfer no more than fits in file */ + rows = MIN(rows, (long) ptr->rows_in_array - thisrow); + if (rows <= 0) /* this chunk might be past end of file! */ + break; + byte_count = rows * bytesperrow; + if (writing) + (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + else + (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); + file_offset += byte_count; + } +} + + +METHODDEF(JSAMPARRAY) +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual sample array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_sarray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_sarray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +METHODDEF(JBLOCKARRAY) +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) +/* Access the part of a virtual block array starting at start_row */ +/* and extending for num_rows rows. writable is true if */ +/* caller intends to modify the accessed area. */ +{ + JDIMENSION end_row = start_row + num_rows; + JDIMENSION undef_row; + + /* debugging check */ + if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || + ptr->mem_buffer == NULL) + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + /* Make the desired part of the virtual array accessible */ + if (start_row < ptr->cur_start_row || + end_row > ptr->cur_start_row+ptr->rows_in_mem) { + if (! ptr->b_s_open) + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + /* Flush old buffer contents if necessary */ + if (ptr->dirty) { + do_barray_io(cinfo, ptr, TRUE); + ptr->dirty = FALSE; + } + /* Decide what part of virtual array to access. + * Algorithm: if target address > current window, assume forward scan, + * load starting at target address. If target address < current window, + * assume backward scan, load so that target area is top of window. + * Note that when switching from forward write to forward read, will have + * start_row = 0, so the limiting case applies and we load from 0 anyway. + */ + if (start_row > ptr->cur_start_row) { + ptr->cur_start_row = start_row; + } else { + /* use long arithmetic here to avoid overflow & unsigned problems */ + long ltemp; + + ltemp = (long) end_row - (long) ptr->rows_in_mem; + if (ltemp < 0) + ltemp = 0; /* don't fall off front end of file */ + ptr->cur_start_row = (JDIMENSION) ltemp; + } + /* Read in the selected part of the array. + * During the initial write pass, we will do no actual read + * because the selected part is all undefined. + */ + do_barray_io(cinfo, ptr, FALSE); + } + /* Ensure the accessed part of the array is defined; prezero if needed. + * To improve locality of access, we only prezero the part of the array + * that the caller is about to access, not the entire in-memory array. + */ + if (ptr->first_undef_row < end_row) { + if (ptr->first_undef_row < start_row) { + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ + } else { + undef_row = ptr->first_undef_row; + } + if (writable) + ptr->first_undef_row = end_row; + if (ptr->pre_zero) { + size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); + undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ + end_row -= ptr->cur_start_row; + while (undef_row < end_row) { + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; + } + } else { + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + } + } + /* Flag the buffer dirty if caller will write in it */ + if (writable) + ptr->dirty = TRUE; + /* Return address of proper part of the buffer */ + return ptr->mem_buffer + (start_row - ptr->cur_start_row); +} + + +/* + * Release all objects belonging to a specified pool. + */ + +METHODDEF(void) +free_pool (j_common_ptr cinfo, int pool_id) +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + small_pool_ptr shdr_ptr; + large_pool_ptr lhdr_ptr; + size_t space_freed; + + if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + +#ifdef MEM_STATS + if (cinfo->err->trace_level > 1) + print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ +#endif + + /* If freeing IMAGE pool, close any virtual arrays first */ + if (pool_id == JPOOL_IMAGE) { + jvirt_sarray_ptr sptr; + jvirt_barray_ptr bptr; + + for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { + if (sptr->b_s_open) { /* there may be no backing store */ + sptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); + } + } + mem->virt_sarray_list = NULL; + for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { + if (bptr->b_s_open) { /* there may be no backing store */ + bptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); + } + } + mem->virt_barray_list = NULL; + } + + /* Release large objects */ + lhdr_ptr = mem->large_list[pool_id]; + mem->large_list[pool_id] = NULL; + + while (lhdr_ptr != NULL) { + large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; + space_freed = lhdr_ptr->hdr.bytes_used + + lhdr_ptr->hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + lhdr_ptr = next_lhdr_ptr; + } + + /* Release small objects */ + shdr_ptr = mem->small_list[pool_id]; + mem->small_list[pool_id] = NULL; + + while (shdr_ptr != NULL) { + small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; + space_freed = shdr_ptr->hdr.bytes_used + + shdr_ptr->hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); + mem->total_space_allocated -= space_freed; + shdr_ptr = next_shdr_ptr; + } +} + + +/* + * Close up shop entirely. + * Note that this cannot be called unless cinfo->mem is non-NULL. + */ + +METHODDEF(void) +self_destruct (j_common_ptr cinfo) +{ + int pool; + + /* Close all backing store, release all memory. + * Releasing pools in reverse order might help avoid fragmentation + * with some (brain-damaged) malloc libraries. + */ + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + free_pool(cinfo, pool); + } + + /* Release the memory manager control block too. */ + jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); + cinfo->mem = NULL; /* ensures I will be called only once */ + + jpeg_mem_term(cinfo); /* system-dependent cleanup */ +} + + +/* + * Memory manager initialization. + * When this is called, only the error manager pointer is valid in cinfo! + */ + +GLOBAL(void) +jinit_memory_mgr (j_common_ptr cinfo) +{ + my_mem_ptr mem; + long max_to_use; + int pool; + size_t test_mac; + + cinfo->mem = NULL; /* for safety if init fails */ + + /* Check for configuration errors. + * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + * doesn't reflect any real hardware alignment requirement. + * The test is a little tricky: for X>0, X and X-1 have no one-bits + * in common if and only if X is a power of 2, ie has only one one-bit. + * Some compilers may give an "unreachable code" warning here; ignore it. + */ + if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be + * a multiple of SIZEOF(ALIGN_TYPE). + * Again, an "unreachable code" warning may be ignored here. + * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. + */ + test_mac = (size_t) MAX_ALLOC_CHUNK; + if ((long) test_mac != MAX_ALLOC_CHUNK || + (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ + + /* Attempt to allocate memory manager's control block */ + mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); + + if (mem == NULL) { + jpeg_mem_term(cinfo); /* system-dependent cleanup */ + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + } + + /* OK, fill in the method pointers */ + mem->pub.alloc_small = alloc_small; + mem->pub.alloc_large = alloc_large; + mem->pub.alloc_sarray = alloc_sarray; + mem->pub.alloc_barray = alloc_barray; + mem->pub.request_virt_sarray = request_virt_sarray; + mem->pub.request_virt_barray = request_virt_barray; + mem->pub.realize_virt_arrays = realize_virt_arrays; + mem->pub.access_virt_sarray = access_virt_sarray; + mem->pub.access_virt_barray = access_virt_barray; + mem->pub.free_pool = free_pool; + mem->pub.self_destruct = self_destruct; + + /* Make MAX_ALLOC_CHUNK accessible to other modules */ + mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK; + + /* Initialize working state */ + mem->pub.max_memory_to_use = max_to_use; + + for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { + mem->small_list[pool] = NULL; + mem->large_list[pool] = NULL; + } + mem->virt_sarray_list = NULL; + mem->virt_barray_list = NULL; + + mem->total_space_allocated = SIZEOF(my_memory_mgr); + + /* Declare ourselves open for business */ + cinfo->mem = & mem->pub; + + /* Check for an environment variable JPEGMEM; if found, override the + * default max_memory setting from jpeg_mem_init. Note that the + * surrounding application may again override this value. + * If your system doesn't support getenv(), define NO_GETENV to disable + * this feature. + */ +#ifndef NO_GETENV + { char * memenv; + + if ((memenv = getenv("JPEGMEM")) != NULL) { + char ch = 'x'; + + if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { + if (ch == 'm' || ch == 'M') + max_to_use *= 1000L; + mem->pub.max_memory_to_use = max_to_use * 1000L; + } + } + } +#endif + +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemname.c b/src/dep/src/irrlicht/jpeglib/jmemname.c new file mode 100644 index 0000000..e28b212 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemname.c @@ -0,0 +1,276 @@ +/* + * jmemname.c + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a generic implementation of the system-dependent + * portion of the JPEG memory manager. This implementation assumes that + * you must explicitly construct a name for each temp file. + * Also, the problem of determining the amount of memory available + * is shoved onto the user. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + +#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ +#define SEEK_SET 0 /* if not, assume 0 is correct */ +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define RW_BINARY "w+" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define RW_BINARY "w+b", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define RW_BINARY "w+b" +#endif +#endif + + +/* + * Selection of a file name for a temporary file. + * This is system-dependent! + * + * The code as given is suitable for most Unix systems, and it is easily + * modified for most non-Unix systems. Some notes: + * 1. The temp file is created in the directory named by TEMP_DIRECTORY. + * The default value is /usr/tmp, which is the conventional place for + * creating large temp files on Unix. On other systems you'll probably + * want to change the file location. You can do this by editing the + * #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h. + * + * 2. If you need to change the file name as well as its location, + * you can override the TEMP_FILE_NAME macro. (Note that this is + * actually a printf format string; it must contain %s and %d.) + * Few people should need to do this. + * + * 3. mktemp() is used to ensure that multiple processes running + * simultaneously won't select the same file names. If your system + * doesn't have mktemp(), define NO_MKTEMP to do it the hard way. + * (If you don't have , also define NO_ERRNO_H.) + * + * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c + * will cause the temp files to be removed if you stop the program early. + */ + +#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ +#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ +#endif + +static int next_file_num; /* to distinguish among several temp files */ + +#ifdef NO_MKTEMP + +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%03d.TMP" +#endif + +#ifndef NO_ERRNO_H +#include /* to define ENOENT */ +#endif + +/* ANSI C specifies that errno is a macro, but on older systems it's more + * likely to be a plain int variable. And not all versions of errno.h + * bother to declare it, so we have to in order to be most portable. Thus: + */ +#ifndef errno +extern int errno; +#endif + + +LOCAL(void) +select_file_name (char * fname) +{ + FILE * tfile; + + /* Keep generating file names till we find one that's not in use */ + for (;;) { + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + if ((tfile = fopen(fname, READ_BINARY)) == NULL) { + /* fopen could have failed for a reason other than the file not + * being there; for example, file there but unreadable. + * If isn't available, then we cannot test the cause. + */ +#ifdef ENOENT + if (errno != ENOENT) + continue; +#endif + break; + } + fclose(tfile); /* oops, it's there; close tfile & try again */ + } +} + +#else /* ! NO_MKTEMP */ + +/* Note that mktemp() requires the initial filename to end in six X's */ +#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ +#define TEMP_FILE_NAME "%sJPG%dXXXXXX" +#endif + +LOCAL(void) +select_file_name (char * fname) +{ + next_file_num++; /* advance counter */ + sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); + mktemp(fname); /* make sure file name is unique */ + /* mktemp replaces the trailing XXXXXX with a unique string of characters */ +} + +#endif /* NO_MKTEMP */ + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * It's impossible to do this in a portable way; our current solution is + * to make the user tell us (with a default value set at compile time). + * If you can actually get the available space, it's a good idea to subtract + * a slop factor of 5% or so. + */ + +#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ +#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ +#endif + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return cinfo->mem->max_memory_to_use - already_allocated; +} + + +/* + * Backing store (temporary file) management. + * Backing store objects are only used when the value returned by + * jpeg_mem_available is less than the total space needed. You can dispense + * with these routines if you have plenty of virtual memory; see jmemnobs.c. + */ + + +METHODDEF(void) +read_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFREAD(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_READ); +} + + +METHODDEF(void) +write_backing_store (j_common_ptr cinfo, backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count) +{ + if (fseek(info->temp_file, file_offset, SEEK_SET)) + ERREXIT(cinfo, JERR_TFILE_SEEK); + if (JFWRITE(info->temp_file, buffer_address, byte_count) + != (size_t) byte_count) + ERREXIT(cinfo, JERR_TFILE_WRITE); +} + + +METHODDEF(void) +close_backing_store (j_common_ptr cinfo, backing_store_ptr info) +{ + fclose(info->temp_file); /* close the file */ + unlink(info->temp_name); /* delete the file */ +/* If your system doesn't have unlink(), use remove() instead. + * remove() is the ANSI-standard name for this function, but if + * your system was ANSI you'd be using jmemansi.c, right? + */ + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); +} + + +/* + * Initial opening of a backing-store object. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + select_file_name(info->temp_name); + if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL) + ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); + info->read_backing_store = read_backing_store; + info->write_backing_store = write_backing_store; + info->close_backing_store = close_backing_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + next_file_num = 0; /* initialize temp file name generator */ + return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemnobs.c b/src/dep/src/irrlicht/jpeglib/jmemnobs.c new file mode 100644 index 0000000..6aa1e92 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemnobs.c @@ -0,0 +1,109 @@ +/* + * jmemnobs.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space + * can be obtained from malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return 0; /* just set max_memory_to_use to 0 */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jmemsys.h b/src/dep/src/irrlicht/jpeglib/jmemsys.h new file mode 100644 index 0000000..2a87961 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmemsys.h @@ -0,0 +1,198 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory. (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free. jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * On an 80x86 machine using small-data memory model, these manage near heap. + */ + +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used. On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * in case a different allocation strategy is desirable for large chunks. + */ + +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, + size_t sizeofobject)); +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play). This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK 1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large. If more space than this is needed, backing store will be + * used. NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero. The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed. If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure. Hence it's wise to subtract + * a slop factor from the true available space. 5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * Conversely, zero may be returned to always use the minimum amount of memory. + */ + +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object. The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + + +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ + +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ + +typedef union { + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#include +#endif /* USE_MAC_MEMMGR */ + + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { + /* Methods for reading/writing/closing this backing-store object */ + JMETHOD(void, read_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr info)); + + /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR + /* For the MS-DOS manager (jmemdos.c), we need: */ + handle_union handle; /* reference to backing-store storage object */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else +#ifdef USE_MAC_MEMMGR + /* For the Mac manager (jmemmac.c), we need: */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else + /* For a typical implementation with temp files, we need: */ + FILE * temp_file; /* stdio reference to temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ +#endif +#endif +} backing_store_info; + + +/* + * Initial opening of a backing-store object. This must fill in the + * read/write/close pointers in the object. The read/write routines + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer). It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application. (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * all opened backing-store objects have been closed. + */ + +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/src/dep/src/irrlicht/jpeglib/jmorecfg.h b/src/dep/src/irrlicht/jpeglib/jmorecfg.h new file mode 100644 index 0000000..c856e22 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/src/dep/src/irrlicht/jpeglib/jpegint.h b/src/dep/src/irrlicht/jpeglib/jpegint.h new file mode 100644 index 0000000..685a361 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jpegint.h @@ -0,0 +1,392 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* Marker writing */ +struct jpeg_marker_writer { + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, + unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, + JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean insufficient_data; /* set TRUE after emitting warning */ +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); + JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity. This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit. But some + * C compilers implement >> with an unsigned shift. For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts. SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x,shft) \ + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_huff_encoder jIHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_marker_writer jIMWriter +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_huff_decoder jIHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Compression module initialization routines */ +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, + boolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +/* Memory manager initialization */ +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); + +/* Utility routines in jutils.c */ +EXTERN(long) jdiv_round_up JPP((long a, long b)); +EXTERN(long) jround_up JPP((long a, long b)); +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); +/* Constant tables in jutils.c */ +#if 0 /* This table is not actually needed in v6a */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +#endif +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/src/dep/src/irrlicht/jpeglib/jpeglib.h b/src/dep/src/irrlicht/jpeglib/jpeglib.h new file mode 100644 index 0000000..b9356f3 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jpeglib.h @@ -0,0 +1,1096 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/src/dep/src/irrlicht/jpeglib/jpegtran.1 b/src/dep/src/irrlicht/jpeglib/jpegtran.1 new file mode 100644 index 0000000..ba3c2b3 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jpegtran.1 @@ -0,0 +1,238 @@ +.TH JPEGTRAN 1 "3 August 1997" +.SH NAME +jpegtran \- lossless transformation of JPEG files +.SH SYNOPSIS +.B jpegtran +[ +.I options +] +[ +.I filename +] +.LP +.SH DESCRIPTION +.LP +.B jpegtran +performs various useful transformations of JPEG files. +It can translate the coded representation from one variant of JPEG to another, +for example from baseline JPEG to progressive JPEG or vice versa. It can also +perform some rearrangements of the image data, for example turning an image +from landscape to portrait format by rotation. +.PP +.B jpegtran +works by rearranging the compressed data (DCT coefficients), without +ever fully decoding the image. Therefore, its transformations are lossless: +there is no image degradation at all, which would not be true if you used +.B djpeg +followed by +.B cjpeg +to accomplish the same conversion. But by the same token, +.B jpegtran +cannot perform lossy operations such as changing the image quality. +.PP +.B jpegtran +reads the named JPEG/JFIF file, or the standard input if no file is +named, and produces a JPEG/JFIF file on the standard output. +.SH OPTIONS +All switch names may be abbreviated; for example, +.B \-optimize +may be written +.B \-opt +or +.BR \-o . +Upper and lower case are equivalent. +British spellings are also accepted (e.g., +.BR \-optimise ), +though for brevity these are not mentioned below. +.PP +To specify the coded JPEG representation used in the output file, +.B jpegtran +accepts a subset of the switches recognized by +.BR cjpeg : +.TP +.B \-optimize +Perform optimization of entropy encoding parameters. +.TP +.B \-progressive +Create progressive JPEG file. +.TP +.BI \-restart " N" +Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is +attached to the number. +.TP +.BI \-scans " file" +Use the scan script given in the specified text file. +.PP +See +.BR cjpeg (1) +for more details about these switches. +If you specify none of these switches, you get a plain baseline-JPEG output +file. The quality setting and so forth are determined by the input file. +.PP +The image can be losslessly transformed by giving one of these switches: +.TP +.B \-flip horizontal +Mirror image horizontally (left-right). +.TP +.B \-flip vertical +Mirror image vertically (top-bottom). +.TP +.B \-rotate 90 +Rotate image 90 degrees clockwise. +.TP +.B \-rotate 180 +Rotate image 180 degrees. +.TP +.B \-rotate 270 +Rotate image 270 degrees clockwise (or 90 ccw). +.TP +.B \-transpose +Transpose image (across UL-to-LR axis). +.TP +.B \-transverse +Transverse transpose (across UR-to-LL axis). +.PP +The transpose transformation has no restrictions regarding image dimensions. +The other transformations operate rather oddly if the image dimensions are not +a multiple of the iMCU size (usually 8 or 16 pixels), because they can only +transform complete blocks of DCT coefficient data in the desired way. +.PP +.BR jpegtran 's +default behavior when transforming an odd-size image is designed +to preserve exact reversibility and mathematical consistency of the +transformation set. As stated, transpose is able to flip the entire image +area. Horizontal mirroring leaves any partial iMCU column at the right edge +untouched, but is able to flip all rows of the image. Similarly, vertical +mirroring leaves any partial iMCU row at the bottom edge untouched, but is +able to flip all columns. The other transforms can be built up as sequences +of transpose and flip operations; for consistency, their actions on edge +pixels are defined to be the same as the end result of the corresponding +transpose-and-flip sequence. +.PP +For practical use, you may prefer to discard any untransformable edge pixels +rather than having a strange-looking strip along the right and/or bottom edges +of a transformed image. To do this, add the +.B \-trim +switch: +.TP +.B \-trim +Drop non-transformable edge blocks. +.PP +Obviously, a transformation with +.B \-trim +is not reversible, so strictly speaking +.B jpegtran +with this switch is not lossless. Also, the expected mathematical +equivalences between the transformations no longer hold. For example, +.B \-rot 270 -trim +trims only the bottom edge, but +.B \-rot 90 -trim +followed by +.B \-rot 180 -trim +trims both edges. +.PP +Another not-strictly-lossless transformation switch is: +.TP +.B \-grayscale +Force grayscale output. +.PP +This option discards the chrominance channels if the input image is YCbCr +(ie, a standard color JPEG), resulting in a grayscale JPEG file. The +luminance channel is preserved exactly, so this is a better method of reducing +to grayscale than decompression, conversion, and recompression. This switch +is particularly handy for fixing a monochrome picture that was mistakenly +encoded as a color JPEG. (In such a case, the space savings from getting rid +of the near-empty chroma channels won't be large; but the decoding time for +a grayscale JPEG is substantially less than that for a color JPEG.) +.PP +.B jpegtran +also recognizes these switches that control what to do with "extra" markers, +such as comment blocks: +.TP +.B \-copy none +Copy no extra markers from source file. This setting suppresses all +comments and other excess baggage present in the source file. +.TP +.B \-copy comments +Copy only comment markers. This setting copies comments from the source file, +but discards any other inessential data. +.TP +.B \-copy all +Copy all extra markers. This setting preserves miscellaneous markers +found in the source file, such as JFIF thumbnails and Photoshop settings. +In some files these extra markers can be sizable. +.PP +The default behavior is +.BR "\-copy comments" . +(Note: in IJG releases v6 and v6a, +.B jpegtran +always did the equivalent of +.BR "\-copy none" .) +.PP +Additional switches recognized by jpegtran are: +.TP +.BI \-maxmemory " N" +Set limit for amount of memory to use in processing large images. Value is +in thousands of bytes, or millions of bytes if "M" is attached to the +number. For example, +.B \-max 4m +selects 4000000 bytes. If more space is needed, temporary files will be used. +.TP +.BI \-outfile " name" +Send output image to the named file, not to standard output. +.TP +.B \-verbose +Enable debug printout. More +.BR \-v 's +give more output. Also, version information is printed at startup. +.TP +.B \-debug +Same as +.BR \-verbose . +.SH EXAMPLES +.LP +This example converts a baseline JPEG file to progressive form: +.IP +.B jpegtran \-progressive +.I foo.jpg +.B > +.I fooprog.jpg +.PP +This example rotates an image 90 degrees clockwise, discarding any +unrotatable edge pixels: +.IP +.B jpegtran \-rot 90 -trim +.I foo.jpg +.B > +.I foo90.jpg +.SH ENVIRONMENT +.TP +.B JPEGMEM +If this environment variable is set, its value is the default memory limit. +The value is specified as described for the +.B \-maxmemory +switch. +.B JPEGMEM +overrides the default value specified when the program was compiled, and +itself is overridden by an explicit +.BR \-maxmemory . +.SH SEE ALSO +.BR cjpeg (1), +.BR djpeg (1), +.BR rdjpgcom (1), +.BR wrjpgcom (1) +.br +Wallace, Gregory K. "The JPEG Still Picture Compression Standard", +Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44. +.SH AUTHOR +Independent JPEG Group +.SH BUGS +Arithmetic coding is not supported for legal reasons. +.PP +The transform options can't transform odd-size images perfectly. Use +.B \-trim +if you don't like the results without it. +.PP +The entire image is read into memory and then written out again, even in +cases where this isn't really necessary. Expect swapping on large images, +especially when using the more complex transform options. diff --git a/src/dep/src/irrlicht/jpeglib/jpegtran.c b/src/dep/src/irrlicht/jpeglib/jpegtran.c new file mode 100644 index 0000000..719aaa7 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jpegtran.c @@ -0,0 +1,504 @@ +/* + * jpegtran.c + * + * Copyright (C) 1995-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a command-line user interface for JPEG transcoding. + * It is very similar to cjpeg.c, but provides lossless transcoding between + * different JPEG file formats. It also provides some lossless and sort-of- + * lossless transformations of JPEG data. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include "transupp.h" /* Support routines for jpegtran */ +#include "jversion.h" /* for version message */ + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + + +/* + * Argument-parsing code. + * The switch parser is designed to be useful with DOS-style command line + * syntax, ie, intermixed switches and file names, where only the switches + * to the left of a given file name affect processing of that file. + * The main program in this file doesn't actually use this capability... + */ + + +static const char * progname; /* program name for error messages */ +static char * outfilename; /* for -outfile switch */ +static JCOPY_OPTION copyoption; /* -copy switch */ +static jpeg_transform_info transformoption; /* image transformation options */ + + +LOCAL(void) +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -copy none Copy no extra markers from source file\n"); + fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); + fprintf(stderr, " -copy all Copy all extra markers\n"); +#ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); +#endif +#ifdef C_PROGRESSIVE_SUPPORTED + fprintf(stderr, " -progressive Create progressive JPEG file\n"); +#endif +#if TRANSFORMS_SUPPORTED + fprintf(stderr, "Switches for modifying the image:\n"); + fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n"); + fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n"); + fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n"); + fprintf(stderr, " -transpose Transpose image\n"); + fprintf(stderr, " -transverse Transverse transpose image\n"); + fprintf(stderr, " -trim Drop non-transformable edge blocks\n"); +#endif /* TRANSFORMS_SUPPORTED */ + fprintf(stderr, "Switches for advanced users:\n"); + fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); + fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); + fprintf(stderr, " -outfile name Specify name for output file\n"); + fprintf(stderr, " -verbose or -debug Emit debug output\n"); + fprintf(stderr, "Switches for wizards:\n"); +#ifdef C_ARITH_CODING_SUPPORTED + fprintf(stderr, " -arithmetic Use arithmetic coding\n"); +#endif +#ifdef C_MULTISCAN_FILES_SUPPORTED + fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); +#endif + exit(EXIT_FAILURE); +} + + +LOCAL(void) +select_transform (JXFORM_CODE transform) +/* Silly little routine to detect multiple transform options, + * which we can't handle. + */ +{ +#if TRANSFORMS_SUPPORTED + if (transformoption.transform == JXFORM_NONE || + transformoption.transform == transform) { + transformoption.transform = transform; + } else { + fprintf(stderr, "%s: can only do one image transformation at a time\n", + progname); + usage(); + } +#else + fprintf(stderr, "%s: sorry, image transformation was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif +} + + +LOCAL(int) +parse_switches (j_compress_ptr cinfo, int argc, char **argv, + int last_file_arg_seen, boolean for_real) +/* Parse optional switches. + * Returns argv[] index of first file-name argument (== argc if none). + * Any file names with indexes <= last_file_arg_seen are ignored; + * they have presumably been processed in a previous iteration. + * (Pass 0 for last_file_arg_seen on the first or only iteration.) + * for_real is FALSE on the first (dummy) pass; we may skip any expensive + * processing. + */ +{ + int argn; + char * arg; + boolean simple_progressive; + char * scansarg = NULL; /* saves -scans parm if any */ + + /* Set up default JPEG parameters. */ + simple_progressive = FALSE; + outfilename = NULL; + copyoption = JCOPYOPT_DEFAULT; + transformoption.transform = JXFORM_NONE; + transformoption.trim = FALSE; + transformoption.force_grayscale = FALSE; + cinfo->err->trace_level = 0; + + /* Scan command line options, adjust parameters */ + + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (*arg != '-') { + /* Not a switch, must be a file name argument */ + if (argn <= last_file_arg_seen) { + outfilename = NULL; /* -outfile applies to just one input file */ + continue; /* ignore this name if previously processed */ + } + break; /* else done parsing switches */ + } + arg++; /* advance past switch marker character */ + + if (keymatch(arg, "arithmetic", 1)) { + /* Use arithmetic coding. */ +#ifdef C_ARITH_CODING_SUPPORTED + cinfo->arith_code = TRUE; +#else + fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "copy", 1)) { + /* Select which extra markers to copy. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "none", 1)) { + copyoption = JCOPYOPT_NONE; + } else if (keymatch(argv[argn], "comments", 1)) { + copyoption = JCOPYOPT_COMMENTS; + } else if (keymatch(argv[argn], "all", 1)) { + copyoption = JCOPYOPT_ALL; + } else + usage(); + + } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { + /* Enable debug printouts. */ + /* On first -d, print version identification */ + static boolean printed_version = FALSE; + + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", + JVERSION, JCOPYRIGHT); + printed_version = TRUE; + } + cinfo->err->trace_level++; + + } else if (keymatch(arg, "flip", 1)) { + /* Mirror left-right or top-bottom. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "horizontal", 1)) + select_transform(JXFORM_FLIP_H); + else if (keymatch(argv[argn], "vertical", 1)) + select_transform(JXFORM_FLIP_V); + else + usage(); + + } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) { + /* Force to grayscale. */ +#if TRANSFORMS_SUPPORTED + transformoption.force_grayscale = TRUE; +#else + select_transform(JXFORM_NONE); /* force an error */ +#endif + + } else if (keymatch(arg, "maxmemory", 3)) { + /* Maximum memory in Kb (or Mb with 'm'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (ch == 'm' || ch == 'M') + lval *= 1000L; + cinfo->mem->max_memory_to_use = lval * 1000L; + + } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { + /* Enable entropy parm optimization. */ +#ifdef ENTROPY_OPT_SUPPORTED + cinfo->optimize_coding = TRUE; +#else + fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "outfile", 4)) { + /* Set output file name. */ + if (++argn >= argc) /* advance to next argument */ + usage(); + outfilename = argv[argn]; /* save it away for later use */ + + } else if (keymatch(arg, "progressive", 1)) { + /* Select simple progressive mode. */ +#ifdef C_PROGRESSIVE_SUPPORTED + simple_progressive = TRUE; + /* We must postpone execution until num_components is known. */ +#else + fprintf(stderr, "%s: sorry, progressive output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "restart", 1)) { + /* Restart interval in MCU rows (or in MCUs with 'b'). */ + long lval; + char ch = 'x'; + + if (++argn >= argc) /* advance to next argument */ + usage(); + if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) + usage(); + if (lval < 0 || lval > 65535L) + usage(); + if (ch == 'b' || ch == 'B') { + cinfo->restart_interval = (unsigned int) lval; + cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ + } else { + cinfo->restart_in_rows = (int) lval; + /* restart_interval will be computed during startup */ + } + + } else if (keymatch(arg, "rotate", 2)) { + /* Rotate 90, 180, or 270 degrees (measured clockwise). */ + if (++argn >= argc) /* advance to next argument */ + usage(); + if (keymatch(argv[argn], "90", 2)) + select_transform(JXFORM_ROT_90); + else if (keymatch(argv[argn], "180", 3)) + select_transform(JXFORM_ROT_180); + else if (keymatch(argv[argn], "270", 3)) + select_transform(JXFORM_ROT_270); + else + usage(); + + } else if (keymatch(arg, "scans", 1)) { + /* Set scan script. */ +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (++argn >= argc) /* advance to next argument */ + usage(); + scansarg = argv[argn]; + /* We must postpone reading the file in case -progressive appears. */ +#else + fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", + progname); + exit(EXIT_FAILURE); +#endif + + } else if (keymatch(arg, "transpose", 1)) { + /* Transpose (across UL-to-LR axis). */ + select_transform(JXFORM_TRANSPOSE); + + } else if (keymatch(arg, "transverse", 6)) { + /* Transverse transpose (across UR-to-LL axis). */ + select_transform(JXFORM_TRANSVERSE); + + } else if (keymatch(arg, "trim", 3)) { + /* Trim off any partial edge MCUs that the transform can't handle. */ + transformoption.trim = TRUE; + + } else { + usage(); /* bogus switch */ + } + } + + /* Post-switch-scanning cleanup */ + + if (for_real) { + +#ifdef C_PROGRESSIVE_SUPPORTED + if (simple_progressive) /* process -progressive; -scans can override */ + jpeg_simple_progression(cinfo); +#endif + +#ifdef C_MULTISCAN_FILES_SUPPORTED + if (scansarg != NULL) /* process -scans if it was present */ + if (! read_scan_script(cinfo, scansarg)) + usage(); +#endif + } + + return argn; /* return index of next arg (file name) */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + struct jpeg_decompress_struct srcinfo; + struct jpeg_compress_struct dstinfo; + struct jpeg_error_mgr jsrcerr, jdsterr; +#ifdef PROGRESS_REPORT + struct cdjpeg_progress_mgr progress; +#endif + jvirt_barray_ptr * src_coef_arrays; + jvirt_barray_ptr * dst_coef_arrays; + int file_index; + FILE * input_file; + FILE * output_file; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "jpegtran"; /* in case C library doesn't provide it */ + + /* Initialize the JPEG decompression object with default error handling. */ + srcinfo.err = jpeg_std_error(&jsrcerr); + jpeg_create_decompress(&srcinfo); + /* Initialize the JPEG compression object with default error handling. */ + dstinfo.err = jpeg_std_error(&jdsterr); + jpeg_create_compress(&dstinfo); + + /* Now safe to enable signal catcher. + * Note: we assume only the decompression object will have virtual arrays. + */ +#ifdef NEED_SIGNAL_CATCHER + enable_signal_catcher((j_common_ptr) &srcinfo); +#endif + + /* Scan command line to find file names. + * It is convenient to use just one switch-parsing routine, but the switch + * values read here are mostly ignored; we will rescan the switches after + * opening the input file. Also note that most of the switches affect the + * destination JPEG object, so we parse into that and then copy over what + * needs to affects the source too. + */ + + file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); + jsrcerr.trace_level = jdsterr.trace_level; + srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; + +#ifdef TWO_FILE_COMMANDLINE + /* Must have either -outfile switch or explicit output file name */ + if (outfilename == NULL) { + if (file_index != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + outfilename = argv[file_index+1]; + } else { + if (file_index != argc-1) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + } +#else + /* Unix style: expect zero or one file name */ + if (file_index < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } +#endif /* TWO_FILE_COMMANDLINE */ + + /* Open the input file. */ + if (file_index < argc) { + if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ + input_file = read_stdin(); + } + + /* Open the output file. */ + if (outfilename != NULL) { + if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, outfilename); + exit(EXIT_FAILURE); + } + } else { + /* default output file is stdout */ + output_file = write_stdout(); + } + +#ifdef PROGRESS_REPORT + start_progress_monitor((j_common_ptr) &dstinfo, &progress); +#endif + + /* Specify data source for decompression */ + jpeg_stdio_src(&srcinfo, input_file); + + /* Enable saving of extra markers that we want to copy */ + jcopy_markers_setup(&srcinfo, copyoption); + + /* Read file header */ + (void) jpeg_read_header(&srcinfo, TRUE); + + /* Any space needed by a transform option must be requested before + * jpeg_read_coefficients so that memory allocation will be done right. + */ +#if TRANSFORMS_SUPPORTED + jtransform_request_workspace(&srcinfo, &transformoption); +#endif + + /* Read source file as DCT coefficients */ + src_coef_arrays = jpeg_read_coefficients(&srcinfo); + + /* Initialize destination compression parameters from source values */ + jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + + /* Adjust destination parameters if required by transform options; + * also find out which set of coefficient arrays will hold the output. + */ +#if TRANSFORMS_SUPPORTED + dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#else + dst_coef_arrays = src_coef_arrays; +#endif + + /* Adjust default compression parameters by re-parsing the options */ + file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); + + /* Specify data destination for compression */ + jpeg_stdio_dest(&dstinfo, output_file); + + /* Start compressor (note no image data is actually written here) */ + jpeg_write_coefficients(&dstinfo, dst_coef_arrays); + + /* Copy to the output file any extra markers that we want to preserve */ + jcopy_markers_execute(&srcinfo, &dstinfo, copyoption); + + /* Execute image transformation, if any */ +#if TRANSFORMS_SUPPORTED + jtransform_execute_transformation(&srcinfo, &dstinfo, + src_coef_arrays, + &transformoption); +#endif + + /* Finish compression and release memory */ + jpeg_finish_compress(&dstinfo); + jpeg_destroy_compress(&dstinfo); + (void) jpeg_finish_decompress(&srcinfo); + jpeg_destroy_decompress(&srcinfo); + + /* Close files, if we opened them */ + if (input_file != stdin) + fclose(input_file); + if (output_file != stdout) + fclose(output_file); + +#ifdef PROGRESS_REPORT + end_progress_monitor((j_common_ptr) &dstinfo); +#endif + + /* All done. */ + exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/src/dep/src/irrlicht/jpeglib/jquant1.c b/src/dep/src/irrlicht/jpeglib/jquant1.c new file mode 100644 index 0000000..aaa34a1 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jquant1.c @@ -0,0 +1,856 @@ +/* + * jquant1.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 1-pass color quantization (color mapping) routines. + * These routines provide mapping to a fixed color map using equally spaced + * color values. Optional Floyd-Steinberg or ordered dithering is available. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_1PASS_SUPPORTED + + +/* + * The main purpose of 1-pass quantization is to provide a fast, if not very + * high quality, colormapped output capability. A 2-pass quantizer usually + * gives better visual quality; however, for quantized grayscale output this + * quantizer is perfectly adequate. Dithering is highly recommended with this + * quantizer, though you can turn it off if you really want to. + * + * In 1-pass quantization the colormap must be chosen in advance of seeing the + * image. We use a map consisting of all combinations of Ncolors[i] color + * values for the i'th component. The Ncolors[] values are chosen so that + * their product, the total number of colors, is no more than that requested. + * (In most cases, the product will be somewhat less.) + * + * Since the colormap is orthogonal, the representative value for each color + * component can be determined without considering the other components; + * then these indexes can be combined into a colormap index by a standard + * N-dimensional-array-subscript calculation. Most of the arithmetic involved + * can be precalculated and stored in the lookup table colorindex[]. + * colorindex[i][j] maps pixel value j in component i to the nearest + * representative value (grid plane) for that component; this index is + * multiplied by the array stride for component i, so that the + * index of the colormap entry closest to a given pixel value is just + * sum( colorindex[component-number][pixel-component-value] ) + * Aside from being fast, this scheme allows for variable spacing between + * representative values with no additional lookup cost. + * + * If gamma correction has been applied in color conversion, it might be wise + * to adjust the color grid spacing so that the representative colors are + * equidistant in linear space. At this writing, gamma correction is not + * implemented by jdcolor, so nothing is done here. + */ + + +/* Declarations for ordered dithering. + * + * We use a standard 16x16 ordered dither array. The basic concept of ordered + * dithering is described in many references, for instance Dale Schumacher's + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + * In place of Schumacher's comparisons against a "threshold" value, we add a + * "dither" value to the input pixel and then round the result to the nearest + * output value. The dither value is equivalent to (0.5 - threshold) times + * the distance between output values. For ordered dithering, we assume that + * the output colors are equally spaced; if not, results will probably be + * worse, since the dither may be too much or too little at a given point. + * + * The normal calculation would be to form pixel value + dither, range-limit + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + * We can skip the separate range-limiting step by extending the colorindex + * table in both directions. + */ + +#define ODITHER_SIZE 16 /* dimension of dither matrix */ +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ +#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ + +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; + +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { + /* Bayer's order-4 dither array. Generated by the code given in + * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + * The values in this array must range from 0 to ODITHER_CELLS-1. + */ + { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, + { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, + { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, + { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, + { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, + { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, + { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, + { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, + { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, + { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, + { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, + { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, + { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, + { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, + { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, + { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } +}; + + +/* Declarations for Floyd-Steinberg dithering. + * + * Errors are accumulated into the array fserrors[], at a resolution of + * 1/16th of a pixel count. The error at a given pixel is propagated + * to its not-yet-processed neighbors using the standard F-S fractions, + * ... (here) 7/16 + * 3/16 5/16 1/16 + * We work left-to-right on even rows, right-to-left on odd rows. + * + * We can get away with a single array (holding one row's worth of errors) + * by using it to store the current row's errors at pixel columns not yet + * processed, but the next row's errors at columns already processed. We + * need only a few extra variables to hold the errors immediately around the + * current column. (If we are lucky, those variables are in registers, but + * even if not, they're probably cheaper to access than array elements are.) + * + * The fserrors[] array is indexed [component#][position]. + * We provide (#columns + 2) entries per component; the extra entry at each + * end saves us from special-casing the first and last pixels. + * + * Note: on a wide image, we might not have enough room in a PC's near data + * segment to hold the error array; so it is allocated with alloc_large. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef INT16 FSERROR; /* 16 bits should be enough */ +typedef int LOCFSERROR; /* use 'int' for calculation temps */ +#else +typedef INT32 FSERROR; /* may need more than 16 bits */ +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ +#endif + +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ + + +/* Private subobject */ + +#define MAX_Q_COMPS 4 /* max components I can handle */ + +typedef struct { + struct jpeg_color_quantizer pub; /* public fields */ + + /* Initially allocated colormap is saved here */ + JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ + int sv_actual; /* number of entries in use */ + + JSAMPARRAY colorindex; /* Precomputed mapping for speed */ + /* colorindex[i][j] = index of color closest to pixel value j in component i, + * premultiplied as described above. Since colormap indexes must fit into + * JSAMPLEs, the entries of this array will too. + */ + boolean is_padded; /* is the colorindex padded for odither? */ + + int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ + + /* Variables for ordered dithering */ + int row_index; /* cur row's vertical index in dither matrix */ + ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ + + /* Variables for Floyd-Steinberg dithering */ + FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ + boolean on_odd_row; /* flag to remember which row we are on */ +} my_cquantizer; + +typedef my_cquantizer * my_cquantize_ptr; + + +/* + * Policy-making subroutines for create_colormap and create_colorindex. + * These routines determine the colormap to be used. The rest of the module + * only assumes that the colormap is orthogonal. + * + * * select_ncolors decides how to divvy up the available colors + * among the components. + * * output_value defines the set of representative values for a component. + * * largest_input_value defines the mapping from input values to + * representative values for a component. + * Note that the latter two routines may impose different policies for + * different components, though this is not currently done. + */ + + +LOCAL(int) +select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) +/* Determine allocation of desired colors to components, */ +/* and fill in Ncolors[] array to indicate choice. */ +/* Return value is total number of colors (product of Ncolors[] values). */ +{ + int nc = cinfo->out_color_components; /* number of color components */ + int max_colors = cinfo->desired_number_of_colors; + int total_colors, iroot, i, j; + boolean changed; + long temp; + static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; + + /* We can allocate at least the nc'th root of max_colors per component. */ + /* Compute floor(nc'th root of max_colors). */ + iroot = 1; + do { + iroot++; + temp = iroot; /* set temp = iroot ** nc */ + for (i = 1; i < nc; i++) + temp *= iroot; + } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ + iroot--; /* now iroot = floor(root) */ + + /* Must have at least 2 color values per component */ + if (iroot < 2) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); + + /* Initialize to iroot color values for each component */ + total_colors = 1; + for (i = 0; i < nc; i++) { + Ncolors[i] = iroot; + total_colors *= iroot; + } + /* We may be able to increment the count for one or more components without + * exceeding max_colors, though we know not all can be incremented. + * Sometimes, the first component can be incremented more than once! + * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + * In RGB colorspace, try to increment G first, then R, then B. + */ + do { + changed = FALSE; + for (i = 0; i < nc; i++) { + j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); + /* calculate new total_colors if Ncolors[j] is incremented */ + temp = total_colors / Ncolors[j]; + temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ + if (temp > (long) max_colors) + break; /* won't fit, done with this pass */ + Ncolors[j]++; /* OK, apply the increment */ + total_colors = (int) temp; + changed = TRUE; + } + } while (changed); + + return total_colors; +} + + +LOCAL(int) +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return j'th output value, where j will range from 0 to maxj */ +/* The output values must fall in 0..MAXJSAMPLE in increasing order */ +{ + /* We always provide values 0 and MAXJSAMPLE for each component; + * any additional values are equally spaced between these limits. + * (Forcing the upper and lower values to the limits ensures that + * dithering can't produce a color outside the selected gamut.) + */ + return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); +} + + +LOCAL(int) +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) +/* Return largest input value that should map to j'th output value */ +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ +{ + /* Breakpoints are halfway between values returned by output_value */ + return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); +} + + +/* + * Create the colormap. + */ + +LOCAL(void) +create_colormap (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colormap; /* Created colormap */ + int total_colors; /* Number of distinct output colors */ + int i,j,k, nci, blksize, blkdist, ptr, val; + + /* Select number of colors for each component */ + total_colors = select_ncolors(cinfo, cquantize->Ncolors); + + /* Report selected color counts */ + if (cinfo->out_color_components == 3) + TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize->Ncolors[0], + cquantize->Ncolors[1], cquantize->Ncolors[2]); + else + TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); + + /* Allocate and fill in the colormap. */ + /* The colors are ordered in the map in standard row-major order, */ + /* i.e. rightmost (highest-indexed) color changes most rapidly. */ + + colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + /* blkdist is distance between groups of identical entries for a component */ + blkdist = total_colors; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colormap entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blkdist / nci; + for (j = 0; j < nci; j++) { + /* Compute j'th output value (out of nci) for component */ + val = output_value(cinfo, i, j, nci-1); + /* Fill in all colormap entries that have this value of this component */ + for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { + /* fill in blksize entries beginning at ptr */ + for (k = 0; k < blksize; k++) + colormap[i][ptr+k] = (JSAMPLE) val; + } + } + blkdist = blksize; /* blksize of this color is blkdist of next */ + } + + /* Save the colormap in private storage, + * where it will survive color quantization mode changes. + */ + cquantize->sv_colormap = colormap; + cquantize->sv_actual = total_colors; +} + + +/* + * Create the color index table. + */ + +LOCAL(void) +create_colorindex (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPROW indexptr; + int i,j,k, nci, blksize, val, pad; + + /* For ordered dither, we pad the color index tables by MAXJSAMPLE in + * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + * This is not necessary in the other dithering modes. However, we + * flag whether it was done in case user changes dithering mode. + */ + if (cinfo->dither_mode == JDITHER_ORDERED) { + pad = MAXJSAMPLE*2; + cquantize->is_padded = TRUE; + } else { + pad = 0; + cquantize->is_padded = FALSE; + } + + cquantize->colorindex = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1 + pad), + (JDIMENSION) cinfo->out_color_components); + + /* blksize is number of adjacent repeated entries for a component */ + blksize = cquantize->sv_actual; + + for (i = 0; i < cinfo->out_color_components; i++) { + /* fill in colorindex entries for i'th color component */ + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + blksize = blksize / nci; + + /* adjust colorindex pointers to provide padding at negative indexes. */ + if (pad) + cquantize->colorindex[i] += MAXJSAMPLE; + + /* in loop, val = index of current output value, */ + /* and k = largest j that maps to current val */ + indexptr = cquantize->colorindex[i]; + val = 0; + k = largest_input_value(cinfo, i, 0, nci-1); + for (j = 0; j <= MAXJSAMPLE; j++) { + while (j > k) /* advance val if past boundary */ + k = largest_input_value(cinfo, i, ++val, nci-1); + /* premultiply so that no multiplication needed in main processing */ + indexptr[j] = (JSAMPLE) (val * blksize); + } + /* Pad at both ends if necessary */ + if (pad) + for (j = 1; j <= MAXJSAMPLE; j++) { + indexptr[-j] = indexptr[0]; + indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; + } + } +} + + +/* + * Create an ordered-dither array for a component having ncolors + * distinct output values. + */ + +LOCAL(ODITHER_MATRIX_PTR) +make_odither_array (j_decompress_ptr cinfo, int ncolors) +{ + ODITHER_MATRIX_PTR odither; + int j,k; + INT32 num,den; + + odither = (ODITHER_MATRIX_PTR) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX)); + /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + * Hence the dither value for the matrix cell with fill order f + * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + * On 16-bit-int machine, be careful to avoid overflow. + */ + den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); + for (j = 0; j < ODITHER_SIZE; j++) { + for (k = 0; k < ODITHER_SIZE; k++) { + num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) + * MAXJSAMPLE; + /* Ensure round towards zero despite C's lack of consistency + * about rounding negative values in integer division... + */ + odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); + } + } + return odither; +} + + +/* + * Create the ordered-dither tables. + * Components having the same number of representative colors may + * share a dither table. + */ + +LOCAL(void) +create_odither_tables (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + ODITHER_MATRIX_PTR odither; + int i, j, nci; + + for (i = 0; i < cinfo->out_color_components; i++) { + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ + odither = NULL; /* search for matching prior component */ + for (j = 0; j < i; j++) { + if (nci == cquantize->Ncolors[j]) { + odither = cquantize->odither[j]; + break; + } + } + if (odither == NULL) /* need a new table? */ + odither = make_odither_array(cinfo, nci); + cquantize->odither[i] = odither; + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + JSAMPARRAY colorindex = cquantize->colorindex; + register int pixcode, ci; + register JSAMPROW ptrin, ptrout; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + register int nc = cinfo->out_color_components; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = 0; + for (ci = 0; ci < nc; ci++) { + pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); + } + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW ptrin, ptrout; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptrin = input_buf[row]; + ptrout = output_buf[row]; + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); + *ptrout++ = (JSAMPLE) pixcode; + } + } +} + + +METHODDEF(void) +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + int * dither; /* points to active row of dither matrix */ + int row_index, col_index; /* current indexes into dither matrix */ + int nc = cinfo->out_color_components; + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + row_index = cquantize->row_index; + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + colorindex_ci = cquantize->colorindex[ci]; + dither = cquantize->odither[ci][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + * select output value, accumulate into output code for this pixel. + * Range-limiting need not be done explicitly, as we have extended + * the colorindex table to produce the right answers for out-of-range + * inputs. The maximum dither is +- MAXJSAMPLE; this sets the + * required amount of padding. + */ + *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; + input_ptr += nc; + output_ptr++; + col_index = (col_index + 1) & ODITHER_MASK; + } + } + /* Advance row index for next row */ + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* Fast path for out_color_components==3, with ordered dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register int pixcode; + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex0 = cquantize->colorindex[0]; + JSAMPROW colorindex1 = cquantize->colorindex[1]; + JSAMPROW colorindex2 = cquantize->colorindex[2]; + int * dither0; /* points to active row of dither matrix */ + int * dither1; + int * dither2; + int row_index, col_index; /* current indexes into dither matrix */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + row_index = cquantize->row_index; + input_ptr = input_buf[row]; + output_ptr = output_buf[row]; + dither0 = cquantize->odither[0][row_index]; + dither1 = cquantize->odither[1][row_index]; + dither2 = cquantize->odither[2][row_index]; + col_index = 0; + + for (col = width; col > 0; col--) { + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + + dither0[col_index]]); + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + + dither1[col_index]]); + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + + dither2[col_index]]); + *output_ptr++ = (JSAMPLE) pixcode; + col_index = (col_index + 1) & ODITHER_MASK; + } + row_index = (row_index + 1) & ODITHER_MASK; + cquantize->row_index = row_index; + } +} + + +METHODDEF(void) +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +/* General case, with Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + register LOCFSERROR cur; /* current error or pixel value */ + LOCFSERROR belowerr; /* error for pixel below cur */ + LOCFSERROR bpreverr; /* error for below/prev col */ + LOCFSERROR bnexterr; /* error for below/next col */ + LOCFSERROR delta; + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + register JSAMPROW input_ptr; + register JSAMPROW output_ptr; + JSAMPROW colorindex_ci; + JSAMPROW colormap_ci; + int pixcode; + int nc = cinfo->out_color_components; + int dir; /* 1 for left-to-right, -1 for right-to-left */ + int dirnc; /* dir * nc */ + int ci; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + /* Initialize output values to 0 so can process components separately */ + jzero_far((void FAR *) output_buf[row], + (size_t) (width * SIZEOF(JSAMPLE))); + for (ci = 0; ci < nc; ci++) { + input_ptr = input_buf[row] + ci; + output_ptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + input_ptr += (width-1) * nc; /* so point to rightmost pixel */ + output_ptr += width-1; + dir = -1; + dirnc = -nc; + errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ + } else { + /* work left to right in this row */ + dir = 1; + dirnc = nc; + errorptr = cquantize->fserrors[ci]; /* => entry before first column */ + } + colorindex_ci = cquantize->colorindex[ci]; + colormap_ci = cquantize->sv_colormap[ci]; + /* Preset error values: no error propagated to first pixel from left */ + cur = 0; + /* and no error propagated to row below yet */ + belowerr = bpreverr = 0; + + for (col = width; col > 0; col--) { + /* cur holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE; this sets the required size + * of the range_limit array. + */ + cur += GETJSAMPLE(*input_ptr); + cur = GETJSAMPLE(range_limit[cur]); + /* Select output value, accumulate into output code for this pixel */ + pixcode = GETJSAMPLE(colorindex_ci[cur]); + *output_ptr += (JSAMPLE) pixcode; + /* Compute actual representation error at this pixel */ + /* Note: we can do this even though we don't have the final */ + /* pixel code, because the colormap is orthogonal. */ + cur -= GETJSAMPLE(colormap_ci[pixcode]); + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + bnexterr = cur; + delta = cur * 2; + cur += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr + cur); + cur += delta; /* form error * 5 */ + bpreverr = belowerr + cur; + belowerr = bnexterr; + cur += delta; /* form error * 7 */ + /* At this point cur contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + input_ptr += dirnc; /* advance input ptr to next column */ + output_ptr += dir; /* advance output ptr to next column */ + errorptr += dir; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error value into the + * final fserrors[] entry. Note we need not unload belowerr because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ + } + cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); + } +} + + +/* + * Allocate workspace for Floyd-Steinberg errors. + */ + +LOCAL(void) +alloc_fs_workspace (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) { + cquantize->fserrors[i] = (FSERRPTR) + (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + } +} + + +/* + * Initialize for one-pass color quantization. + */ + +METHODDEF(void) +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + size_t arraysize; + int i; + + /* Install my colormap. */ + cinfo->colormap = cquantize->sv_colormap; + cinfo->actual_number_of_colors = cquantize->sv_actual; + + /* Initialize for desired dithering mode. */ + switch (cinfo->dither_mode) { + case JDITHER_NONE: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = color_quantize3; + else + cquantize->pub.color_quantize = color_quantize; + break; + case JDITHER_ORDERED: + if (cinfo->out_color_components == 3) + cquantize->pub.color_quantize = quantize3_ord_dither; + else + cquantize->pub.color_quantize = quantize_ord_dither; + cquantize->row_index = 0; /* initialize state for ordered dither */ + /* If user changed to ordered dither from another mode, + * we must recreate the color index table with padding. + * This will cost extra space, but probably isn't very likely. + */ + if (! cquantize->is_padded) + create_colorindex(cinfo); + /* Create ordered-dither tables if we didn't already. */ + if (cquantize->odither[0] == NULL) + create_odither_tables(cinfo); + break; + case JDITHER_FS: + cquantize->pub.color_quantize = quantize_fs_dither; + cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ + /* Allocate Floyd-Steinberg workspace if didn't already. */ + if (cquantize->fserrors[0] == NULL) + alloc_fs_workspace(cinfo); + /* Initialize the propagated errors to zero. */ + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); + for (i = 0; i < cinfo->out_color_components; i++) + jzero_far((void FAR *) cquantize->fserrors[i], arraysize); + break; + default: + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; + } +} + + +/* + * Finish up at the end of the pass. + */ + +METHODDEF(void) +finish_pass_1_quant (j_decompress_ptr cinfo) +{ + /* no work in 1-pass case */ +} + + +/* + * Switch to a new external colormap between output passes. + * Shouldn't get to this module! + */ + +METHODDEF(void) +new_color_map_1_quant (j_decompress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_MODE_CHANGE); +} + + +/* + * Module initialization routine for 1-pass color quantization. + */ + +GLOBAL(void) +jinit_1pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_1_quant; + cquantize->pub.finish_pass = finish_pass_1_quant; + cquantize->pub.new_color_map = new_color_map_1_quant; + cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ + cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ + + /* Make sure my internal arrays won't overflow */ + if (cinfo->out_color_components > MAX_Q_COMPS) + ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + /* Create the colormap and color index table. */ + create_colormap(cinfo); + create_colorindex(cinfo); + + /* Allocate Floyd-Steinberg workspace now if requested. + * We do this now since it is FAR storage and may affect the memory + * manager's space calculations. If the user changes to FS dither + * mode in a later pass, we will allocate the space then, and will + * possibly overrun the max_memory_to_use setting. + */ + if (cinfo->dither_mode == JDITHER_FS) + alloc_fs_workspace(cinfo); +} + +#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jquant2.c b/src/dep/src/irrlicht/jpeglib/jquant2.c new file mode 100644 index 0000000..87a3920 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jquant2.c @@ -0,0 +1,1310 @@ +/* + * jquant2.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains 2-pass color quantization (color mapping) routines. + * These routines provide selection of a custom color map for an image, + * followed by mapping of the image to that color map, with optional + * Floyd-Steinberg dithering. + * It is also possible to use just the second pass to map to an arbitrary + * externally-given color map. + * + * Note: ordered dithering is not supported, since there isn't any fast + * way to compute intercolor distances; it's unclear that ordered dither's + * fundamental assumptions even hold with an irregularly spaced color map. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +#ifdef QUANT_2PASS_SUPPORTED + + +/* + * This module implements the well-known Heckbert paradigm for color + * quantization. Most of the ideas used here can be traced back to + * Heckbert's seminal paper + * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + * + * In the first pass over the image, we accumulate a histogram showing the + * usage count of each possible color. To keep the histogram to a reasonable + * size, we reduce the precision of the input; typical practice is to retain + * 5 or 6 bits per color, so that 8 or 4 different input values are counted + * in the same histogram cell. + * + * Next, the color-selection step begins with a box representing the whole + * color space, and repeatedly splits the "largest" remaining box until we + * have as many boxes as desired colors. Then the mean color in each + * remaining box becomes one of the possible output colors. + * + * The second pass over the image maps each input pixel to the closest output + * color (optionally after applying a Floyd-Steinberg dithering correction). + * This mapping is logically trivial, but making it go fast enough requires + * considerable care. + * + * Heckbert-style quantizers vary a good deal in their policies for choosing + * the "largest" box and deciding where to cut it. The particular policies + * used here have proved out well in experimental comparisons, but better ones + * may yet be found. + * + * In earlier versions of the IJG code, this module quantized in YCbCr color + * space, processing the raw upsampled data without a color conversion step. + * This allowed the color conversion math to be done only once per colormap + * entry, not once per pixel. However, that optimization precluded other + * useful optimizations (such as merging color conversion with upsampling) + * and it also interfered with desired capabilities such as quantizing to an + * externally-supplied colormap. We have therefore abandoned that approach. + * The present code works in the post-conversion color space, typically RGB. + * + * To improve the visual quality of the results, we actually work in scaled + * RGB space, giving G distances more weight than R, and R in turn more than + * B. To do everything in integer math, we must use integer scale factors. + * The 2/3/1 scale factors used here correspond loosely to the relative + * weights of the colors in the NTSC grayscale equation. + * If you want to use this code to quantize a non-RGB color space, you'll + * probably need to change these scale factors. + */ + +#define R_SCALE 2 /* scale R distances by this much */ +#define G_SCALE 3 /* scale G distances by this much */ +#define B_SCALE 1 /* and B by this much */ + +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + * and B,G,R orders. If you define some other weird order in jmorecfg.h, + * you'll get compile errors until you extend this logic. In that case + * you'll probably want to tweak the histogram sizes too. + */ + +#if RGB_RED == 0 +#define C0_SCALE R_SCALE +#endif +#if RGB_BLUE == 0 +#define C0_SCALE B_SCALE +#endif +#if RGB_GREEN == 1 +#define C1_SCALE G_SCALE +#endif +#if RGB_RED == 2 +#define C2_SCALE R_SCALE +#endif +#if RGB_BLUE == 2 +#define C2_SCALE B_SCALE +#endif + + +/* + * First we have the histogram data structure and routines for creating it. + * + * The number of bits of precision can be adjusted by changing these symbols. + * We recommend keeping 6 bits for G and 5 each for R and B. + * If you have plenty of memory and cycles, 6 bits all around gives marginally + * better results; if you are short of memory, 5 bits all around will save + * some space but degrade the results. + * To maintain a fully accurate histogram, we'd need to allocate a "long" + * (preferably unsigned long) for each cell. In practice this is overkill; + * we can get by with 16 bits per cell. Few of the cell counts will overflow, + * and clamping those that do overflow to the maximum value will give close- + * enough results. This reduces the recommended histogram size from 256Kb + * to 128Kb, which is a useful savings on PC-class machines. + * (In the second pass the histogram space is re-used for pixel mapping data; + * in that capacity, each cell must be able to store zero to the number of + * desired colors. 16 bits/cell is plenty for that too.) + * Since the JPEG code is intended to run in small memory model on 80x86 + * machines, we can't just allocate the histogram in one chunk. Instead + * of a true 3-D array, we use a row of pointers to 2-D arrays. Each + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + * on 80x86 machines, the pointer row is in near memory but the actual + * arrays are in far memory (same arrangement as we use for image arrays). + */ + +#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ + +/* These will do the right thing for either R,G,B or B,G,R color order, + * but you may not like the results for other color orders. + */ +#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ +#define HIST_C1_BITS 6 /* bits of precision in G histogram */ +#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ + +/* Number of elements along histogram axes. */ +#define HIST_C0_ELEMS (1<cquantize; + register JSAMPROW ptr; + register histptr histp; + register hist3d histogram = cquantize->histogram; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + ptr = input_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the histogram */ + histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] + [GETJSAMPLE(ptr[1]) >> C1_SHIFT] + [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; + /* increment, check for overflow and undo increment if so. */ + if (++(*histp) <= 0) + (*histp)--; + ptr += 3; + } + } +} + + +/* + * Next we have the really interesting routines: selection of a colormap + * given the completed histogram. + * These routines work with a list of "boxes", each representing a rectangular + * subset of the input color space (to histogram precision). + */ + +typedef struct { + /* The bounds of the box (inclusive); expressed as histogram indexes */ + int c0min, c0max; + int c1min, c1max; + int c2min, c2max; + /* The volume (actually 2-norm) of the box */ + INT32 volume; + /* The number of nonzero histogram cells within this box */ + long colorcount; +} box; + +typedef box * boxptr; + + +LOCAL(boxptr) +find_biggest_color_pop (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest color population */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register long maxc = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->colorcount > maxc && boxp->volume > 0) { + which = boxp; + maxc = boxp->colorcount; + } + } + return which; +} + + +LOCAL(boxptr) +find_biggest_volume (boxptr boxlist, int numboxes) +/* Find the splittable box with the largest (scaled) volume */ +/* Returns NULL if no splittable boxes remain */ +{ + register boxptr boxp; + register int i; + register INT32 maxv = 0; + boxptr which = NULL; + + for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { + if (boxp->volume > maxv) { + which = boxp; + maxv = boxp->volume; + } + } + return which; +} + + +LOCAL(void) +update_box (j_decompress_ptr cinfo, boxptr boxp) +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ +/* and recompute its volume and population */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + INT32 dist0,dist1,dist2; + long ccount; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + if (c0max > c0min) + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0min = c0min = c0; + goto have_c0min; + } + } + have_c0min: + if (c0max > c0min) + for (c0 = c0max; c0 >= c0min; c0--) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c0max = c0max = c0; + goto have_c0max; + } + } + have_c0max: + if (c1max > c1min) + for (c1 = c1min; c1 <= c1max; c1++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1min = c1min = c1; + goto have_c1min; + } + } + have_c1min: + if (c1max > c1min) + for (c1 = c1max; c1 >= c1min; c1--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) + if (*histp++ != 0) { + boxp->c1max = c1max = c1; + goto have_c1max; + } + } + have_c1max: + if (c2max > c2min) + for (c2 = c2min; c2 <= c2max; c2++) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2min = c2min = c2; + goto have_c2min; + } + } + have_c2min: + if (c2max > c2min) + for (c2 = c2max; c2 >= c2min; c2--) + for (c0 = c0min; c0 <= c0max; c0++) { + histp = & histogram[c0][c1min][c2]; + for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) + if (*histp != 0) { + boxp->c2max = c2max = c2; + goto have_c2max; + } + } + have_c2max: + + /* Update box volume. + * We use 2-norm rather than real volume here; this biases the method + * against making long narrow boxes, and it has the side benefit that + * a box is splittable iff norm > 0. + * Since the differences are expressed in histogram-cell units, + * we have to shift back to JSAMPLE units to get consistent distances; + * after which, we scale according to the selected distance scale factors. + */ + dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; + dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; + dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; + boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; + + /* Now scan remaining volume of box and compute population */ + ccount = 0; + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++, histp++) + if (*histp != 0) { + ccount++; + } + } + boxp->colorcount = ccount; +} + + +LOCAL(int) +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, + int desired_colors) +/* Repeatedly select and split the largest box until we have enough boxes */ +{ + int n,lb; + int c0,c1,c2,cmax; + register boxptr b1,b2; + + while (numboxes < desired_colors) { + /* Select box to split. + * Current algorithm: by population for first half, then by volume. + */ + if (numboxes*2 <= desired_colors) { + b1 = find_biggest_color_pop(boxlist, numboxes); + } else { + b1 = find_biggest_volume(boxlist, numboxes); + } + if (b1 == NULL) /* no splittable boxes left! */ + break; + b2 = &boxlist[numboxes]; /* where new box will go */ + /* Copy the color bounds to the new box. */ + b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; + b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; + /* Choose which axis to split the box on. + * Current algorithm: longest scaled axis. + * See notes in update_box about scaling distances. + */ + c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; + c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; + c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; + /* We want to break any ties in favor of green, then red, blue last. + * This code does the right thing for R,G,B or B,G,R color orders only. + */ +#if RGB_RED == 0 + cmax = c1; n = 1; + if (c0 > cmax) { cmax = c0; n = 0; } + if (c2 > cmax) { n = 2; } +#else + cmax = c1; n = 1; + if (c2 > cmax) { cmax = c2; n = 2; } + if (c0 > cmax) { n = 0; } +#endif + /* Choose split point along selected axis, and update box bounds. + * Current algorithm: split at halfway point. + * (Since the box has been shrunk to minimum volume, + * any split will produce two nonempty subboxes.) + * Note that lb value is max for lower box, so must be < old max. + */ + switch (n) { + case 0: + lb = (b1->c0max + b1->c0min) / 2; + b1->c0max = lb; + b2->c0min = lb+1; + break; + case 1: + lb = (b1->c1max + b1->c1min) / 2; + b1->c1max = lb; + b2->c1min = lb+1; + break; + case 2: + lb = (b1->c2max + b1->c2min) / 2; + b1->c2max = lb; + b2->c2min = lb+1; + break; + } + /* Update stats for boxes */ + update_box(cinfo, b1); + update_box(cinfo, b2); + numboxes++; + } + return numboxes; +} + + +LOCAL(void) +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) +/* Compute representative color for a box, put it in colormap[icolor] */ +{ + /* Current algorithm: mean weighted by pixels (not colors) */ + /* Note it is important to get the rounding correct! */ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + histptr histp; + int c0,c1,c2; + int c0min,c0max,c1min,c1max,c2min,c2max; + long count; + long total = 0; + long c0total = 0; + long c1total = 0; + long c2total = 0; + + c0min = boxp->c0min; c0max = boxp->c0max; + c1min = boxp->c1min; c1max = boxp->c1max; + c2min = boxp->c2min; c2max = boxp->c2max; + + for (c0 = c0min; c0 <= c0max; c0++) + for (c1 = c1min; c1 <= c1max; c1++) { + histp = & histogram[c0][c1][c2min]; + for (c2 = c2min; c2 <= c2max; c2++) { + if ((count = *histp++) != 0) { + total += count; + c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count; + c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; + c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count; + } + } + } + + cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); + cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); + cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); +} + + +LOCAL(void) +select_colors (j_decompress_ptr cinfo, int desired_colors) +/* Master routine for color selection */ +{ + boxptr boxlist; + int numboxes; + int i; + + /* Allocate workspace for box list */ + boxlist = (boxptr) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); + /* Initialize one box containing whole space */ + numboxes = 1; + boxlist[0].c0min = 0; + boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; + boxlist[0].c1min = 0; + boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; + boxlist[0].c2min = 0; + boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; + /* Shrink it to actually-used volume and set its statistics */ + update_box(cinfo, & boxlist[0]); + /* Perform median-cut to produce final box list */ + numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); + /* Compute the representative color for each box, fill colormap */ + for (i = 0; i < numboxes; i++) + compute_color(cinfo, & boxlist[i], i); + cinfo->actual_number_of_colors = numboxes; + TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); +} + + +/* + * These routines are concerned with the time-critical task of mapping input + * colors to the nearest color in the selected colormap. + * + * We re-use the histogram space as an "inverse color map", essentially a + * cache for the results of nearest-color searches. All colors within a + * histogram cell will be mapped to the same colormap entry, namely the one + * closest to the cell's center. This may not be quite the closest entry to + * the actual input color, but it's almost as good. A zero in the cache + * indicates we haven't found the nearest color for that cell yet; the array + * is cleared to zeroes before starting the mapping pass. When we find the + * nearest color for a cell, its colormap index plus one is recorded in the + * cache for future use. The pass2 scanning routines call fill_inverse_cmap + * when they need to use an unfilled entry in the cache. + * + * Our method of efficiently finding nearest colors is based on the "locally + * sorted search" idea described by Heckbert and on the incremental distance + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics + * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + * the distances from a given colormap entry to each cell of the histogram can + * be computed quickly using an incremental method: the differences between + * distances to adjacent cells themselves differ by a constant. This allows a + * fairly fast implementation of the "brute force" approach of computing the + * distance from every colormap entry to every histogram cell. Unfortunately, + * it needs a work array to hold the best-distance-so-far for each histogram + * cell (because the inner loop has to be over cells, not colormap entries). + * The work array elements have to be INT32s, so the work array would need + * 256Kb at our recommended precision. This is not feasible in DOS machines. + * + * To get around these problems, we apply Thomas' method to compute the + * nearest colors for only the cells within a small subbox of the histogram. + * The work array need be only as big as the subbox, so the memory usage + * problem is solved. Furthermore, we need not fill subboxes that are never + * referenced in pass2; many images use only part of the color gamut, so a + * fair amount of work is saved. An additional advantage of this + * approach is that we can apply Heckbert's locality criterion to quickly + * eliminate colormap entries that are far away from the subbox; typically + * three-fourths of the colormap entries are rejected by Heckbert's criterion, + * and we need not compute their distances to individual cells in the subbox. + * The speed of this approach is heavily influenced by the subbox size: too + * small means too much overhead, too big loses because Heckbert's criterion + * can't eliminate as many colormap entries. Empirically the best subbox + * size seems to be about 1/512th of the histogram (1/8th in each direction). + * + * Thomas' article also describes a refined method which is asymptotically + * faster than the brute-force method, but it is also far more complex and + * cannot efficiently be applied to small subboxes. It is therefore not + * useful for programs intended to be portable to DOS machines. On machines + * with plenty of memory, filling the whole histogram in one shot with Thomas' + * refined method might be faster than the present code --- but then again, + * it might not be any faster, and it's certainly more complicated. + */ + + +/* log2(histogram cells in update box) for each axis; this can be adjusted */ +#define BOX_C0_LOG (HIST_C0_BITS-3) +#define BOX_C1_LOG (HIST_C1_BITS-3) +#define BOX_C2_LOG (HIST_C2_BITS-3) + +#define BOX_C0_ELEMS (1<actual_number_of_colors; + int maxc0, maxc1, maxc2; + int centerc0, centerc1, centerc2; + int i, x, ncolors; + INT32 minmaxdist, min_dist, max_dist, tdist; + INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ + + /* Compute true coordinates of update box's upper corner and center. + * Actually we compute the coordinates of the center of the upper-corner + * histogram cell, which are the upper bounds of the volume we care about. + * Note that since ">>" rounds down, the "center" values may be closer to + * min than to max; hence comparisons to them must be "<=", not "<". + */ + maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); + centerc0 = (minc0 + maxc0) >> 1; + maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); + centerc1 = (minc1 + maxc1) >> 1; + maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); + centerc2 = (minc2 + maxc2) >> 1; + + /* For each color in colormap, find: + * 1. its minimum squared-distance to any point in the update box + * (zero if color is within update box); + * 2. its maximum squared-distance to any point in the update box. + * Both of these can be found by considering only the corners of the box. + * We save the minimum distance for each color in mindist[]; + * only the smallest maximum distance is of interest. + */ + minmaxdist = 0x7FFFFFFFL; + + for (i = 0; i < numcolors; i++) { + /* We compute the squared-c0-distance term, then add in the other two. */ + x = GETJSAMPLE(cinfo->colormap[0][i]); + if (x < minc0) { + tdist = (x - minc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else if (x > maxc0) { + tdist = (x - maxc0) * C0_SCALE; + min_dist = tdist*tdist; + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + min_dist = 0; + if (x <= centerc0) { + tdist = (x - maxc0) * C0_SCALE; + max_dist = tdist*tdist; + } else { + tdist = (x - minc0) * C0_SCALE; + max_dist = tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[1][i]); + if (x < minc1) { + tdist = (x - minc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc1) { + tdist = (x - maxc1) * C1_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc1) { + tdist = (x - maxc1) * C1_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc1) * C1_SCALE; + max_dist += tdist*tdist; + } + } + + x = GETJSAMPLE(cinfo->colormap[2][i]); + if (x < minc2) { + tdist = (x - minc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else if (x > maxc2) { + tdist = (x - maxc2) * C2_SCALE; + min_dist += tdist*tdist; + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + /* within cell range so no contribution to min_dist */ + if (x <= centerc2) { + tdist = (x - maxc2) * C2_SCALE; + max_dist += tdist*tdist; + } else { + tdist = (x - minc2) * C2_SCALE; + max_dist += tdist*tdist; + } + } + + mindist[i] = min_dist; /* save away the results */ + if (max_dist < minmaxdist) + minmaxdist = max_dist; + } + + /* Now we know that no cell in the update box is more than minmaxdist + * away from some colormap entry. Therefore, only colors that are + * within minmaxdist of some part of the box need be considered. + */ + ncolors = 0; + for (i = 0; i < numcolors; i++) { + if (mindist[i] <= minmaxdist) + colorlist[ncolors++] = (JSAMPLE) i; + } + return ncolors; +} + + +LOCAL(void) +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, + int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) +/* Find the closest colormap entry for each cell in the update box, + * given the list of candidate colors prepared by find_nearby_colors. + * Return the indexes of the closest entries in the bestcolor[] array. + * This routine uses Thomas' incremental distance calculation method to + * find the distance from a colormap entry to successive cells in the box. + */ +{ + int ic0, ic1, ic2; + int i, icolor; + register INT32 * bptr; /* pointer into bestdist[] array */ + JSAMPLE * cptr; /* pointer into bestcolor[] array */ + INT32 dist0, dist1; /* initial distance values */ + register INT32 dist2; /* current distance in inner loop */ + INT32 xx0, xx1; /* distance increments */ + register INT32 xx2; + INT32 inc0, inc1, inc2; /* initial values for increments */ + /* This array holds the distance to the nearest-so-far color for each cell */ + INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Initialize best-distance for each cell of the update box */ + bptr = bestdist; + for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) + *bptr++ = 0x7FFFFFFFL; + + /* For each color selected by find_nearby_colors, + * compute its distance to the center of each cell in the box. + * If that's less than best-so-far, update best distance and color number. + */ + + /* Nominal steps between cell centers ("x" in Thomas article) */ +#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) +#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) +#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) + + for (i = 0; i < numcolors; i++) { + icolor = GETJSAMPLE(colorlist[i]); + /* Compute (square of) distance from minc0/c1/c2 to this color */ + inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; + dist0 = inc0*inc0; + inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; + dist0 += inc1*inc1; + inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; + dist0 += inc2*inc2; + /* Form the initial difference increments */ + inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + /* Now loop over all cells in box, updating distance per Thomas method */ + bptr = bestdist; + cptr = bestcolor; + xx0 = inc0; + for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { + dist1 = dist0; + xx1 = inc1; + for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { + dist2 = dist1; + xx2 = inc2; + for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { + if (dist2 < *bptr) { + *bptr = dist2; + *cptr = (JSAMPLE) icolor; + } + dist2 += xx2; + xx2 += 2 * STEP_C2 * STEP_C2; + bptr++; + cptr++; + } + dist1 += xx1; + xx1 += 2 * STEP_C1 * STEP_C1; + } + dist0 += xx0; + xx0 += 2 * STEP_C0 * STEP_C0; + } + } +} + + +LOCAL(void) +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) +/* Fill the inverse-colormap entries in the update box that contains */ +/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ +/* we can fill as many others as we wish.) */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int minc0, minc1, minc2; /* lower left corner of update box */ + int ic0, ic1, ic2; + register JSAMPLE * cptr; /* pointer into bestcolor[] array */ + register histptr cachep; /* pointer into main cache array */ + /* This array lists the candidate colormap indexes. */ + JSAMPLE colorlist[MAXNUMCOLORS]; + int numcolors; /* number of candidate colors */ + /* This array holds the actually closest colormap index for each cell. */ + JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; + + /* Convert cell coordinates to update box ID */ + c0 >>= BOX_C0_LOG; + c1 >>= BOX_C1_LOG; + c2 >>= BOX_C2_LOG; + + /* Compute true coordinates of update box's origin corner. + * Actually we compute the coordinates of the center of the corner + * histogram cell, which are the lower bounds of the volume we care about. + */ + minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); + minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); + minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); + + /* Determine which colormap entries are close enough to be candidates + * for the nearest entry to some cell in the update box. + */ + numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + /* Determine the actually nearest colors. */ + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + /* Save the best color numbers (plus 1) in the main cache array */ + c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ + c1 <<= BOX_C1_LOG; + c2 <<= BOX_C2_LOG; + cptr = bestcolor; + for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { + for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { + cachep = & histogram[c0+ic0][c1+ic1][c2]; + for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { + *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); + } + } + } +} + + +/* + * Map some rows of pixels to the output colormapped representation. + */ + +METHODDEF(void) +pass2_no_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs no dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register JSAMPROW inptr, outptr; + register histptr cachep; + register int c0, c1, c2; + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + for (col = width; col > 0; col--) { + /* get pixel value and index into the cache */ + c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; + c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; + c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; + cachep = & histogram[c0][c1][c2]; + /* If we have not seen this color before, find nearest colormap entry */ + /* and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, c0,c1,c2); + /* Now emit the colormap index for this cell */ + *outptr++ = (JSAMPLE) (*cachep - 1); + } + } +} + + +METHODDEF(void) +pass2_fs_dither (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) +/* This version performs Floyd-Steinberg dithering */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ + LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ + register FSERRPTR errorptr; /* => fserrors[] at column before current */ + JSAMPROW inptr; /* => current input pixel */ + JSAMPROW outptr; /* => current output pixel */ + histptr cachep; + int dir; /* +1 or -1 depending on direction */ + int dir3; /* 3*dir, for advancing inptr & errorptr */ + int row; + JDIMENSION col; + JDIMENSION width = cinfo->output_width; + JSAMPLE *range_limit = cinfo->sample_range_limit; + int *error_limit = cquantize->error_limiter; + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + SHIFT_TEMPS + + for (row = 0; row < num_rows; row++) { + inptr = input_buf[row]; + outptr = output_buf[row]; + if (cquantize->on_odd_row) { + /* work right to left in this row */ + inptr += (width-1) * 3; /* so point to rightmost pixel */ + outptr += width-1; + dir = -1; + dir3 = -3; + errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ + cquantize->on_odd_row = FALSE; /* flip for next time */ + } else { + /* work left to right in this row */ + dir = 1; + dir3 = 3; + errorptr = cquantize->fserrors; /* => entry before first real column */ + cquantize->on_odd_row = TRUE; /* flip for next time */ + } + /* Preset error values: no error propagated to first pixel from left */ + cur0 = cur1 = cur2 = 0; + /* and no error propagated to row below yet */ + belowerr0 = belowerr1 = belowerr2 = 0; + bpreverr0 = bpreverr1 = bpreverr2 = 0; + + for (col = width; col > 0; col--) { + /* curN holds the error propagated from the previous pixel on the + * current line. Add the error propagated from the previous line + * to form the complete error correction term for this pixel, and + * round the error term (which is expressed * 16) to an integer. + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + * for either sign of the error value. + * Note: errorptr points to *previous* column's array entry. + */ + cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); + cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); + cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); + /* Limit the error using transfer function set by init_error_limit. + * See comments with init_error_limit for rationale. + */ + cur0 = error_limit[cur0]; + cur1 = error_limit[cur1]; + cur2 = error_limit[cur2]; + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + * The maximum error is +- MAXJSAMPLE (or less with error limiting); + * this sets the required size of the range_limit array. + */ + cur0 += GETJSAMPLE(inptr[0]); + cur1 += GETJSAMPLE(inptr[1]); + cur2 += GETJSAMPLE(inptr[2]); + cur0 = GETJSAMPLE(range_limit[cur0]); + cur1 = GETJSAMPLE(range_limit[cur1]); + cur2 = GETJSAMPLE(range_limit[cur2]); + /* Index into the cache with adjusted pixel value */ + cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; + /* If we have not seen this color before, find nearest colormap */ + /* entry and update the cache */ + if (*cachep == 0) + fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); + /* Now emit the colormap index for this cell */ + { register int pixcode = *cachep - 1; + *outptr = (JSAMPLE) pixcode; + /* Compute representation error for this pixel */ + cur0 -= GETJSAMPLE(colormap0[pixcode]); + cur1 -= GETJSAMPLE(colormap1[pixcode]); + cur2 -= GETJSAMPLE(colormap2[pixcode]); + } + /* Compute error fractions to be propagated to adjacent pixels. + * Add these into the running sums, and simultaneously shift the + * next-line error sums left by 1 column. + */ + { register LOCFSERROR bnexterr, delta; + + bnexterr = cur0; /* Process component 0 */ + delta = cur0 * 2; + cur0 += delta; /* form error * 3 */ + errorptr[0] = (FSERROR) (bpreverr0 + cur0); + cur0 += delta; /* form error * 5 */ + bpreverr0 = belowerr0 + cur0; + belowerr0 = bnexterr; + cur0 += delta; /* form error * 7 */ + bnexterr = cur1; /* Process component 1 */ + delta = cur1 * 2; + cur1 += delta; /* form error * 3 */ + errorptr[1] = (FSERROR) (bpreverr1 + cur1); + cur1 += delta; /* form error * 5 */ + bpreverr1 = belowerr1 + cur1; + belowerr1 = bnexterr; + cur1 += delta; /* form error * 7 */ + bnexterr = cur2; /* Process component 2 */ + delta = cur2 * 2; + cur2 += delta; /* form error * 3 */ + errorptr[2] = (FSERROR) (bpreverr2 + cur2); + cur2 += delta; /* form error * 5 */ + bpreverr2 = belowerr2 + cur2; + belowerr2 = bnexterr; + cur2 += delta; /* form error * 7 */ + } + /* At this point curN contains the 7/16 error value to be propagated + * to the next pixel on the current line, and all the errors for the + * next line have been shifted over. We are therefore ready to move on. + */ + inptr += dir3; /* Advance pixel pointers to next column */ + outptr += dir; + errorptr += dir3; /* advance errorptr to current column */ + } + /* Post-loop cleanup: we must unload the final error values into the + * final fserrors[] entry. Note we need not unload belowerrN because + * it is for the dummy column before or after the actual array. + */ + errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ + errorptr[1] = (FSERROR) bpreverr1; + errorptr[2] = (FSERROR) bpreverr2; + } +} + + +/* + * Initialize the error-limiting transfer function (lookup table). + * The raw F-S error computation can potentially compute error values of up to + * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + * much less, otherwise obviously wrong pixels will be created. (Typical + * effects include weird fringes at color-area boundaries, isolated bright + * pixels in a dark area, etc.) The standard advice for avoiding this problem + * is to ensure that the "corners" of the color cube are allocated as output + * colors; then repeated errors in the same direction cannot cause cascading + * error buildup. However, that only prevents the error from getting + * completely out of hand; Aaron Giles reports that error limiting improves + * the results even with corner colors allocated. + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + * well, but the smoother transfer function used below is even better. Thanks + * to Aaron Giles for this idea. + */ + +LOCAL(void) +init_error_limit (j_decompress_ptr cinfo) +/* Allocate and fill in the error_limiter table */ +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + int * table; + int in, out; + + table = (int *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); + table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ + cquantize->error_limiter = table; + +#define STEPSIZE ((MAXJSAMPLE+1)/16) + /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ + out = 0; + for (in = 0; in < STEPSIZE; in++, out++) { + table[in] = out; table[-in] = -out; + } + /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ + for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { + table[in] = out; table[-in] = -out; + } + /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ + for (; in <= MAXJSAMPLE; in++) { + table[in] = out; table[-in] = -out; + } +#undef STEPSIZE +} + + +/* + * Finish up at the end of each pass. + */ + +METHODDEF(void) +finish_pass1 (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Select the representative colors and fill in cinfo->colormap */ + cinfo->colormap = cquantize->sv_colormap; + select_colors(cinfo, cquantize->desired); + /* Force next pass to zero the color index table */ + cquantize->needs_zeroed = TRUE; +} + + +METHODDEF(void) +finish_pass2 (j_decompress_ptr cinfo) +{ + /* no work */ +} + + +/* + * Initialize for each processing pass. + */ + +METHODDEF(void) +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + hist3d histogram = cquantize->histogram; + int i; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + if (is_pre_scan) { + /* Set up method pointers */ + cquantize->pub.color_quantize = prescan_quantize; + cquantize->pub.finish_pass = finish_pass1; + cquantize->needs_zeroed = TRUE; /* Always zero histogram */ + } else { + /* Set up method pointers */ + if (cinfo->dither_mode == JDITHER_FS) + cquantize->pub.color_quantize = pass2_fs_dither; + else + cquantize->pub.color_quantize = pass2_no_dither; + cquantize->pub.finish_pass = finish_pass2; + + /* Make sure color count is acceptable */ + i = cinfo->actual_number_of_colors; + if (i < 1) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo->dither_mode == JDITHER_FS) { + size_t arraysize = (size_t) ((cinfo->output_width + 2) * + (3 * SIZEOF(FSERROR))); + /* Allocate Floyd-Steinberg workspace if we didn't already. */ + if (cquantize->fserrors == NULL) + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); + /* Initialize the propagated errors to zero. */ + jzero_far((void FAR *) cquantize->fserrors, arraysize); + /* Make the error-limit table if we didn't already. */ + if (cquantize->error_limiter == NULL) + init_error_limit(cinfo); + cquantize->on_odd_row = FALSE; + } + + } + /* Zero the histogram or inverse color map, if necessary */ + if (cquantize->needs_zeroed) { + for (i = 0; i < HIST_C0_ELEMS; i++) { + jzero_far((void FAR *) histogram[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = FALSE; + } +} + + +/* + * Switch to a new external colormap between output passes. + */ + +METHODDEF(void) +new_color_map_2_quant (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; + + /* Reset the inverse color map */ + cquantize->needs_zeroed = TRUE; +} + + +/* + * Module initialization routine for 2-pass color quantization. + */ + +GLOBAL(void) +jinit_2pass_quantizer (j_decompress_ptr cinfo) +{ + my_cquantize_ptr cquantize; + int i; + + cquantize = (my_cquantize_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(my_cquantizer)); + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; + cquantize->pub.start_pass = start_pass_2_quant; + cquantize->pub.new_color_map = new_color_map_2_quant; + cquantize->fserrors = NULL; /* flag optional arrays not allocated */ + cquantize->error_limiter = NULL; + + /* Make sure jdmaster didn't give me a case I can't handle */ + if (cinfo->out_color_components != 3) + ERREXIT(cinfo, JERR_NOTIMPL); + + /* Allocate the histogram/inverse colormap storage */ + cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); + for (i = 0; i < HIST_C0_ELEMS; i++) { + cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + } + cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ + + /* Allocate storage for the completed colormap, if required. + * We do this now since it is FAR storage and may affect + * the memory manager's space calculations. + */ + if (cinfo->enable_2pass_quant) { + /* Make sure color count is acceptable */ + int desired = cinfo->desired_number_of_colors; + /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ + if (desired < 8) + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); + /* Make sure colormap indexes can be represented by JSAMPLEs */ + if (desired > MAXNUMCOLORS) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); + cquantize->desired = desired; + } else + cquantize->sv_colormap = NULL; + + /* Only F-S dithering or no dithering is supported. */ + /* If user asks for ordered dither, give him F-S. */ + if (cinfo->dither_mode != JDITHER_NONE) + cinfo->dither_mode = JDITHER_FS; + + /* Allocate Floyd-Steinberg workspace if necessary. + * This isn't really needed until pass 2, but again it is FAR storage. + * Although we will cope with a later change in dither_mode, + * we do not promise to honor max_memory_to_use if dither_mode changes. + */ + if (cinfo->dither_mode == JDITHER_FS) { + cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); + /* Might as well create the error-limiting table too. */ + init_error_limit(cinfo); + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/jutils.c b/src/dep/src/irrlicht/jpeglib/jutils.c new file mode 100644 index 0000000..286cda2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jutils.c @@ -0,0 +1,179 @@ +/* + * jutils.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains tables and miscellaneous utility routines needed + * for both compression and decompression. + * Note we prefix all global names with "j" to minimize conflicts with + * a surrounding application. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + * of a DCT block read in natural order (left to right, top to bottom). + */ + +#if 0 /* This table is not actually needed in v6a */ + +const int jpeg_zigzag_order[DCTSIZE2] = { + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 +}; + +#endif + +/* + * jpeg_natural_order[i] is the natural-order position of the i'th element + * of zigzag order. + * + * When reading corrupted data, the Huffman decoders could attempt + * to reference an entry beyond the end of this array (if the decoded + * zero run length reaches past the end of the block). To prevent + * wild stores without adding an inner-loop test, we put some extra + * "63"s after the real entries. This will cause the extra coefficient + * to be stored in location 63 of the block, not somewhere random. + * The worst case would be a run-length of 15, which means we need 16 + * fake entries. + */ + +const int jpeg_natural_order[DCTSIZE2+16] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ + 63, 63, 63, 63, 63, 63, 63, 63 +}; + + +/* + * Arithmetic utilities + */ + +GLOBAL(long) +jdiv_round_up (long a, long b) +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ +/* Assumes a >= 0, b > 0 */ +{ + return (a + b - 1L) / b; +} + + +GLOBAL(long) +jround_up (long a, long b) +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ +/* Assumes a >= 0, b > 0 */ +{ + a += b - 1L; + return a - (a % b); +} + + +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + * and coefficient-block arrays. This won't work on 80x86 because the arrays + * are FAR and we're assuming a small-pointer memory model. However, some + * DOS compilers provide far-pointer versions of memcpy() and memset() even + * in the small-model libraries. These will be used if USE_FMEM is defined. + * Otherwise, the routines below do it the hard way. (The performance cost + * is not all that great, because these routines aren't very heavily used.) + */ + +#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) +#define FMEMZERO(target,size) MEMZERO(target,size) +#else /* 80x86 case, define if we can */ +#ifdef USE_FMEM +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) +#endif +#endif + + +GLOBAL(void) +jcopy_sample_rows (JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols) +/* Copy some rows of samples from one place to another. + * num_rows rows are copied from input_array[source_row++] + * to output_array[dest_row++]; these areas may overlap for duplication. + * The source and destination arrays must be at least as wide as num_cols. + */ +{ + register JSAMPROW inptr, outptr; +#ifdef FMEMCOPY + register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); +#else + register JDIMENSION count; +#endif + register int row; + + input_array += source_row; + output_array += dest_row; + + for (row = num_rows; row > 0; row--) { + inptr = *input_array++; + outptr = *output_array++; +#ifdef FMEMCOPY + FMEMCOPY(outptr, inptr, count); +#else + for (count = num_cols; count > 0; count--) + *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ +#endif + } +} + + +GLOBAL(void) +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks) +/* Copy a row of coefficient blocks from one place to another. */ +{ +#ifdef FMEMCOPY + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +#else + register JCOEFPTR inptr, outptr; + register long count; + + inptr = (JCOEFPTR) input_row; + outptr = (JCOEFPTR) output_row; + for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { + *outptr++ = *inptr++; + } +#endif +} + + +GLOBAL(void) +jzero_far (void FAR * target, size_t bytestozero) +/* Zero out a chunk of FAR memory. */ +/* This might be sample-array data, block-array data, or alloc_large data. */ +{ +#ifdef FMEMZERO + FMEMZERO(target, bytestozero); +#else + register char FAR * ptr = (char FAR *) target; + register size_t count; + + for (count = bytestozero; count > 0; count--) { + *ptr++ = 0; + } +#endif +} diff --git a/src/dep/src/irrlicht/jpeglib/jversion.h b/src/dep/src/irrlicht/jpeglib/jversion.h new file mode 100644 index 0000000..dadd453 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/jversion.h @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6b 27-Mar-1998" + +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/src/dep/src/irrlicht/jpeglib/libjpeg.doc b/src/dep/src/irrlicht/jpeglib/libjpeg.doc new file mode 100644 index 0000000..f741051 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/libjpeg.doc @@ -0,0 +1,3006 @@ +USING THE IJG JPEG LIBRARY + +Copyright (C) 1994-1998, Thomas G. Lane. +This file is part of the Independent JPEG Group's software. +For conditions of distribution and use, see the accompanying README file. + + +This file describes how to use the IJG JPEG library within an application +program. Read it if you want to write a program that uses the library. + +The file example.c provides heavily commented skeleton code for calling the +JPEG library. Also see jpeglib.h (the include file to be used by application +programs) for full details about data structures and function parameter lists. +The library source code, of course, is the ultimate reference. + +Note that there have been *major* changes from the application interface +presented by IJG version 4 and earlier versions. The old design had several +inherent limitations, and it had accumulated a lot of cruft as we added +features while trying to minimize application-interface changes. We have +sacrificed backward compatibility in the version 5 rewrite, but we think the +improvements justify this. + + +TABLE OF CONTENTS +----------------- + +Overview: + Functions provided by the library + Outline of typical usage +Basic library usage: + Data formats + Compression details + Decompression details + Mechanics of usage: include files, linking, etc +Advanced features: + Compression parameter selection + Decompression parameter selection + Special color spaces + Error handling + Compressed data handling (source and destination managers) + I/O suspension + Progressive JPEG support + Buffered-image mode + Abbreviated datastreams and multiple images + Special markers + Raw (downsampled) image data + Really raw data: DCT coefficients + Progress monitoring + Memory management + Memory usage + Library compile-time options + Portability considerations + Notes for MS-DOS implementors + +You should read at least the overview and basic usage sections before trying +to program with the library. The sections on advanced features can be read +if and when you need them. + + +OVERVIEW +======== + +Functions provided by the library +--------------------------------- + +The IJG JPEG library provides C code to read and write JPEG-compressed image +files. The surrounding application program receives or supplies image data a +scanline at a time, using a straightforward uncompressed image format. All +details of color conversion and other preprocessing/postprocessing can be +handled by the library. + +The library includes a substantial amount of code that is not covered by the +JPEG standard but is necessary for typical applications of JPEG. These +functions preprocess the image before JPEG compression or postprocess it after +decompression. They include colorspace conversion, downsampling/upsampling, +and color quantization. The application indirectly selects use of this code +by specifying the format in which it wishes to supply or receive image data. +For example, if colormapped output is requested, then the decompression +library automatically invokes color quantization. + +A wide range of quality vs. speed tradeoffs are possible in JPEG processing, +and even more so in decompression postprocessing. The decompression library +provides multiple implementations that cover most of the useful tradeoffs, +ranging from very-high-quality down to fast-preview operation. On the +compression side we have generally not provided low-quality choices, since +compression is normally less time-critical. It should be understood that the +low-quality modes may not meet the JPEG standard's accuracy requirements; +nonetheless, they are useful for viewers. + +A word about functions *not* provided by the library. We handle a subset of +the ISO JPEG standard; most baseline, extended-sequential, and progressive +JPEG processes are supported. (Our subset includes all features now in common +use.) Unsupported ISO options include: + * Hierarchical storage + * Lossless JPEG + * Arithmetic entropy coding (unsupported for legal reasons) + * DNL marker + * Nonintegral subsampling ratios +We support both 8- and 12-bit data precision, but this is a compile-time +choice rather than a run-time choice; hence it is difficult to use both +precisions in a single application. + +By itself, the library handles only interchange JPEG datastreams --- in +particular the widely used JFIF file format. The library can be used by +surrounding code to process interchange or abbreviated JPEG datastreams that +are embedded in more complex file formats. (For example, this library is +used by the free LIBTIFF library to support JPEG compression in TIFF.) + + +Outline of typical usage +------------------------ + +The rough outline of a JPEG compression operation is: + + Allocate and initialize a JPEG compression object + Specify the destination for the compressed data (eg, a file) + Set parameters for compression, including image size & colorspace + jpeg_start_compress(...); + while (scan lines remain to be written) + jpeg_write_scanlines(...); + jpeg_finish_compress(...); + Release the JPEG compression object + +A JPEG compression object holds parameters and working state for the JPEG +library. We make creation/destruction of the object separate from starting +or finishing compression of an image; the same object can be re-used for a +series of image compression operations. This makes it easy to re-use the +same parameter settings for a sequence of images. Re-use of a JPEG object +also has important implications for processing abbreviated JPEG datastreams, +as discussed later. + +The image data to be compressed is supplied to jpeg_write_scanlines() from +in-memory buffers. If the application is doing file-to-file compression, +reading image data from the source file is the application's responsibility. +The library emits compressed data by calling a "data destination manager", +which typically will write the data into a file; but the application can +provide its own destination manager to do something else. + +Similarly, the rough outline of a JPEG decompression operation is: + + Allocate and initialize a JPEG decompression object + Specify the source of the compressed data (eg, a file) + Call jpeg_read_header() to obtain image info + Set parameters for decompression + jpeg_start_decompress(...); + while (scan lines remain to be read) + jpeg_read_scanlines(...); + jpeg_finish_decompress(...); + Release the JPEG decompression object + +This is comparable to the compression outline except that reading the +datastream header is a separate step. This is helpful because information +about the image's size, colorspace, etc is available when the application +selects decompression parameters. For example, the application can choose an +output scaling ratio that will fit the image into the available screen size. + +The decompression library obtains compressed data by calling a data source +manager, which typically will read the data from a file; but other behaviors +can be obtained with a custom source manager. Decompressed data is delivered +into in-memory buffers passed to jpeg_read_scanlines(). + +It is possible to abort an incomplete compression or decompression operation +by calling jpeg_abort(); or, if you do not need to retain the JPEG object, +simply release it by calling jpeg_destroy(). + +JPEG compression and decompression objects are two separate struct types. +However, they share some common fields, and certain routines such as +jpeg_destroy() can work on either type of object. + +The JPEG library has no static variables: all state is in the compression +or decompression object. Therefore it is possible to process multiple +compression and decompression operations concurrently, using multiple JPEG +objects. + +Both compression and decompression can be done in an incremental memory-to- +memory fashion, if suitable source/destination managers are used. See the +section on "I/O suspension" for more details. + + +BASIC LIBRARY USAGE +=================== + +Data formats +------------ + +Before diving into procedural details, it is helpful to understand the +image data format that the JPEG library expects or returns. + +The standard input image format is a rectangular array of pixels, with each +pixel having the same number of "component" or "sample" values (color +channels). You must specify how many components there are and the colorspace +interpretation of the components. Most applications will use RGB data +(three components per pixel) or grayscale data (one component per pixel). +PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE. +A remarkable number of people manage to miss this, only to find that their +programs don't work with grayscale JPEG files. + +There is no provision for colormapped input. JPEG files are always full-color +or full grayscale (or sometimes another colorspace such as CMYK). You can +feed in a colormapped image by expanding it to full-color format. However +JPEG often doesn't work very well with source data that has been colormapped, +because of dithering noise. This is discussed in more detail in the JPEG FAQ +and the other references mentioned in the README file. + +Pixels are stored by scanlines, with each scanline running from left to +right. The component values for each pixel are adjacent in the row; for +example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color. Each scanline is an +array of data type JSAMPLE --- which is typically "unsigned char", unless +you've changed jmorecfg.h. (You can also change the RGB pixel layout, say +to B,G,R order, by modifying jmorecfg.h. But see the restrictions listed in +that file before doing so.) + +A 2-D array of pixels is formed by making a list of pointers to the starts of +scanlines; so the scanlines need not be physically adjacent in memory. Even +if you process just one scanline at a time, you must make a one-element +pointer array to conform to this structure. Pointers to JSAMPLE rows are of +type JSAMPROW, and the pointer to the pointer array is of type JSAMPARRAY. + +The library accepts or supplies one or more complete scanlines per call. +It is not possible to process part of a row at a time. Scanlines are always +processed top-to-bottom. You can process an entire image in one call if you +have it all in memory, but usually it's simplest to process one scanline at +a time. + +For best results, source data values should have the precision specified by +BITS_IN_JSAMPLE (normally 8 bits). For instance, if you choose to compress +data that's only 6 bits/channel, you should left-justify each value in a +byte before passing it to the compressor. If you need to compress data +that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12. +(See "Library compile-time options", later.) + + +The data format returned by the decompressor is the same in all details, +except that colormapped output is supported. (Again, a JPEG file is never +colormapped. But you can ask the decompressor to perform on-the-fly color +quantization to deliver colormapped output.) If you request colormapped +output then the returned data array contains a single JSAMPLE per pixel; +its value is an index into a color map. The color map is represented as +a 2-D JSAMPARRAY in which each row holds the values of one color component, +that is, colormap[i][j] is the value of the i'th color component for pixel +value (map index) j. Note that since the colormap indexes are stored in +JSAMPLEs, the maximum number of colors is limited by the size of JSAMPLE +(ie, at most 256 colors for an 8-bit JPEG library). + + +Compression details +------------------- + +Here we revisit the JPEG compression outline given in the overview. + +1. Allocate and initialize a JPEG compression object. + +A JPEG compression object is a "struct jpeg_compress_struct". (It also has +a bunch of subsidiary structures which are allocated via malloc(), but the +application doesn't control those directly.) This struct can be just a local +variable in the calling routine, if a single routine is going to execute the +whole JPEG compression sequence. Otherwise it can be static or allocated +from malloc(). + +You will also need a structure representing a JPEG error handler. The part +of this that the library cares about is a "struct jpeg_error_mgr". If you +are providing your own error handler, you'll typically want to embed the +jpeg_error_mgr struct in a larger structure; this is discussed later under +"Error handling". For now we'll assume you are just using the default error +handler. The default error handler will print JPEG error/warning messages +on stderr, and it will call exit() if a fatal error occurs. + +You must initialize the error handler structure, store a pointer to it into +the JPEG object's "err" field, and then call jpeg_create_compress() to +initialize the rest of the JPEG object. + +Typical code for this step, if you are using the default error handler, is + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + ... + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + +jpeg_create_compress allocates a small amount of memory, so it could fail +if you are out of memory. In that case it will exit via the error handler; +that's why the error handler must be initialized first. + + +2. Specify the destination for the compressed data (eg, a file). + +As previously mentioned, the JPEG library delivers compressed data to a +"data destination" module. The library includes one data destination +module which knows how to write to a stdio stream. You can use your own +destination module if you want to do something else, as discussed later. + +If you use the standard destination module, you must open the target stdio +stream beforehand. Typical code for this step looks like: + + FILE * outfile; + ... + if ((outfile = fopen(filename, "wb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + exit(1); + } + jpeg_stdio_dest(&cinfo, outfile); + +where the last line invokes the standard destination module. + +WARNING: it is critical that the binary compressed data be delivered to the +output file unchanged. On non-Unix systems the stdio library may perform +newline translation or otherwise corrupt binary data. To suppress this +behavior, you may need to use a "b" option to fopen (as shown above), or use +setmode() or another routine to put the stdio stream in binary mode. See +cjpeg.c and djpeg.c for code that has been found to work on many systems. + +You can select the data destination after setting other parameters (step 3), +if that's more convenient. You may not change the destination between +calling jpeg_start_compress() and jpeg_finish_compress(). + + +3. Set parameters for compression, including image size & colorspace. + +You must supply information about the source image by setting the following +fields in the JPEG object (cinfo structure): + + image_width Width of image, in pixels + image_height Height of image, in pixels + input_components Number of color channels (samples per pixel) + in_color_space Color space of source image + +The image dimensions are, hopefully, obvious. JPEG supports image dimensions +of 1 to 64K pixels in either direction. The input color space is typically +RGB or grayscale, and input_components is 3 or 1 accordingly. (See "Special +color spaces", later, for more info.) The in_color_space field must be +assigned one of the J_COLOR_SPACE enum constants, typically JCS_RGB or +JCS_GRAYSCALE. + +JPEG has a large number of compression parameters that determine how the +image is encoded. Most applications don't need or want to know about all +these parameters. You can set all the parameters to reasonable defaults by +calling jpeg_set_defaults(); then, if there are particular values you want +to change, you can do so after that. The "Compression parameter selection" +section tells about all the parameters. + +You must set in_color_space correctly before calling jpeg_set_defaults(), +because the defaults depend on the source image colorspace. However the +other three source image parameters need not be valid until you call +jpeg_start_compress(). There's no harm in calling jpeg_set_defaults() more +than once, if that happens to be convenient. + +Typical code for a 24-bit RGB source image is + + cinfo.image_width = Width; /* image width and height, in pixels */ + cinfo.image_height = Height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + /* Make optional parameter settings here */ + + +4. jpeg_start_compress(...); + +After you have established the data destination and set all the necessary +source image info and other parameters, call jpeg_start_compress() to begin +a compression cycle. This will initialize internal state, allocate working +storage, and emit the first few bytes of the JPEG datastream header. + +Typical code: + + jpeg_start_compress(&cinfo, TRUE); + +The "TRUE" parameter ensures that a complete JPEG interchange datastream +will be written. This is appropriate in most cases. If you think you might +want to use an abbreviated datastream, read the section on abbreviated +datastreams, below. + +Once you have called jpeg_start_compress(), you may not alter any JPEG +parameters or other fields of the JPEG object until you have completed +the compression cycle. + + +5. while (scan lines remain to be written) + jpeg_write_scanlines(...); + +Now write all the required image data by calling jpeg_write_scanlines() +one or more times. You can pass one or more scanlines in each call, up +to the total image height. In most applications it is convenient to pass +just one or a few scanlines at a time. The expected format for the passed +data is discussed under "Data formats", above. + +Image data should be written in top-to-bottom scanline order. The JPEG spec +contains some weasel wording about how top and bottom are application-defined +terms (a curious interpretation of the English language...) but if you want +your files to be compatible with everyone else's, you WILL use top-to-bottom +order. If the source data must be read in bottom-to-top order, you can use +the JPEG library's virtual array mechanism to invert the data efficiently. +Examples of this can be found in the sample application cjpeg. + +The library maintains a count of the number of scanlines written so far +in the next_scanline field of the JPEG object. Usually you can just use +this variable as the loop counter, so that the loop test looks like +"while (cinfo.next_scanline < cinfo.image_height)". + +Code for this step depends heavily on the way that you store the source data. +example.c shows the following code for the case of a full-size 2-D source +array containing 3-byte RGB pixels: + + JSAMPROW row_pointer[1]; /* pointer to a single row */ + int row_stride; /* physical row width in buffer */ + + row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ + + while (cinfo.next_scanline < cinfo.image_height) { + row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + +jpeg_write_scanlines() returns the number of scanlines actually written. +This will normally be equal to the number passed in, so you can usually +ignore the return value. It is different in just two cases: + * If you try to write more scanlines than the declared image height, + the additional scanlines are ignored. + * If you use a suspending data destination manager, output buffer overrun + will cause the compressor to return before accepting all the passed lines. + This feature is discussed under "I/O suspension", below. The normal + stdio destination manager will NOT cause this to happen. +In any case, the return value is the same as the change in the value of +next_scanline. + + +6. jpeg_finish_compress(...); + +After all the image data has been written, call jpeg_finish_compress() to +complete the compression cycle. This step is ESSENTIAL to ensure that the +last bufferload of data is written to the data destination. +jpeg_finish_compress() also releases working memory associated with the JPEG +object. + +Typical code: + + jpeg_finish_compress(&cinfo); + +If using the stdio destination manager, don't forget to close the output +stdio stream (if necessary) afterwards. + +If you have requested a multi-pass operating mode, such as Huffman code +optimization, jpeg_finish_compress() will perform the additional passes using +data buffered by the first pass. In this case jpeg_finish_compress() may take +quite a while to complete. With the default compression parameters, this will +not happen. + +It is an error to call jpeg_finish_compress() before writing the necessary +total number of scanlines. If you wish to abort compression, call +jpeg_abort() as discussed below. + +After completing a compression cycle, you may dispose of the JPEG object +as discussed next, or you may use it to compress another image. In that case +return to step 2, 3, or 4 as appropriate. If you do not change the +destination manager, the new datastream will be written to the same target. +If you do not change any JPEG parameters, the new datastream will be written +with the same parameters as before. Note that you can change the input image +dimensions freely between cycles, but if you change the input colorspace, you +should call jpeg_set_defaults() to adjust for the new colorspace; and then +you'll need to repeat all of step 3. + + +7. Release the JPEG compression object. + +When you are done with a JPEG compression object, destroy it by calling +jpeg_destroy_compress(). This will free all subsidiary memory (regardless of +the previous state of the object). Or you can call jpeg_destroy(), which +works for either compression or decompression objects --- this may be more +convenient if you are sharing code between compression and decompression +cases. (Actually, these routines are equivalent except for the declared type +of the passed pointer. To avoid gripes from ANSI C compilers, jpeg_destroy() +should be passed a j_common_ptr.) + +If you allocated the jpeg_compress_struct structure from malloc(), freeing +it is your responsibility --- jpeg_destroy() won't. Ditto for the error +handler structure. + +Typical code: + + jpeg_destroy_compress(&cinfo); + + +8. Aborting. + +If you decide to abort a compression cycle before finishing, you can clean up +in either of two ways: + +* If you don't need the JPEG object any more, just call + jpeg_destroy_compress() or jpeg_destroy() to release memory. This is + legitimate at any point after calling jpeg_create_compress() --- in fact, + it's safe even if jpeg_create_compress() fails. + +* If you want to re-use the JPEG object, call jpeg_abort_compress(), or call + jpeg_abort() which works on both compression and decompression objects. + This will return the object to an idle state, releasing any working memory. + jpeg_abort() is allowed at any time after successful object creation. + +Note that cleaning up the data destination, if required, is your +responsibility; neither of these routines will call term_destination(). +(See "Compressed data handling", below, for more about that.) + +jpeg_destroy() and jpeg_abort() are the only safe calls to make on a JPEG +object that has reported an error by calling error_exit (see "Error handling" +for more info). The internal state of such an object is likely to be out of +whack. Either of these two routines will return the object to a known state. + + +Decompression details +--------------------- + +Here we revisit the JPEG decompression outline given in the overview. + +1. Allocate and initialize a JPEG decompression object. + +This is just like initialization for compression, as discussed above, +except that the object is a "struct jpeg_decompress_struct" and you +call jpeg_create_decompress(). Error handling is exactly the same. + +Typical code: + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + ... + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + +(Both here and in the IJG code, we usually use variable name "cinfo" for +both compression and decompression objects.) + + +2. Specify the source of the compressed data (eg, a file). + +As previously mentioned, the JPEG library reads compressed data from a "data +source" module. The library includes one data source module which knows how +to read from a stdio stream. You can use your own source module if you want +to do something else, as discussed later. + +If you use the standard source module, you must open the source stdio stream +beforehand. Typical code for this step looks like: + + FILE * infile; + ... + if ((infile = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "can't open %s\n", filename); + exit(1); + } + jpeg_stdio_src(&cinfo, infile); + +where the last line invokes the standard source module. + +WARNING: it is critical that the binary compressed data be read unchanged. +On non-Unix systems the stdio library may perform newline translation or +otherwise corrupt binary data. To suppress this behavior, you may need to use +a "b" option to fopen (as shown above), or use setmode() or another routine to +put the stdio stream in binary mode. See cjpeg.c and djpeg.c for code that +has been found to work on many systems. + +You may not change the data source between calling jpeg_read_header() and +jpeg_finish_decompress(). If you wish to read a series of JPEG images from +a single source file, you should repeat the jpeg_read_header() to +jpeg_finish_decompress() sequence without reinitializing either the JPEG +object or the data source module; this prevents buffered input data from +being discarded. + + +3. Call jpeg_read_header() to obtain image info. + +Typical code for this step is just + + jpeg_read_header(&cinfo, TRUE); + +This will read the source datastream header markers, up to the beginning +of the compressed data proper. On return, the image dimensions and other +info have been stored in the JPEG object. The application may wish to +consult this information before selecting decompression parameters. + +More complex code is necessary if + * A suspending data source is used --- in that case jpeg_read_header() + may return before it has read all the header data. See "I/O suspension", + below. The normal stdio source manager will NOT cause this to happen. + * Abbreviated JPEG files are to be processed --- see the section on + abbreviated datastreams. Standard applications that deal only in + interchange JPEG files need not be concerned with this case either. + +It is permissible to stop at this point if you just wanted to find out the +image dimensions and other header info for a JPEG file. In that case, +call jpeg_destroy() when you are done with the JPEG object, or call +jpeg_abort() to return it to an idle state before selecting a new data +source and reading another header. + + +4. Set parameters for decompression. + +jpeg_read_header() sets appropriate default decompression parameters based on +the properties of the image (in particular, its colorspace). However, you +may well want to alter these defaults before beginning the decompression. +For example, the default is to produce full color output from a color file. +If you want colormapped output you must ask for it. Other options allow the +returned image to be scaled and allow various speed/quality tradeoffs to be +selected. "Decompression parameter selection", below, gives details. + +If the defaults are appropriate, nothing need be done at this step. + +Note that all default values are set by each call to jpeg_read_header(). +If you reuse a decompression object, you cannot expect your parameter +settings to be preserved across cycles, as you can for compression. +You must set desired parameter values each time. + + +5. jpeg_start_decompress(...); + +Once the parameter values are satisfactory, call jpeg_start_decompress() to +begin decompression. This will initialize internal state, allocate working +memory, and prepare for returning data. + +Typical code is just + + jpeg_start_decompress(&cinfo); + +If you have requested a multi-pass operating mode, such as 2-pass color +quantization, jpeg_start_decompress() will do everything needed before data +output can begin. In this case jpeg_start_decompress() may take quite a while +to complete. With a single-scan (non progressive) JPEG file and default +decompression parameters, this will not happen; jpeg_start_decompress() will +return quickly. + +After this call, the final output image dimensions, including any requested +scaling, are available in the JPEG object; so is the selected colormap, if +colormapped output has been requested. Useful fields include + + output_width image width and height, as scaled + output_height + out_color_components # of color components in out_color_space + output_components # of color components returned per pixel + colormap the selected colormap, if any + actual_number_of_colors number of entries in colormap + +output_components is 1 (a colormap index) when quantizing colors; otherwise it +equals out_color_components. It is the number of JSAMPLE values that will be +emitted per pixel in the output arrays. + +Typically you will need to allocate data buffers to hold the incoming image. +You will need output_width * output_components JSAMPLEs per scanline in your +output buffer, and a total of output_height scanlines will be returned. + +Note: if you are using the JPEG library's internal memory manager to allocate +data buffers (as djpeg does), then the manager's protocol requires that you +request large buffers *before* calling jpeg_start_decompress(). This is a +little tricky since the output_XXX fields are not normally valid then. You +can make them valid by calling jpeg_calc_output_dimensions() after setting the +relevant parameters (scaling, output color space, and quantization flag). + + +6. while (scan lines remain to be read) + jpeg_read_scanlines(...); + +Now you can read the decompressed image data by calling jpeg_read_scanlines() +one or more times. At each call, you pass in the maximum number of scanlines +to be read (ie, the height of your working buffer); jpeg_read_scanlines() +will return up to that many lines. The return value is the number of lines +actually read. The format of the returned data is discussed under "Data +formats", above. Don't forget that grayscale and color JPEGs will return +different data formats! + +Image data is returned in top-to-bottom scanline order. If you must write +out the image in bottom-to-top order, you can use the JPEG library's virtual +array mechanism to invert the data efficiently. Examples of this can be +found in the sample application djpeg. + +The library maintains a count of the number of scanlines returned so far +in the output_scanline field of the JPEG object. Usually you can just use +this variable as the loop counter, so that the loop test looks like +"while (cinfo.output_scanline < cinfo.output_height)". (Note that the test +should NOT be against image_height, unless you never use scaling. The +image_height field is the height of the original unscaled image.) +The return value always equals the change in the value of output_scanline. + +If you don't use a suspending data source, it is safe to assume that +jpeg_read_scanlines() reads at least one scanline per call, until the +bottom of the image has been reached. + +If you use a buffer larger than one scanline, it is NOT safe to assume that +jpeg_read_scanlines() fills it. (The current implementation returns only a +few scanlines per call, no matter how large a buffer you pass.) So you must +always provide a loop that calls jpeg_read_scanlines() repeatedly until the +whole image has been read. + + +7. jpeg_finish_decompress(...); + +After all the image data has been read, call jpeg_finish_decompress() to +complete the decompression cycle. This causes working memory associated +with the JPEG object to be released. + +Typical code: + + jpeg_finish_decompress(&cinfo); + +If using the stdio source manager, don't forget to close the source stdio +stream if necessary. + +It is an error to call jpeg_finish_decompress() before reading the correct +total number of scanlines. If you wish to abort decompression, call +jpeg_abort() as discussed below. + +After completing a decompression cycle, you may dispose of the JPEG object as +discussed next, or you may use it to decompress another image. In that case +return to step 2 or 3 as appropriate. If you do not change the source +manager, the next image will be read from the same source. + + +8. Release the JPEG decompression object. + +When you are done with a JPEG decompression object, destroy it by calling +jpeg_destroy_decompress() or jpeg_destroy(). The previous discussion of +destroying compression objects applies here too. + +Typical code: + + jpeg_destroy_decompress(&cinfo); + + +9. Aborting. + +You can abort a decompression cycle by calling jpeg_destroy_decompress() or +jpeg_destroy() if you don't need the JPEG object any more, or +jpeg_abort_decompress() or jpeg_abort() if you want to reuse the object. +The previous discussion of aborting compression cycles applies here too. + + +Mechanics of usage: include files, linking, etc +----------------------------------------------- + +Applications using the JPEG library should include the header file jpeglib.h +to obtain declarations of data types and routines. Before including +jpeglib.h, include system headers that define at least the typedefs FILE and +size_t. On ANSI-conforming systems, including is sufficient; on +older Unix systems, you may need to define size_t. + +If the application needs to refer to individual JPEG library error codes, also +include jerror.h to define those symbols. + +jpeglib.h indirectly includes the files jconfig.h and jmorecfg.h. If you are +installing the JPEG header files in a system directory, you will want to +install all four files: jpeglib.h, jerror.h, jconfig.h, jmorecfg.h. + +The most convenient way to include the JPEG code into your executable program +is to prepare a library file ("libjpeg.a", or a corresponding name on non-Unix +machines) and reference it at your link step. If you use only half of the +library (only compression or only decompression), only that much code will be +included from the library, unless your linker is hopelessly brain-damaged. +The supplied makefiles build libjpeg.a automatically (see install.doc). + +While you can build the JPEG library as a shared library if the whim strikes +you, we don't really recommend it. The trouble with shared libraries is that +at some point you'll probably try to substitute a new version of the library +without recompiling the calling applications. That generally doesn't work +because the parameter struct declarations usually change with each new +version. In other words, the library's API is *not* guaranteed binary +compatible across versions; we only try to ensure source-code compatibility. +(In hindsight, it might have been smarter to hide the parameter structs from +applications and introduce a ton of access functions instead. Too late now, +however.) + +On some systems your application may need to set up a signal handler to ensure +that temporary files are deleted if the program is interrupted. This is most +critical if you are on MS-DOS and use the jmemdos.c memory manager back end; +it will try to grab extended memory for temp files, and that space will NOT be +freed automatically. See cjpeg.c or djpeg.c for an example signal handler. + +It may be worth pointing out that the core JPEG library does not actually +require the stdio library: only the default source/destination managers and +error handler need it. You can use the library in a stdio-less environment +if you replace those modules and use jmemnobs.c (or another memory manager of +your own devising). More info about the minimum system library requirements +may be found in jinclude.h. + + +ADVANCED FEATURES +================= + +Compression parameter selection +------------------------------- + +This section describes all the optional parameters you can set for JPEG +compression, as well as the "helper" routines provided to assist in this +task. Proper setting of some parameters requires detailed understanding +of the JPEG standard; if you don't know what a parameter is for, it's best +not to mess with it! See REFERENCES in the README file for pointers to +more info about JPEG. + +It's a good idea to call jpeg_set_defaults() first, even if you plan to set +all the parameters; that way your code is more likely to work with future JPEG +libraries that have additional parameters. For the same reason, we recommend +you use a helper routine where one is provided, in preference to twiddling +cinfo fields directly. + +The helper routines are: + +jpeg_set_defaults (j_compress_ptr cinfo) + This routine sets all JPEG parameters to reasonable defaults, using + only the input image's color space (field in_color_space, which must + already be set in cinfo). Many applications will only need to use + this routine and perhaps jpeg_set_quality(). + +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) + Sets the JPEG file's colorspace (field jpeg_color_space) as specified, + and sets other color-space-dependent parameters appropriately. See + "Special color spaces", below, before using this. A large number of + parameters, including all per-component parameters, are set by this + routine; if you want to twiddle individual parameters you should call + jpeg_set_colorspace() before rather than after. + +jpeg_default_colorspace (j_compress_ptr cinfo) + Selects an appropriate JPEG colorspace based on cinfo->in_color_space, + and calls jpeg_set_colorspace(). This is actually a subroutine of + jpeg_set_defaults(). It's broken out in case you want to change + just the colorspace-dependent JPEG parameters. + +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) + Constructs JPEG quantization tables appropriate for the indicated + quality setting. The quality value is expressed on the 0..100 scale + recommended by IJG (cjpeg's "-quality" switch uses this routine). + Note that the exact mapping from quality values to tables may change + in future IJG releases as more is learned about DCT quantization. + If the force_baseline parameter is TRUE, then the quantization table + entries are constrained to the range 1..255 for full JPEG baseline + compatibility. In the current implementation, this only makes a + difference for quality settings below 25, and it effectively prevents + very small/low quality files from being generated. The IJG decoder + is capable of reading the non-baseline files generated at low quality + settings when force_baseline is FALSE, but other decoders may not be. + +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline) + Same as jpeg_set_quality() except that the generated tables are the + sample tables given in the JPEC spec section K.1, multiplied by the + specified scale factor (which is expressed as a percentage; thus + scale_factor = 100 reproduces the spec's tables). Note that larger + scale factors give lower quality. This entry point is useful for + conforming to the Adobe PostScript DCT conventions, but we do not + recommend linear scaling as a user-visible quality scale otherwise. + force_baseline again constrains the computed table entries to 1..255. + +int jpeg_quality_scaling (int quality) + Converts a value on the IJG-recommended quality scale to a linear + scaling percentage. Note that this routine may change or go away + in future releases --- IJG may choose to adopt a scaling method that + can't be expressed as a simple scalar multiplier, in which case the + premise of this routine collapses. Caveat user. + +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) + Allows an arbitrary quantization table to be created. which_tbl + indicates which table slot to fill. basic_table points to an array + of 64 unsigned ints given in normal array order. These values are + multiplied by scale_factor/100 and then clamped to the range 1..65535 + (or to 1..255 if force_baseline is TRUE). + CAUTION: prior to library version 6a, jpeg_add_quant_table expected + the basic table to be given in JPEG zigzag order. If you need to + write code that works with either older or newer versions of this + routine, you must check the library version number. Something like + "#if JPEG_LIB_VERSION >= 61" is the right test. + +jpeg_simple_progression (j_compress_ptr cinfo) + Generates a default scan script for writing a progressive-JPEG file. + This is the recommended method of creating a progressive file, + unless you want to make a custom scan sequence. You must ensure that + the JPEG color space is set correctly before calling this routine. + + +Compression parameters (cinfo fields) include: + +J_DCT_METHOD dct_method + Selects the algorithm used for the DCT step. Choices are: + JDCT_ISLOW: slow but accurate integer algorithm + JDCT_IFAST: faster, less accurate integer method + JDCT_FLOAT: floating-point method + JDCT_DEFAULT: default method (normally JDCT_ISLOW) + JDCT_FASTEST: fastest method (normally JDCT_IFAST) + The FLOAT method is very slightly more accurate than the ISLOW method, + but may give different results on different machines due to varying + roundoff behavior. The integer methods should give the same results + on all machines. On machines with sufficiently fast FP hardware, the + floating-point method may also be the fastest. The IFAST method is + considerably less accurate than the other two; its use is not + recommended if high quality is a concern. JDCT_DEFAULT and + JDCT_FASTEST are macros configurable by each installation. + +J_COLOR_SPACE jpeg_color_space +int num_components + The JPEG color space and corresponding number of components; see + "Special color spaces", below, for more info. We recommend using + jpeg_set_color_space() if you want to change these. + +boolean optimize_coding + TRUE causes the compressor to compute optimal Huffman coding tables + for the image. This requires an extra pass over the data and + therefore costs a good deal of space and time. The default is + FALSE, which tells the compressor to use the supplied or default + Huffman tables. In most cases optimal tables save only a few percent + of file size compared to the default tables. Note that when this is + TRUE, you need not supply Huffman tables at all, and any you do + supply will be overwritten. + +unsigned int restart_interval +int restart_in_rows + To emit restart markers in the JPEG file, set one of these nonzero. + Set restart_interval to specify the exact interval in MCU blocks. + Set restart_in_rows to specify the interval in MCU rows. (If + restart_in_rows is not 0, then restart_interval is set after the + image width in MCUs is computed.) Defaults are zero (no restarts). + One restart marker per MCU row is often a good choice. + NOTE: the overhead of restart markers is higher in grayscale JPEG + files than in color files, and MUCH higher in progressive JPEGs. + If you use restarts, you may want to use larger intervals in those + cases. + +const jpeg_scan_info * scan_info +int num_scans + By default, scan_info is NULL; this causes the compressor to write a + single-scan sequential JPEG file. If not NULL, scan_info points to + an array of scan definition records of length num_scans. The + compressor will then write a JPEG file having one scan for each scan + definition record. This is used to generate noninterleaved or + progressive JPEG files. The library checks that the scan array + defines a valid JPEG scan sequence. (jpeg_simple_progression creates + a suitable scan definition array for progressive JPEG.) This is + discussed further under "Progressive JPEG support". + +int smoothing_factor + If non-zero, the input image is smoothed; the value should be 1 for + minimal smoothing to 100 for maximum smoothing. Consult jcsample.c + for details of the smoothing algorithm. The default is zero. + +boolean write_JFIF_header + If TRUE, a JFIF APP0 marker is emitted. jpeg_set_defaults() and + jpeg_set_colorspace() set this TRUE if a JFIF-legal JPEG color space + (ie, YCbCr or grayscale) is selected, otherwise FALSE. + +UINT8 JFIF_major_version +UINT8 JFIF_minor_version + The version number to be written into the JFIF marker. + jpeg_set_defaults() initializes the version to 1.01 (major=minor=1). + You should set it to 1.02 (major=1, minor=2) if you plan to write + any JFIF 1.02 extension markers. + +UINT8 density_unit +UINT16 X_density +UINT16 Y_density + The resolution information to be written into the JFIF marker; + not used otherwise. density_unit may be 0 for unknown, + 1 for dots/inch, or 2 for dots/cm. The default values are 0,1,1 + indicating square pixels of unknown size. + +boolean write_Adobe_marker + If TRUE, an Adobe APP14 marker is emitted. jpeg_set_defaults() and + jpeg_set_colorspace() set this TRUE if JPEG color space RGB, CMYK, + or YCCK is selected, otherwise FALSE. It is generally a bad idea + to set both write_JFIF_header and write_Adobe_marker. In fact, + you probably shouldn't change the default settings at all --- the + default behavior ensures that the JPEG file's color space can be + recognized by the decoder. + +JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS] + Pointers to coefficient quantization tables, one per table slot, + or NULL if no table is defined for a slot. Usually these should + be set via one of the above helper routines; jpeg_add_quant_table() + is general enough to define any quantization table. The other + routines will set up table slot 0 for luminance quality and table + slot 1 for chrominance. + +JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS] +JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS] + Pointers to Huffman coding tables, one per table slot, or NULL if + no table is defined for a slot. Slots 0 and 1 are filled with the + JPEG sample tables by jpeg_set_defaults(). If you need to allocate + more table structures, jpeg_alloc_huff_table() may be used. + Note that optimal Huffman tables can be computed for an image + by setting optimize_coding, as discussed above; there's seldom + any need to mess with providing your own Huffman tables. + +There are some additional cinfo fields which are not documented here +because you currently can't change them; for example, you can't set +arith_code TRUE because arithmetic coding is unsupported. + + +Per-component parameters are stored in the struct cinfo.comp_info[i] for +component number i. Note that components here refer to components of the +JPEG color space, *not* the source image color space. A suitably large +comp_info[] array is allocated by jpeg_set_defaults(); if you choose not +to use that routine, it's up to you to allocate the array. + +int component_id + The one-byte identifier code to be recorded in the JPEG file for + this component. For the standard color spaces, we recommend you + leave the default values alone. + +int h_samp_factor +int v_samp_factor + Horizontal and vertical sampling factors for the component; must + be 1..4 according to the JPEG standard. Note that larger sampling + factors indicate a higher-resolution component; many people find + this behavior quite unintuitive. The default values are 2,2 for + luminance components and 1,1 for chrominance components, except + for grayscale where 1,1 is used. + +int quant_tbl_no + Quantization table number for component. The default value is + 0 for luminance components and 1 for chrominance components. + +int dc_tbl_no +int ac_tbl_no + DC and AC entropy coding table numbers. The default values are + 0 for luminance components and 1 for chrominance components. + +int component_index + Must equal the component's index in comp_info[]. (Beginning in + release v6, the compressor library will fill this in automatically; + you don't have to.) + + +Decompression parameter selection +--------------------------------- + +Decompression parameter selection is somewhat simpler than compression +parameter selection, since all of the JPEG internal parameters are +recorded in the source file and need not be supplied by the application. +(Unless you are working with abbreviated files, in which case see +"Abbreviated datastreams", below.) Decompression parameters control +the postprocessing done on the image to deliver it in a format suitable +for the application's use. Many of the parameters control speed/quality +tradeoffs, in which faster decompression may be obtained at the price of +a poorer-quality image. The defaults select the highest quality (slowest) +processing. + +The following fields in the JPEG object are set by jpeg_read_header() and +may be useful to the application in choosing decompression parameters: + +JDIMENSION image_width Width and height of image +JDIMENSION image_height +int num_components Number of color components +J_COLOR_SPACE jpeg_color_space Colorspace of image +boolean saw_JFIF_marker TRUE if a JFIF APP0 marker was seen + UINT8 JFIF_major_version Version information from JFIF marker + UINT8 JFIF_minor_version + UINT8 density_unit Resolution data from JFIF marker + UINT16 X_density + UINT16 Y_density +boolean saw_Adobe_marker TRUE if an Adobe APP14 marker was seen + UINT8 Adobe_transform Color transform code from Adobe marker + +The JPEG color space, unfortunately, is something of a guess since the JPEG +standard proper does not provide a way to record it. In practice most files +adhere to the JFIF or Adobe conventions, and the decoder will recognize these +correctly. See "Special color spaces", below, for more info. + + +The decompression parameters that determine the basic properties of the +returned image are: + +J_COLOR_SPACE out_color_space + Output color space. jpeg_read_header() sets an appropriate default + based on jpeg_color_space; typically it will be RGB or grayscale. + The application can change this field to request output in a different + colorspace. For example, set it to JCS_GRAYSCALE to get grayscale + output from a color file. (This is useful for previewing: grayscale + output is faster than full color since the color components need not + be processed.) Note that not all possible color space transforms are + currently implemented; you may need to extend jdcolor.c if you want an + unusual conversion. + +unsigned int scale_num, scale_denom + Scale the image by the fraction scale_num/scale_denom. Default is + 1/1, or no scaling. Currently, the only supported scaling ratios + are 1/1, 1/2, 1/4, and 1/8. (The library design allows for arbitrary + scaling ratios but this is not likely to be implemented any time soon.) + Smaller scaling ratios permit significantly faster decoding since + fewer pixels need be processed and a simpler IDCT method can be used. + +boolean quantize_colors + If set TRUE, colormapped output will be delivered. Default is FALSE, + meaning that full-color output will be delivered. + +The next three parameters are relevant only if quantize_colors is TRUE. + +int desired_number_of_colors + Maximum number of colors to use in generating a library-supplied color + map (the actual number of colors is returned in a different field). + Default 256. Ignored when the application supplies its own color map. + +boolean two_pass_quantize + If TRUE, an extra pass over the image is made to select a custom color + map for the image. This usually looks a lot better than the one-size- + fits-all colormap that is used otherwise. Default is TRUE. Ignored + when the application supplies its own color map. + +J_DITHER_MODE dither_mode + Selects color dithering method. Supported values are: + JDITHER_NONE no dithering: fast, very low quality + JDITHER_ORDERED ordered dither: moderate speed and quality + JDITHER_FS Floyd-Steinberg dither: slow, high quality + Default is JDITHER_FS. (At present, ordered dither is implemented + only in the single-pass, standard-colormap case. If you ask for + ordered dither when two_pass_quantize is TRUE or when you supply + an external color map, you'll get F-S dithering.) + +When quantize_colors is TRUE, the target color map is described by the next +two fields. colormap is set to NULL by jpeg_read_header(). The application +can supply a color map by setting colormap non-NULL and setting +actual_number_of_colors to the map size. Otherwise, jpeg_start_decompress() +selects a suitable color map and sets these two fields itself. +[Implementation restriction: at present, an externally supplied colormap is +only accepted for 3-component output color spaces.] + +JSAMPARRAY colormap + The color map, represented as a 2-D pixel array of out_color_components + rows and actual_number_of_colors columns. Ignored if not quantizing. + CAUTION: if the JPEG library creates its own colormap, the storage + pointed to by this field is released by jpeg_finish_decompress(). + Copy the colormap somewhere else first, if you want to save it. + +int actual_number_of_colors + The number of colors in the color map. + +Additional decompression parameters that the application may set include: + +J_DCT_METHOD dct_method + Selects the algorithm used for the DCT step. Choices are the same + as described above for compression. + +boolean do_fancy_upsampling + If TRUE, do careful upsampling of chroma components. If FALSE, + a faster but sloppier method is used. Default is TRUE. The visual + impact of the sloppier method is often very small. + +boolean do_block_smoothing + If TRUE, interblock smoothing is applied in early stages of decoding + progressive JPEG files; if FALSE, not. Default is TRUE. Early + progression stages look "fuzzy" with smoothing, "blocky" without. + In any case, block smoothing ceases to be applied after the first few + AC coefficients are known to full accuracy, so it is relevant only + when using buffered-image mode for progressive images. + +boolean enable_1pass_quant +boolean enable_external_quant +boolean enable_2pass_quant + These are significant only in buffered-image mode, which is + described in its own section below. + + +The output image dimensions are given by the following fields. These are +computed from the source image dimensions and the decompression parameters +by jpeg_start_decompress(). You can also call jpeg_calc_output_dimensions() +to obtain the values that will result from the current parameter settings. +This can be useful if you are trying to pick a scaling ratio that will get +close to a desired target size. It's also important if you are using the +JPEG library's memory manager to allocate output buffer space, because you +are supposed to request such buffers *before* jpeg_start_decompress(). + +JDIMENSION output_width Actual dimensions of output image. +JDIMENSION output_height +int out_color_components Number of color components in out_color_space. +int output_components Number of color components returned. +int rec_outbuf_height Recommended height of scanline buffer. + +When quantizing colors, output_components is 1, indicating a single color map +index per pixel. Otherwise it equals out_color_components. The output arrays +are required to be output_width * output_components JSAMPLEs wide. + +rec_outbuf_height is the recommended minimum height (in scanlines) of the +buffer passed to jpeg_read_scanlines(). If the buffer is smaller, the +library will still work, but time will be wasted due to unnecessary data +copying. In high-quality modes, rec_outbuf_height is always 1, but some +faster, lower-quality modes set it to larger values (typically 2 to 4). +If you are going to ask for a high-speed processing mode, you may as well +go to the trouble of honoring rec_outbuf_height so as to avoid data copying. +(An output buffer larger than rec_outbuf_height lines is OK, but won't +provide any material speed improvement over that height.) + + +Special color spaces +-------------------- + +The JPEG standard itself is "color blind" and doesn't specify any particular +color space. It is customary to convert color data to a luminance/chrominance +color space before compressing, since this permits greater compression. The +existing de-facto JPEG file format standards specify YCbCr or grayscale data +(JFIF), or grayscale, RGB, YCbCr, CMYK, or YCCK (Adobe). For special +applications such as multispectral images, other color spaces can be used, +but it must be understood that such files will be unportable. + +The JPEG library can handle the most common colorspace conversions (namely +RGB <=> YCbCr and CMYK <=> YCCK). It can also deal with data of an unknown +color space, passing it through without conversion. If you deal extensively +with an unusual color space, you can easily extend the library to understand +additional color spaces and perform appropriate conversions. + +For compression, the source data's color space is specified by field +in_color_space. This is transformed to the JPEG file's color space given +by jpeg_color_space. jpeg_set_defaults() chooses a reasonable JPEG color +space depending on in_color_space, but you can override this by calling +jpeg_set_colorspace(). Of course you must select a supported transformation. +jccolor.c currently supports the following transformations: + RGB => YCbCr + RGB => GRAYSCALE + YCbCr => GRAYSCALE + CMYK => YCCK +plus the null transforms: GRAYSCALE => GRAYSCALE, RGB => RGB, +YCbCr => YCbCr, CMYK => CMYK, YCCK => YCCK, and UNKNOWN => UNKNOWN. + +The de-facto file format standards (JFIF and Adobe) specify APPn markers that +indicate the color space of the JPEG file. It is important to ensure that +these are written correctly, or omitted if the JPEG file's color space is not +one of the ones supported by the de-facto standards. jpeg_set_colorspace() +will set the compression parameters to include or omit the APPn markers +properly, so long as it is told the truth about the JPEG color space. +For example, if you are writing some random 3-component color space without +conversion, don't try to fake out the library by setting in_color_space and +jpeg_color_space to JCS_YCbCr; use JCS_UNKNOWN. You may want to write an +APPn marker of your own devising to identify the colorspace --- see "Special +markers", below. + +When told that the color space is UNKNOWN, the library will default to using +luminance-quality compression parameters for all color components. You may +well want to change these parameters. See the source code for +jpeg_set_colorspace(), in jcparam.c, for details. + +For decompression, the JPEG file's color space is given in jpeg_color_space, +and this is transformed to the output color space out_color_space. +jpeg_read_header's setting of jpeg_color_space can be relied on if the file +conforms to JFIF or Adobe conventions, but otherwise it is no better than a +guess. If you know the JPEG file's color space for certain, you can override +jpeg_read_header's guess by setting jpeg_color_space. jpeg_read_header also +selects a default output color space based on (its guess of) jpeg_color_space; +set out_color_space to override this. Again, you must select a supported +transformation. jdcolor.c currently supports + YCbCr => GRAYSCALE + YCbCr => RGB + GRAYSCALE => RGB + YCCK => CMYK +as well as the null transforms. (Since GRAYSCALE=>RGB is provided, an +application can force grayscale JPEGs to look like color JPEGs if it only +wants to handle one case.) + +The two-pass color quantizer, jquant2.c, is specialized to handle RGB data +(it weights distances appropriately for RGB colors). You'll need to modify +the code if you want to use it for non-RGB output color spaces. Note that +jquant2.c is used to map to an application-supplied colormap as well as for +the normal two-pass colormap selection process. + +CAUTION: it appears that Adobe Photoshop writes inverted data in CMYK JPEG +files: 0 represents 100% ink coverage, rather than 0% ink as you'd expect. +This is arguably a bug in Photoshop, but if you need to work with Photoshop +CMYK files, you will have to deal with it in your application. We cannot +"fix" this in the library by inverting the data during the CMYK<=>YCCK +transform, because that would break other applications, notably Ghostscript. +Photoshop versions prior to 3.0 write EPS files containing JPEG-encoded CMYK +data in the same inverted-YCCK representation used in bare JPEG files, but +the surrounding PostScript code performs an inversion using the PS image +operator. I am told that Photoshop 3.0 will write uninverted YCCK in +EPS/JPEG files, and will omit the PS-level inversion. (But the data +polarity used in bare JPEG files will not change in 3.0.) In either case, +the JPEG library must not invert the data itself, or else Ghostscript would +read these EPS files incorrectly. + + +Error handling +-------------- + +When the default error handler is used, any error detected inside the JPEG +routines will cause a message to be printed on stderr, followed by exit(). +You can supply your own error handling routines to override this behavior +and to control the treatment of nonfatal warnings and trace/debug messages. +The file example.c illustrates the most common case, which is to have the +application regain control after an error rather than exiting. + +The JPEG library never writes any message directly; it always goes through +the error handling routines. Three classes of messages are recognized: + * Fatal errors: the library cannot continue. + * Warnings: the library can continue, but the data is corrupt, and a + damaged output image is likely to result. + * Trace/informational messages. These come with a trace level indicating + the importance of the message; you can control the verbosity of the + program by adjusting the maximum trace level that will be displayed. + +You may, if you wish, simply replace the entire JPEG error handling module +(jerror.c) with your own code. However, you can avoid code duplication by +only replacing some of the routines depending on the behavior you need. +This is accomplished by calling jpeg_std_error() as usual, but then overriding +some of the method pointers in the jpeg_error_mgr struct, as illustrated by +example.c. + +All of the error handling routines will receive a pointer to the JPEG object +(a j_common_ptr which points to either a jpeg_compress_struct or a +jpeg_decompress_struct; if you need to tell which, test the is_decompressor +field). This struct includes a pointer to the error manager struct in its +"err" field. Frequently, custom error handler routines will need to access +additional data which is not known to the JPEG library or the standard error +handler. The most convenient way to do this is to embed either the JPEG +object or the jpeg_error_mgr struct in a larger structure that contains +additional fields; then casting the passed pointer provides access to the +additional fields. Again, see example.c for one way to do it. (Beginning +with IJG version 6b, there is also a void pointer "client_data" in each +JPEG object, which the application can also use to find related data. +The library does not touch client_data at all.) + +The individual methods that you might wish to override are: + +error_exit (j_common_ptr cinfo) + Receives control for a fatal error. Information sufficient to + generate the error message has been stored in cinfo->err; call + output_message to display it. Control must NOT return to the caller; + generally this routine will exit() or longjmp() somewhere. + Typically you would override this routine to get rid of the exit() + default behavior. Note that if you continue processing, you should + clean up the JPEG object with jpeg_abort() or jpeg_destroy(). + +output_message (j_common_ptr cinfo) + Actual output of any JPEG message. Override this to send messages + somewhere other than stderr. Note that this method does not know + how to generate a message, only where to send it. + +format_message (j_common_ptr cinfo, char * buffer) + Constructs a readable error message string based on the error info + stored in cinfo->err. This method is called by output_message. Few + applications should need to override this method. One possible + reason for doing so is to implement dynamic switching of error message + language. + +emit_message (j_common_ptr cinfo, int msg_level) + Decide whether or not to emit a warning or trace message; if so, + calls output_message. The main reason for overriding this method + would be to abort on warnings. msg_level is -1 for warnings, + 0 and up for trace messages. + +Only error_exit() and emit_message() are called from the rest of the JPEG +library; the other two are internal to the error handler. + +The actual message texts are stored in an array of strings which is pointed to +by the field err->jpeg_message_table. The messages are numbered from 0 to +err->last_jpeg_message, and it is these code numbers that are used in the +JPEG library code. You could replace the message texts (for instance, with +messages in French or German) by changing the message table pointer. See +jerror.h for the default texts. CAUTION: this table will almost certainly +change or grow from one library version to the next. + +It may be useful for an application to add its own message texts that are +handled by the same mechanism. The error handler supports a second "add-on" +message table for this purpose. To define an addon table, set the pointer +err->addon_message_table and the message numbers err->first_addon_message and +err->last_addon_message. If you number the addon messages beginning at 1000 +or so, you won't have to worry about conflicts with the library's built-in +messages. See the sample applications cjpeg/djpeg for an example of using +addon messages (the addon messages are defined in cderror.h). + +Actual invocation of the error handler is done via macros defined in jerror.h: + ERREXITn(...) for fatal errors + WARNMSn(...) for corrupt-data warnings + TRACEMSn(...) for trace and informational messages. +These macros store the message code and any additional parameters into the +error handler struct, then invoke the error_exit() or emit_message() method. +The variants of each macro are for varying numbers of additional parameters. +The additional parameters are inserted into the generated message using +standard printf() format codes. + +See jerror.h and jerror.c for further details. + + +Compressed data handling (source and destination managers) +---------------------------------------------------------- + +The JPEG compression library sends its compressed data to a "destination +manager" module. The default destination manager just writes the data to a +stdio stream, but you can provide your own manager to do something else. +Similarly, the decompression library calls a "source manager" to obtain the +compressed data; you can provide your own source manager if you want the data +to come from somewhere other than a stdio stream. + +In both cases, compressed data is processed a bufferload at a time: the +destination or source manager provides a work buffer, and the library invokes +the manager only when the buffer is filled or emptied. (You could define a +one-character buffer to force the manager to be invoked for each byte, but +that would be rather inefficient.) The buffer's size and location are +controlled by the manager, not by the library. For example, if you desired to +decompress a JPEG datastream that was all in memory, you could just make the +buffer pointer and length point to the original data in memory. Then the +buffer-reload procedure would be invoked only if the decompressor ran off the +end of the datastream, which would indicate an erroneous datastream. + +The work buffer is defined as an array of datatype JOCTET, which is generally +"char" or "unsigned char". On a machine where char is not exactly 8 bits +wide, you must define JOCTET as a wider data type and then modify the data +source and destination modules to transcribe the work arrays into 8-bit units +on external storage. + +A data destination manager struct contains a pointer and count defining the +next byte to write in the work buffer and the remaining free space: + + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + +The library increments the pointer and decrements the count until the buffer +is filled. The manager's empty_output_buffer method must reset the pointer +and count. The manager is expected to remember the buffer's starting address +and total size in private fields not visible to the library. + +A data destination manager provides three methods: + +init_destination (j_compress_ptr cinfo) + Initialize destination. This is called by jpeg_start_compress() + before any data is actually written. It must initialize + next_output_byte and free_in_buffer. free_in_buffer must be + initialized to a positive value. + +empty_output_buffer (j_compress_ptr cinfo) + This is called whenever the buffer has filled (free_in_buffer + reaches zero). In typical applications, it should write out the + *entire* buffer (use the saved start address and buffer length; + ignore the current state of next_output_byte and free_in_buffer). + Then reset the pointer & count to the start of the buffer, and + return TRUE indicating that the buffer has been dumped. + free_in_buffer must be set to a positive value when TRUE is + returned. A FALSE return should only be used when I/O suspension is + desired (this operating mode is discussed in the next section). + +term_destination (j_compress_ptr cinfo) + Terminate destination --- called by jpeg_finish_compress() after all + data has been written. In most applications, this must flush any + data remaining in the buffer. Use either next_output_byte or + free_in_buffer to determine how much data is in the buffer. + +term_destination() is NOT called by jpeg_abort() or jpeg_destroy(). If you +want the destination manager to be cleaned up during an abort, you must do it +yourself. + +You will also need code to create a jpeg_destination_mgr struct, fill in its +method pointers, and insert a pointer to the struct into the "dest" field of +the JPEG compression object. This can be done in-line in your setup code if +you like, but it's probably cleaner to provide a separate routine similar to +the jpeg_stdio_dest() routine of the supplied destination manager. + +Decompression source managers follow a parallel design, but with some +additional frammishes. The source manager struct contains a pointer and count +defining the next byte to read from the work buffer and the number of bytes +remaining: + + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + +The library increments the pointer and decrements the count until the buffer +is emptied. The manager's fill_input_buffer method must reset the pointer and +count. In most applications, the manager must remember the buffer's starting +address and total size in private fields not visible to the library. + +A data source manager provides five methods: + +init_source (j_decompress_ptr cinfo) + Initialize source. This is called by jpeg_read_header() before any + data is actually read. Unlike init_destination(), it may leave + bytes_in_buffer set to 0 (in which case a fill_input_buffer() call + will occur immediately). + +fill_input_buffer (j_decompress_ptr cinfo) + This is called whenever bytes_in_buffer has reached zero and more + data is wanted. In typical applications, it should read fresh data + into the buffer (ignoring the current state of next_input_byte and + bytes_in_buffer), reset the pointer & count to the start of the + buffer, and return TRUE indicating that the buffer has been reloaded. + It is not necessary to fill the buffer entirely, only to obtain at + least one more byte. bytes_in_buffer MUST be set to a positive value + if TRUE is returned. A FALSE return should only be used when I/O + suspension is desired (this mode is discussed in the next section). + +skip_input_data (j_decompress_ptr cinfo, long num_bytes) + Skip num_bytes worth of data. The buffer pointer and count should + be advanced over num_bytes input bytes, refilling the buffer as + needed. This is used to skip over a potentially large amount of + uninteresting data (such as an APPn marker). In some applications + it may be possible to optimize away the reading of the skipped data, + but it's not clear that being smart is worth much trouble; large + skips are uncommon. bytes_in_buffer may be zero on return. + A zero or negative skip count should be treated as a no-op. + +resync_to_restart (j_decompress_ptr cinfo, int desired) + This routine is called only when the decompressor has failed to find + a restart (RSTn) marker where one is expected. Its mission is to + find a suitable point for resuming decompression. For most + applications, we recommend that you just use the default resync + procedure, jpeg_resync_to_restart(). However, if you are able to back + up in the input data stream, or if you have a-priori knowledge about + the likely location of restart markers, you may be able to do better. + Read the read_restart_marker() and jpeg_resync_to_restart() routines + in jdmarker.c if you think you'd like to implement your own resync + procedure. + +term_source (j_decompress_ptr cinfo) + Terminate source --- called by jpeg_finish_decompress() after all + data has been read. Often a no-op. + +For both fill_input_buffer() and skip_input_data(), there is no such thing +as an EOF return. If the end of the file has been reached, the routine has +a choice of exiting via ERREXIT() or inserting fake data into the buffer. +In most cases, generating a warning message and inserting a fake EOI marker +is the best course of action --- this will allow the decompressor to output +however much of the image is there. In pathological cases, the decompressor +may swallow the EOI and again demand data ... just keep feeding it fake EOIs. +jdatasrc.c illustrates the recommended error recovery behavior. + +term_source() is NOT called by jpeg_abort() or jpeg_destroy(). If you want +the source manager to be cleaned up during an abort, you must do it yourself. + +You will also need code to create a jpeg_source_mgr struct, fill in its method +pointers, and insert a pointer to the struct into the "src" field of the JPEG +decompression object. This can be done in-line in your setup code if you +like, but it's probably cleaner to provide a separate routine similar to the +jpeg_stdio_src() routine of the supplied source manager. + +For more information, consult the stdio source and destination managers +in jdatasrc.c and jdatadst.c. + + +I/O suspension +-------------- + +Some applications need to use the JPEG library as an incremental memory-to- +memory filter: when the compressed data buffer is filled or emptied, they want +control to return to the outer loop, rather than expecting that the buffer can +be emptied or reloaded within the data source/destination manager subroutine. +The library supports this need by providing an "I/O suspension" mode, which we +describe in this section. + +The I/O suspension mode is not a panacea: nothing is guaranteed about the +maximum amount of time spent in any one call to the library, so it will not +eliminate response-time problems in single-threaded applications. If you +need guaranteed response time, we suggest you "bite the bullet" and implement +a real multi-tasking capability. + +To use I/O suspension, cooperation is needed between the calling application +and the data source or destination manager; you will always need a custom +source/destination manager. (Please read the previous section if you haven't +already.) The basic idea is that the empty_output_buffer() or +fill_input_buffer() routine is a no-op, merely returning FALSE to indicate +that it has done nothing. Upon seeing this, the JPEG library suspends +operation and returns to its caller. The surrounding application is +responsible for emptying or refilling the work buffer before calling the +JPEG library again. + +Compression suspension: + +For compression suspension, use an empty_output_buffer() routine that returns +FALSE; typically it will not do anything else. This will cause the +compressor to return to the caller of jpeg_write_scanlines(), with the return +value indicating that not all the supplied scanlines have been accepted. +The application must make more room in the output buffer, adjust the output +buffer pointer/count appropriately, and then call jpeg_write_scanlines() +again, pointing to the first unconsumed scanline. + +When forced to suspend, the compressor will backtrack to a convenient stopping +point (usually the start of the current MCU); it will regenerate some output +data when restarted. Therefore, although empty_output_buffer() is only +called when the buffer is filled, you should NOT write out the entire buffer +after a suspension. Write only the data up to the current position of +next_output_byte/free_in_buffer. The data beyond that point will be +regenerated after resumption. + +Because of the backtracking behavior, a good-size output buffer is essential +for efficiency; you don't want the compressor to suspend often. (In fact, an +overly small buffer could lead to infinite looping, if a single MCU required +more data than would fit in the buffer.) We recommend a buffer of at least +several Kbytes. You may want to insert explicit code to ensure that you don't +call jpeg_write_scanlines() unless there is a reasonable amount of space in +the output buffer; in other words, flush the buffer before trying to compress +more data. + +The compressor does not allow suspension while it is trying to write JPEG +markers at the beginning and end of the file. This means that: + * At the beginning of a compression operation, there must be enough free + space in the output buffer to hold the header markers (typically 600 or + so bytes). The recommended buffer size is bigger than this anyway, so + this is not a problem as long as you start with an empty buffer. However, + this restriction might catch you if you insert large special markers, such + as a JFIF thumbnail image, without flushing the buffer afterwards. + * When you call jpeg_finish_compress(), there must be enough space in the + output buffer to emit any buffered data and the final EOI marker. In the + current implementation, half a dozen bytes should suffice for this, but + for safety's sake we recommend ensuring that at least 100 bytes are free + before calling jpeg_finish_compress(). + +A more significant restriction is that jpeg_finish_compress() cannot suspend. +This means you cannot use suspension with multi-pass operating modes, namely +Huffman code optimization and multiple-scan output. Those modes write the +whole file during jpeg_finish_compress(), which will certainly result in +buffer overrun. (Note that this restriction applies only to compression, +not decompression. The decompressor supports input suspension in all of its +operating modes.) + +Decompression suspension: + +For decompression suspension, use a fill_input_buffer() routine that simply +returns FALSE (except perhaps during error recovery, as discussed below). +This will cause the decompressor to return to its caller with an indication +that suspension has occurred. This can happen at four places: + * jpeg_read_header(): will return JPEG_SUSPENDED. + * jpeg_start_decompress(): will return FALSE, rather than its usual TRUE. + * jpeg_read_scanlines(): will return the number of scanlines already + completed (possibly 0). + * jpeg_finish_decompress(): will return FALSE, rather than its usual TRUE. +The surrounding application must recognize these cases, load more data into +the input buffer, and repeat the call. In the case of jpeg_read_scanlines(), +increment the passed pointers past any scanlines successfully read. + +Just as with compression, the decompressor will typically backtrack to a +convenient restart point before suspending. When fill_input_buffer() is +called, next_input_byte/bytes_in_buffer point to the current restart point, +which is where the decompressor will backtrack to if FALSE is returned. +The data beyond that position must NOT be discarded if you suspend; it needs +to be re-read upon resumption. In most implementations, you'll need to shift +this data down to the start of your work buffer and then load more data after +it. Again, this behavior means that a several-Kbyte work buffer is essential +for decent performance; furthermore, you should load a reasonable amount of +new data before resuming decompression. (If you loaded, say, only one new +byte each time around, you could waste a LOT of cycles.) + +The skip_input_data() source manager routine requires special care in a +suspension scenario. This routine is NOT granted the ability to suspend the +decompressor; it can decrement bytes_in_buffer to zero, but no more. If the +requested skip distance exceeds the amount of data currently in the input +buffer, then skip_input_data() must set bytes_in_buffer to zero and record the +additional skip distance somewhere else. The decompressor will immediately +call fill_input_buffer(), which should return FALSE, which will cause a +suspension return. The surrounding application must then arrange to discard +the recorded number of bytes before it resumes loading the input buffer. +(Yes, this design is rather baroque, but it avoids complexity in the far more +common case where a non-suspending source manager is used.) + +If the input data has been exhausted, we recommend that you emit a warning +and insert dummy EOI markers just as a non-suspending data source manager +would do. This can be handled either in the surrounding application logic or +within fill_input_buffer(); the latter is probably more efficient. If +fill_input_buffer() knows that no more data is available, it can set the +pointer/count to point to a dummy EOI marker and then return TRUE just as +though it had read more data in a non-suspending situation. + +The decompressor does not attempt to suspend within standard JPEG markers; +instead it will backtrack to the start of the marker and reprocess the whole +marker next time. Hence the input buffer must be large enough to hold the +longest standard marker in the file. Standard JPEG markers should normally +not exceed a few hundred bytes each (DHT tables are typically the longest). +We recommend at least a 2K buffer for performance reasons, which is much +larger than any correct marker is likely to be. For robustness against +damaged marker length counts, you may wish to insert a test in your +application for the case that the input buffer is completely full and yet +the decoder has suspended without consuming any data --- otherwise, if this +situation did occur, it would lead to an endless loop. (The library can't +provide this test since it has no idea whether "the buffer is full", or +even whether there is a fixed-size input buffer.) + +The input buffer would need to be 64K to allow for arbitrary COM or APPn +markers, but these are handled specially: they are either saved into allocated +memory, or skipped over by calling skip_input_data(). In the former case, +suspension is handled correctly, and in the latter case, the problem of +buffer overrun is placed on skip_input_data's shoulders, as explained above. +Note that if you provide your own marker handling routine for large markers, +you should consider how to deal with buffer overflow. + +Multiple-buffer management: + +In some applications it is desirable to store the compressed data in a linked +list of buffer areas, so as to avoid data copying. This can be handled by +having empty_output_buffer() or fill_input_buffer() set the pointer and count +to reference the next available buffer; FALSE is returned only if no more +buffers are available. Although seemingly straightforward, there is a +pitfall in this approach: the backtrack that occurs when FALSE is returned +could back up into an earlier buffer. For example, when fill_input_buffer() +is called, the current pointer & count indicate the backtrack restart point. +Since fill_input_buffer() will set the pointer and count to refer to a new +buffer, the restart position must be saved somewhere else. Suppose a second +call to fill_input_buffer() occurs in the same library call, and no +additional input data is available, so fill_input_buffer must return FALSE. +If the JPEG library has not moved the pointer/count forward in the current +buffer, then *the correct restart point is the saved position in the prior +buffer*. Prior buffers may be discarded only after the library establishes +a restart point within a later buffer. Similar remarks apply for output into +a chain of buffers. + +The library will never attempt to backtrack over a skip_input_data() call, +so any skipped data can be permanently discarded. You still have to deal +with the case of skipping not-yet-received data, however. + +It's much simpler to use only a single buffer; when fill_input_buffer() is +called, move any unconsumed data (beyond the current pointer/count) down to +the beginning of this buffer and then load new data into the remaining buffer +space. This approach requires a little more data copying but is far easier +to get right. + + +Progressive JPEG support +------------------------ + +Progressive JPEG rearranges the stored data into a series of scans of +increasing quality. In situations where a JPEG file is transmitted across a +slow communications link, a decoder can generate a low-quality image very +quickly from the first scan, then gradually improve the displayed quality as +more scans are received. The final image after all scans are complete is +identical to that of a regular (sequential) JPEG file of the same quality +setting. Progressive JPEG files are often slightly smaller than equivalent +sequential JPEG files, but the possibility of incremental display is the main +reason for using progressive JPEG. + +The IJG encoder library generates progressive JPEG files when given a +suitable "scan script" defining how to divide the data into scans. +Creation of progressive JPEG files is otherwise transparent to the encoder. +Progressive JPEG files can also be read transparently by the decoder library. +If the decoding application simply uses the library as defined above, it +will receive a final decoded image without any indication that the file was +progressive. Of course, this approach does not allow incremental display. +To perform incremental display, an application needs to use the decoder +library's "buffered-image" mode, in which it receives a decoded image +multiple times. + +Each displayed scan requires about as much work to decode as a full JPEG +image of the same size, so the decoder must be fairly fast in relation to the +data transmission rate in order to make incremental display useful. However, +it is possible to skip displaying the image and simply add the incoming bits +to the decoder's coefficient buffer. This is fast because only Huffman +decoding need be done, not IDCT, upsampling, colorspace conversion, etc. +The IJG decoder library allows the application to switch dynamically between +displaying the image and simply absorbing the incoming bits. A properly +coded application can automatically adapt the number of display passes to +suit the time available as the image is received. Also, a final +higher-quality display cycle can be performed from the buffered data after +the end of the file is reached. + +Progressive compression: + +To create a progressive JPEG file (or a multiple-scan sequential JPEG file), +set the scan_info cinfo field to point to an array of scan descriptors, and +perform compression as usual. Instead of constructing your own scan list, +you can call the jpeg_simple_progression() helper routine to create a +recommended progression sequence; this method should be used by all +applications that don't want to get involved in the nitty-gritty of +progressive scan sequence design. (If you want to provide user control of +scan sequences, you may wish to borrow the scan script reading code found +in rdswitch.c, so that you can read scan script files just like cjpeg's.) +When scan_info is not NULL, the compression library will store DCT'd data +into a buffer array as jpeg_write_scanlines() is called, and will emit all +the requested scans during jpeg_finish_compress(). This implies that +multiple-scan output cannot be created with a suspending data destination +manager, since jpeg_finish_compress() does not support suspension. We +should also note that the compressor currently forces Huffman optimization +mode when creating a progressive JPEG file, because the default Huffman +tables are unsuitable for progressive files. + +Progressive decompression: + +When buffered-image mode is not used, the decoder library will read all of +a multi-scan file during jpeg_start_decompress(), so that it can provide a +final decoded image. (Here "multi-scan" means either progressive or +multi-scan sequential.) This makes multi-scan files transparent to the +decoding application. However, existing applications that used suspending +input with version 5 of the IJG library will need to be modified to check +for a suspension return from jpeg_start_decompress(). + +To perform incremental display, an application must use the library's +buffered-image mode. This is described in the next section. + + +Buffered-image mode +------------------- + +In buffered-image mode, the library stores the partially decoded image in a +coefficient buffer, from which it can be read out as many times as desired. +This mode is typically used for incremental display of progressive JPEG files, +but it can be used with any JPEG file. Each scan of a progressive JPEG file +adds more data (more detail) to the buffered image. The application can +display in lockstep with the source file (one display pass per input scan), +or it can allow input processing to outrun display processing. By making +input and display processing run independently, it is possible for the +application to adapt progressive display to a wide range of data transmission +rates. + +The basic control flow for buffered-image decoding is + + jpeg_create_decompress() + set data source + jpeg_read_header() + set overall decompression parameters + cinfo.buffered_image = TRUE; /* select buffered-image mode */ + jpeg_start_decompress() + for (each output pass) { + adjust output decompression parameters if required + jpeg_start_output() /* start a new output pass */ + for (all scanlines in image) { + jpeg_read_scanlines() + display scanlines + } + jpeg_finish_output() /* terminate output pass */ + } + jpeg_finish_decompress() + jpeg_destroy_decompress() + +This differs from ordinary unbuffered decoding in that there is an additional +level of looping. The application can choose how many output passes to make +and how to display each pass. + +The simplest approach to displaying progressive images is to do one display +pass for each scan appearing in the input file. In this case the outer loop +condition is typically + while (! jpeg_input_complete(&cinfo)) +and the start-output call should read + jpeg_start_output(&cinfo, cinfo.input_scan_number); +The second parameter to jpeg_start_output() indicates which scan of the input +file is to be displayed; the scans are numbered starting at 1 for this +purpose. (You can use a loop counter starting at 1 if you like, but using +the library's input scan counter is easier.) The library automatically reads +data as necessary to complete each requested scan, and jpeg_finish_output() +advances to the next scan or end-of-image marker (hence input_scan_number +will be incremented by the time control arrives back at jpeg_start_output()). +With this technique, data is read from the input file only as needed, and +input and output processing run in lockstep. + +After reading the final scan and reaching the end of the input file, the +buffered image remains available; it can be read additional times by +repeating the jpeg_start_output()/jpeg_read_scanlines()/jpeg_finish_output() +sequence. For example, a useful technique is to use fast one-pass color +quantization for display passes made while the image is arriving, followed by +a final display pass using two-pass quantization for highest quality. This +is done by changing the library parameters before the final output pass. +Changing parameters between passes is discussed in detail below. + +In general the last scan of a progressive file cannot be recognized as such +until after it is read, so a post-input display pass is the best approach if +you want special processing in the final pass. + +When done with the image, be sure to call jpeg_finish_decompress() to release +the buffered image (or just use jpeg_destroy_decompress()). + +If input data arrives faster than it can be displayed, the application can +cause the library to decode input data in advance of what's needed to produce +output. This is done by calling the routine jpeg_consume_input(). +The return value is one of the following: + JPEG_REACHED_SOS: reached an SOS marker (the start of a new scan) + JPEG_REACHED_EOI: reached the EOI marker (end of image) + JPEG_ROW_COMPLETED: completed reading one MCU row of compressed data + JPEG_SCAN_COMPLETED: completed reading last MCU row of current scan + JPEG_SUSPENDED: suspended before completing any of the above +(JPEG_SUSPENDED can occur only if a suspending data source is used.) This +routine can be called at any time after initializing the JPEG object. It +reads some additional data and returns when one of the indicated significant +events occurs. (If called after the EOI marker is reached, it will +immediately return JPEG_REACHED_EOI without attempting to read more data.) + +The library's output processing will automatically call jpeg_consume_input() +whenever the output processing overtakes the input; thus, simple lockstep +display requires no direct calls to jpeg_consume_input(). But by adding +calls to jpeg_consume_input(), you can absorb data in advance of what is +being displayed. This has two benefits: + * You can limit buildup of unprocessed data in your input buffer. + * You can eliminate extra display passes by paying attention to the + state of the library's input processing. + +The first of these benefits only requires interspersing calls to +jpeg_consume_input() with your display operations and any other processing +you may be doing. To avoid wasting cycles due to backtracking, it's best to +call jpeg_consume_input() only after a hundred or so new bytes have arrived. +This is discussed further under "I/O suspension", above. (Note: the JPEG +library currently is not thread-safe. You must not call jpeg_consume_input() +from one thread of control if a different library routine is working on the +same JPEG object in another thread.) + +When input arrives fast enough that more than one new scan is available +before you start a new output pass, you may as well skip the output pass +corresponding to the completed scan. This occurs for free if you pass +cinfo.input_scan_number as the target scan number to jpeg_start_output(). +The input_scan_number field is simply the index of the scan currently being +consumed by the input processor. You can ensure that this is up-to-date by +emptying the input buffer just before calling jpeg_start_output(): call +jpeg_consume_input() repeatedly until it returns JPEG_SUSPENDED or +JPEG_REACHED_EOI. + +The target scan number passed to jpeg_start_output() is saved in the +cinfo.output_scan_number field. The library's output processing calls +jpeg_consume_input() whenever the current input scan number and row within +that scan is less than or equal to the current output scan number and row. +Thus, input processing can "get ahead" of the output processing but is not +allowed to "fall behind". You can achieve several different effects by +manipulating this interlock rule. For example, if you pass a target scan +number greater than the current input scan number, the output processor will +wait until that scan starts to arrive before producing any output. (To avoid +an infinite loop, the target scan number is automatically reset to the last +scan number when the end of image is reached. Thus, if you specify a large +target scan number, the library will just absorb the entire input file and +then perform an output pass. This is effectively the same as what +jpeg_start_decompress() does when you don't select buffered-image mode.) +When you pass a target scan number equal to the current input scan number, +the image is displayed no faster than the current input scan arrives. The +final possibility is to pass a target scan number less than the current input +scan number; this disables the input/output interlock and causes the output +processor to simply display whatever it finds in the image buffer, without +waiting for input. (However, the library will not accept a target scan +number less than one, so you can't avoid waiting for the first scan.) + +When data is arriving faster than the output display processing can advance +through the image, jpeg_consume_input() will store data into the buffered +image beyond the point at which the output processing is reading data out +again. If the input arrives fast enough, it may "wrap around" the buffer to +the point where the input is more than one whole scan ahead of the output. +If the output processing simply proceeds through its display pass without +paying attention to the input, the effect seen on-screen is that the lower +part of the image is one or more scans better in quality than the upper part. +Then, when the next output scan is started, you have a choice of what target +scan number to use. The recommended choice is to use the current input scan +number at that time, which implies that you've skipped the output scans +corresponding to the input scans that were completed while you processed the +previous output scan. In this way, the decoder automatically adapts its +speed to the arriving data, by skipping output scans as necessary to keep up +with the arriving data. + +When using this strategy, you'll want to be sure that you perform a final +output pass after receiving all the data; otherwise your last display may not +be full quality across the whole screen. So the right outer loop logic is +something like this: + do { + absorb any waiting input by calling jpeg_consume_input() + final_pass = jpeg_input_complete(&cinfo); + adjust output decompression parameters if required + jpeg_start_output(&cinfo, cinfo.input_scan_number); + ... + jpeg_finish_output() + } while (! final_pass); +rather than quitting as soon as jpeg_input_complete() returns TRUE. This +arrangement makes it simple to use higher-quality decoding parameters +for the final pass. But if you don't want to use special parameters for +the final pass, the right loop logic is like this: + for (;;) { + absorb any waiting input by calling jpeg_consume_input() + jpeg_start_output(&cinfo, cinfo.input_scan_number); + ... + jpeg_finish_output() + if (jpeg_input_complete(&cinfo) && + cinfo.input_scan_number == cinfo.output_scan_number) + break; + } +In this case you don't need to know in advance whether an output pass is to +be the last one, so it's not necessary to have reached EOF before starting +the final output pass; rather, what you want to test is whether the output +pass was performed in sync with the final input scan. This form of the loop +will avoid an extra output pass whenever the decoder is able (or nearly able) +to keep up with the incoming data. + +When the data transmission speed is high, you might begin a display pass, +then find that much or all of the file has arrived before you can complete +the pass. (You can detect this by noting the JPEG_REACHED_EOI return code +from jpeg_consume_input(), or equivalently by testing jpeg_input_complete().) +In this situation you may wish to abort the current display pass and start a +new one using the newly arrived information. To do so, just call +jpeg_finish_output() and then start a new pass with jpeg_start_output(). + +A variant strategy is to abort and restart display if more than one complete +scan arrives during an output pass; this can be detected by noting +JPEG_REACHED_SOS returns and/or examining cinfo.input_scan_number. This +idea should be employed with caution, however, since the display process +might never get to the bottom of the image before being aborted, resulting +in the lower part of the screen being several passes worse than the upper. +In most cases it's probably best to abort an output pass only if the whole +file has arrived and you want to begin the final output pass immediately. + +When receiving data across a communication link, we recommend always using +the current input scan number for the output target scan number; if a +higher-quality final pass is to be done, it should be started (aborting any +incomplete output pass) as soon as the end of file is received. However, +many other strategies are possible. For example, the application can examine +the parameters of the current input scan and decide whether to display it or +not. If the scan contains only chroma data, one might choose not to use it +as the target scan, expecting that the scan will be small and will arrive +quickly. To skip to the next scan, call jpeg_consume_input() until it +returns JPEG_REACHED_SOS or JPEG_REACHED_EOI. Or just use the next higher +number as the target scan for jpeg_start_output(); but that method doesn't +let you inspect the next scan's parameters before deciding to display it. + + +In buffered-image mode, jpeg_start_decompress() never performs input and +thus never suspends. An application that uses input suspension with +buffered-image mode must be prepared for suspension returns from these +routines: +* jpeg_start_output() performs input only if you request 2-pass quantization + and the target scan isn't fully read yet. (This is discussed below.) +* jpeg_read_scanlines(), as always, returns the number of scanlines that it + was able to produce before suspending. +* jpeg_finish_output() will read any markers following the target scan, + up to the end of the file or the SOS marker that begins another scan. + (But it reads no input if jpeg_consume_input() has already reached the + end of the file or a SOS marker beyond the target output scan.) +* jpeg_finish_decompress() will read until the end of file, and thus can + suspend if the end hasn't already been reached (as can be tested by + calling jpeg_input_complete()). +jpeg_start_output(), jpeg_finish_output(), and jpeg_finish_decompress() +all return TRUE if they completed their tasks, FALSE if they had to suspend. +In the event of a FALSE return, the application must load more input data +and repeat the call. Applications that use non-suspending data sources need +not check the return values of these three routines. + + +It is possible to change decoding parameters between output passes in the +buffered-image mode. The decoder library currently supports only very +limited changes of parameters. ONLY THE FOLLOWING parameter changes are +allowed after jpeg_start_decompress() is called: +* dct_method can be changed before each call to jpeg_start_output(). + For example, one could use a fast DCT method for early scans, changing + to a higher quality method for the final scan. +* dither_mode can be changed before each call to jpeg_start_output(); + of course this has no impact if not using color quantization. Typically + one would use ordered dither for initial passes, then switch to + Floyd-Steinberg dither for the final pass. Caution: changing dither mode + can cause more memory to be allocated by the library. Although the amount + of memory involved is not large (a scanline or so), it may cause the + initial max_memory_to_use specification to be exceeded, which in the worst + case would result in an out-of-memory failure. +* do_block_smoothing can be changed before each call to jpeg_start_output(). + This setting is relevant only when decoding a progressive JPEG image. + During the first DC-only scan, block smoothing provides a very "fuzzy" look + instead of the very "blocky" look seen without it; which is better seems a + matter of personal taste. But block smoothing is nearly always a win + during later stages, especially when decoding a successive-approximation + image: smoothing helps to hide the slight blockiness that otherwise shows + up on smooth gradients until the lowest coefficient bits are sent. +* Color quantization mode can be changed under the rules described below. + You *cannot* change between full-color and quantized output (because that + would alter the required I/O buffer sizes), but you can change which + quantization method is used. + +When generating color-quantized output, changing quantization method is a +very useful way of switching between high-speed and high-quality display. +The library allows you to change among its three quantization methods: +1. Single-pass quantization to a fixed color cube. + Selected by cinfo.two_pass_quantize = FALSE and cinfo.colormap = NULL. +2. Single-pass quantization to an application-supplied colormap. + Selected by setting cinfo.colormap to point to the colormap (the value of + two_pass_quantize is ignored); also set cinfo.actual_number_of_colors. +3. Two-pass quantization to a colormap chosen specifically for the image. + Selected by cinfo.two_pass_quantize = TRUE and cinfo.colormap = NULL. + (This is the default setting selected by jpeg_read_header, but it is + probably NOT what you want for the first pass of progressive display!) +These methods offer successively better quality and lesser speed. However, +only the first method is available for quantizing in non-RGB color spaces. + +IMPORTANT: because the different quantizer methods have very different +working-storage requirements, the library requires you to indicate which +one(s) you intend to use before you call jpeg_start_decompress(). (If we did +not require this, the max_memory_to_use setting would be a complete fiction.) +You do this by setting one or more of these three cinfo fields to TRUE: + enable_1pass_quant Fixed color cube colormap + enable_external_quant Externally-supplied colormap + enable_2pass_quant Two-pass custom colormap +All three are initialized FALSE by jpeg_read_header(). But +jpeg_start_decompress() automatically sets TRUE the one selected by the +current two_pass_quantize and colormap settings, so you only need to set the +enable flags for any other quantization methods you plan to change to later. + +After setting the enable flags correctly at jpeg_start_decompress() time, you +can change to any enabled quantization method by setting two_pass_quantize +and colormap properly just before calling jpeg_start_output(). The following +special rules apply: +1. You must explicitly set cinfo.colormap to NULL when switching to 1-pass + or 2-pass mode from a different mode, or when you want the 2-pass + quantizer to be re-run to generate a new colormap. +2. To switch to an external colormap, or to change to a different external + colormap than was used on the prior pass, you must call + jpeg_new_colormap() after setting cinfo.colormap. +NOTE: if you want to use the same colormap as was used in the prior pass, +you should not do either of these things. This will save some nontrivial +switchover costs. +(These requirements exist because cinfo.colormap will always be non-NULL +after completing a prior output pass, since both the 1-pass and 2-pass +quantizers set it to point to their output colormaps. Thus you have to +do one of these two things to notify the library that something has changed. +Yup, it's a bit klugy, but it's necessary to do it this way for backwards +compatibility.) + +Note that in buffered-image mode, the library generates any requested colormap +during jpeg_start_output(), not during jpeg_start_decompress(). + +When using two-pass quantization, jpeg_start_output() makes a pass over the +buffered image to determine the optimum color map; it therefore may take a +significant amount of time, whereas ordinarily it does little work. The +progress monitor hook is called during this pass, if defined. It is also +important to realize that if the specified target scan number is greater than +or equal to the current input scan number, jpeg_start_output() will attempt +to consume input as it makes this pass. If you use a suspending data source, +you need to check for a FALSE return from jpeg_start_output() under these +conditions. The combination of 2-pass quantization and a not-yet-fully-read +target scan is the only case in which jpeg_start_output() will consume input. + + +Application authors who support buffered-image mode may be tempted to use it +for all JPEG images, even single-scan ones. This will work, but it is +inefficient: there is no need to create an image-sized coefficient buffer for +single-scan images. Requesting buffered-image mode for such an image wastes +memory. Worse, it can cost time on large images, since the buffered data has +to be swapped out or written to a temporary file. If you are concerned about +maximum performance on baseline JPEG files, you should use buffered-image +mode only when the incoming file actually has multiple scans. This can be +tested by calling jpeg_has_multiple_scans(), which will return a correct +result at any time after jpeg_read_header() completes. + +It is also worth noting that when you use jpeg_consume_input() to let input +processing get ahead of output processing, the resulting pattern of access to +the coefficient buffer is quite nonsequential. It's best to use the memory +manager jmemnobs.c if you can (ie, if you have enough real or virtual main +memory). If not, at least make sure that max_memory_to_use is set as high as +possible. If the JPEG memory manager has to use a temporary file, you will +probably see a lot of disk traffic and poor performance. (This could be +improved with additional work on the memory manager, but we haven't gotten +around to it yet.) + +In some applications it may be convenient to use jpeg_consume_input() for all +input processing, including reading the initial markers; that is, you may +wish to call jpeg_consume_input() instead of jpeg_read_header() during +startup. This works, but note that you must check for JPEG_REACHED_SOS and +JPEG_REACHED_EOI return codes as the equivalent of jpeg_read_header's codes. +Once the first SOS marker has been reached, you must call +jpeg_start_decompress() before jpeg_consume_input() will consume more input; +it'll just keep returning JPEG_REACHED_SOS until you do. If you read a +tables-only file this way, jpeg_consume_input() will return JPEG_REACHED_EOI +without ever returning JPEG_REACHED_SOS; be sure to check for this case. +If this happens, the decompressor will not read any more input until you call +jpeg_abort() to reset it. It is OK to call jpeg_consume_input() even when not +using buffered-image mode, but in that case it's basically a no-op after the +initial markers have been read: it will just return JPEG_SUSPENDED. + + +Abbreviated datastreams and multiple images +------------------------------------------- + +A JPEG compression or decompression object can be reused to process multiple +images. This saves a small amount of time per image by eliminating the +"create" and "destroy" operations, but that isn't the real purpose of the +feature. Rather, reuse of an object provides support for abbreviated JPEG +datastreams. Object reuse can also simplify processing a series of images in +a single input or output file. This section explains these features. + +A JPEG file normally contains several hundred bytes worth of quantization +and Huffman tables. In a situation where many images will be stored or +transmitted with identical tables, this may represent an annoying overhead. +The JPEG standard therefore permits tables to be omitted. The standard +defines three classes of JPEG datastreams: + * "Interchange" datastreams contain an image and all tables needed to decode + the image. These are the usual kind of JPEG file. + * "Abbreviated image" datastreams contain an image, but are missing some or + all of the tables needed to decode that image. + * "Abbreviated table specification" (henceforth "tables-only") datastreams + contain only table specifications. +To decode an abbreviated image, it is necessary to load the missing table(s) +into the decoder beforehand. This can be accomplished by reading a separate +tables-only file. A variant scheme uses a series of images in which the first +image is an interchange (complete) datastream, while subsequent ones are +abbreviated and rely on the tables loaded by the first image. It is assumed +that once the decoder has read a table, it will remember that table until a +new definition for the same table number is encountered. + +It is the application designer's responsibility to figure out how to associate +the correct tables with an abbreviated image. While abbreviated datastreams +can be useful in a closed environment, their use is strongly discouraged in +any situation where data exchange with other applications might be needed. +Caveat designer. + +The JPEG library provides support for reading and writing any combination of +tables-only datastreams and abbreviated images. In both compression and +decompression objects, a quantization or Huffman table will be retained for +the lifetime of the object, unless it is overwritten by a new table definition. + + +To create abbreviated image datastreams, it is only necessary to tell the +compressor not to emit some or all of the tables it is using. Each +quantization and Huffman table struct contains a boolean field "sent_table", +which normally is initialized to FALSE. For each table used by the image, the +header-writing process emits the table and sets sent_table = TRUE unless it is +already TRUE. (In normal usage, this prevents outputting the same table +definition multiple times, as would otherwise occur because the chroma +components typically share tables.) Thus, setting this field to TRUE before +calling jpeg_start_compress() will prevent the table from being written at +all. + +If you want to create a "pure" abbreviated image file containing no tables, +just call "jpeg_suppress_tables(&cinfo, TRUE)" after constructing all the +tables. If you want to emit some but not all tables, you'll need to set the +individual sent_table fields directly. + +To create an abbreviated image, you must also call jpeg_start_compress() +with a second parameter of FALSE, not TRUE. Otherwise jpeg_start_compress() +will force all the sent_table fields to FALSE. (This is a safety feature to +prevent abbreviated images from being created accidentally.) + +To create a tables-only file, perform the same parameter setup that you +normally would, but instead of calling jpeg_start_compress() and so on, call +jpeg_write_tables(&cinfo). This will write an abbreviated datastream +containing only SOI, DQT and/or DHT markers, and EOI. All the quantization +and Huffman tables that are currently defined in the compression object will +be emitted unless their sent_tables flag is already TRUE, and then all the +sent_tables flags will be set TRUE. + +A sure-fire way to create matching tables-only and abbreviated image files +is to proceed as follows: + + create JPEG compression object + set JPEG parameters + set destination to tables-only file + jpeg_write_tables(&cinfo); + set destination to image file + jpeg_start_compress(&cinfo, FALSE); + write data... + jpeg_finish_compress(&cinfo); + +Since the JPEG parameters are not altered between writing the table file and +the abbreviated image file, the same tables are sure to be used. Of course, +you can repeat the jpeg_start_compress() ... jpeg_finish_compress() sequence +many times to produce many abbreviated image files matching the table file. + +You cannot suppress output of the computed Huffman tables when Huffman +optimization is selected. (If you could, there'd be no way to decode the +image...) Generally, you don't want to set optimize_coding = TRUE when +you are trying to produce abbreviated files. + +In some cases you might want to compress an image using tables which are +not stored in the application, but are defined in an interchange or +tables-only file readable by the application. This can be done by setting up +a JPEG decompression object to read the specification file, then copying the +tables into your compression object. See jpeg_copy_critical_parameters() +for an example of copying quantization tables. + + +To read abbreviated image files, you simply need to load the proper tables +into the decompression object before trying to read the abbreviated image. +If the proper tables are stored in the application program, you can just +allocate the table structs and fill in their contents directly. For example, +to load a fixed quantization table into table slot "n": + + if (cinfo.quant_tbl_ptrs[n] == NULL) + cinfo.quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) &cinfo); + quant_ptr = cinfo.quant_tbl_ptrs[n]; /* quant_ptr is JQUANT_TBL* */ + for (i = 0; i < 64; i++) { + /* Qtable[] is desired quantization table, in natural array order */ + quant_ptr->quantval[i] = Qtable[i]; + } + +Code to load a fixed Huffman table is typically (for AC table "n"): + + if (cinfo.ac_huff_tbl_ptrs[n] == NULL) + cinfo.ac_huff_tbl_ptrs[n] = jpeg_alloc_huff_table((j_common_ptr) &cinfo); + huff_ptr = cinfo.ac_huff_tbl_ptrs[n]; /* huff_ptr is JHUFF_TBL* */ + for (i = 1; i <= 16; i++) { + /* counts[i] is number of Huffman codes of length i bits, i=1..16 */ + huff_ptr->bits[i] = counts[i]; + } + for (i = 0; i < 256; i++) { + /* symbols[] is the list of Huffman symbols, in code-length order */ + huff_ptr->huffval[i] = symbols[i]; + } + +(Note that trying to set cinfo.quant_tbl_ptrs[n] to point directly at a +constant JQUANT_TBL object is not safe. If the incoming file happened to +contain a quantization table definition, your master table would get +overwritten! Instead allocate a working table copy and copy the master table +into it, as illustrated above. Ditto for Huffman tables, of course.) + +You might want to read the tables from a tables-only file, rather than +hard-wiring them into your application. The jpeg_read_header() call is +sufficient to read a tables-only file. You must pass a second parameter of +FALSE to indicate that you do not require an image to be present. Thus, the +typical scenario is + + create JPEG decompression object + set source to tables-only file + jpeg_read_header(&cinfo, FALSE); + set source to abbreviated image file + jpeg_read_header(&cinfo, TRUE); + set decompression parameters + jpeg_start_decompress(&cinfo); + read data... + jpeg_finish_decompress(&cinfo); + +In some cases, you may want to read a file without knowing whether it contains +an image or just tables. In that case, pass FALSE and check the return value +from jpeg_read_header(): it will be JPEG_HEADER_OK if an image was found, +JPEG_HEADER_TABLES_ONLY if only tables were found. (A third return value, +JPEG_SUSPENDED, is possible when using a suspending data source manager.) +Note that jpeg_read_header() will not complain if you read an abbreviated +image for which you haven't loaded the missing tables; the missing-table check +occurs later, in jpeg_start_decompress(). + + +It is possible to read a series of images from a single source file by +repeating the jpeg_read_header() ... jpeg_finish_decompress() sequence, +without releasing/recreating the JPEG object or the data source module. +(If you did reinitialize, any partial bufferload left in the data source +buffer at the end of one image would be discarded, causing you to lose the +start of the next image.) When you use this method, stored tables are +automatically carried forward, so some of the images can be abbreviated images +that depend on tables from earlier images. + +If you intend to write a series of images into a single destination file, +you might want to make a specialized data destination module that doesn't +flush the output buffer at term_destination() time. This would speed things +up by some trifling amount. Of course, you'd need to remember to flush the +buffer after the last image. You can make the later images be abbreviated +ones by passing FALSE to jpeg_start_compress(). + + +Special markers +--------------- + +Some applications may need to insert or extract special data in the JPEG +datastream. The JPEG standard provides marker types "COM" (comment) and +"APP0" through "APP15" (application) to hold application-specific data. +Unfortunately, the use of these markers is not specified by the standard. +COM markers are fairly widely used to hold user-supplied text. The JFIF file +format spec uses APP0 markers with specified initial strings to hold certain +data. Adobe applications use APP14 markers beginning with the string "Adobe" +for miscellaneous data. Other APPn markers are rarely seen, but might +contain almost anything. + +If you wish to store user-supplied text, we recommend you use COM markers +and place readable 7-bit ASCII text in them. Newline conventions are not +standardized --- expect to find LF (Unix style), CR/LF (DOS style), or CR +(Mac style). A robust COM reader should be able to cope with random binary +garbage, including nulls, since some applications generate COM markers +containing non-ASCII junk. (But yours should not be one of them.) + +For program-supplied data, use an APPn marker, and be sure to begin it with an +identifying string so that you can tell whether the marker is actually yours. +It's probably best to avoid using APP0 or APP14 for any private markers. +(NOTE: the upcoming SPIFF standard will use APP8 markers; we recommend you +not use APP8 markers for any private purposes, either.) + +Keep in mind that at most 65533 bytes can be put into one marker, but you +can have as many markers as you like. + +By default, the IJG compression library will write a JFIF APP0 marker if the +selected JPEG colorspace is grayscale or YCbCr, or an Adobe APP14 marker if +the selected colorspace is RGB, CMYK, or YCCK. You can disable this, but +we don't recommend it. The decompression library will recognize JFIF and +Adobe markers and will set the JPEG colorspace properly when one is found. + + +You can write special markers immediately following the datastream header by +calling jpeg_write_marker() after jpeg_start_compress() and before the first +call to jpeg_write_scanlines(). When you do this, the markers appear after +the SOI and the JFIF APP0 and Adobe APP14 markers (if written), but before +all else. Specify the marker type parameter as "JPEG_COM" for COM or +"JPEG_APP0 + n" for APPn. (Actually, jpeg_write_marker will let you write +any marker type, but we don't recommend writing any other kinds of marker.) +For example, to write a user comment string pointed to by comment_text: + jpeg_write_marker(cinfo, JPEG_COM, comment_text, strlen(comment_text)); + +If it's not convenient to store all the marker data in memory at once, +you can instead call jpeg_write_m_header() followed by multiple calls to +jpeg_write_m_byte(). If you do it this way, it's your responsibility to +call jpeg_write_m_byte() exactly the number of times given in the length +parameter to jpeg_write_m_header(). (This method lets you empty the +output buffer partway through a marker, which might be important when +using a suspending data destination module. In any case, if you are using +a suspending destination, you should flush its buffer after inserting +any special markers. See "I/O suspension".) + +Or, if you prefer to synthesize the marker byte sequence yourself, +you can just cram it straight into the data destination module. + +If you are writing JFIF 1.02 extension markers (thumbnail images), don't +forget to set cinfo.JFIF_minor_version = 2 so that the encoder will write the +correct JFIF version number in the JFIF header marker. The library's default +is to write version 1.01, but that's wrong if you insert any 1.02 extension +markers. (We could probably get away with just defaulting to 1.02, but there +used to be broken decoders that would complain about unknown minor version +numbers. To reduce compatibility risks it's safest not to write 1.02 unless +you are actually using 1.02 extensions.) + + +When reading, two methods of handling special markers are available: +1. You can ask the library to save the contents of COM and/or APPn markers +into memory, and then examine them at your leisure afterwards. +2. You can supply your own routine to process COM and/or APPn markers +on-the-fly as they are read. +The first method is simpler to use, especially if you are using a suspending +data source; writing a marker processor that copes with input suspension is +not easy (consider what happens if the marker is longer than your available +input buffer). However, the second method conserves memory since the marker +data need not be kept around after it's been processed. + +For either method, you'd normally set up marker handling after creating a +decompression object and before calling jpeg_read_header(), because the +markers of interest will typically be near the head of the file and so will +be scanned by jpeg_read_header. Once you've established a marker handling +method, it will be used for the life of that decompression object +(potentially many datastreams), unless you change it. Marker handling is +determined separately for COM markers and for each APPn marker code. + + +To save the contents of special markers in memory, call + jpeg_save_markers(cinfo, marker_code, length_limit) +where marker_code is the marker type to save, JPEG_COM or JPEG_APP0+n. +(To arrange to save all the special marker types, you need to call this +routine 17 times, for COM and APP0-APP15.) If the incoming marker is longer +than length_limit data bytes, only length_limit bytes will be saved; this +parameter allows you to avoid chewing up memory when you only need to see the +first few bytes of a potentially large marker. If you want to save all the +data, set length_limit to 0xFFFF; that is enough since marker lengths are only +16 bits. As a special case, setting length_limit to 0 prevents that marker +type from being saved at all. (That is the default behavior, in fact.) + +After jpeg_read_header() completes, you can examine the special markers by +following the cinfo->marker_list pointer chain. All the special markers in +the file appear in this list, in order of their occurrence in the file (but +omitting any markers of types you didn't ask for). Both the original data +length and the saved data length are recorded for each list entry; the latter +will not exceed length_limit for the particular marker type. Note that these +lengths exclude the marker length word, whereas the stored representation +within the JPEG file includes it. (Hence the maximum data length is really +only 65533.) + +It is possible that additional special markers appear in the file beyond the +SOS marker at which jpeg_read_header stops; if so, the marker list will be +extended during reading of the rest of the file. This is not expected to be +common, however. If you are short on memory you may want to reset the length +limit to zero for all marker types after finishing jpeg_read_header, to +ensure that the max_memory_to_use setting cannot be exceeded due to addition +of later markers. + +The marker list remains stored until you call jpeg_finish_decompress or +jpeg_abort, at which point the memory is freed and the list is set to empty. +(jpeg_destroy also releases the storage, of course.) + +Note that the library is internally interested in APP0 and APP14 markers; +if you try to set a small nonzero length limit on these types, the library +will silently force the length up to the minimum it wants. (But you can set +a zero length limit to prevent them from being saved at all.) Also, in a +16-bit environment, the maximum length limit may be constrained to less than +65533 by malloc() limitations. It is therefore best not to assume that the +effective length limit is exactly what you set it to be. + + +If you want to supply your own marker-reading routine, you do it by calling +jpeg_set_marker_processor(). A marker processor routine must have the +signature + boolean jpeg_marker_parser_method (j_decompress_ptr cinfo) +Although the marker code is not explicitly passed, the routine can find it +in cinfo->unread_marker. At the time of call, the marker proper has been +read from the data source module. The processor routine is responsible for +reading the marker length word and the remaining parameter bytes, if any. +Return TRUE to indicate success. (FALSE should be returned only if you are +using a suspending data source and it tells you to suspend. See the standard +marker processors in jdmarker.c for appropriate coding methods if you need to +use a suspending data source.) + +If you override the default APP0 or APP14 processors, it is up to you to +recognize JFIF and Adobe markers if you want colorspace recognition to occur +properly. We recommend copying and extending the default processors if you +want to do that. (A better idea is to save these marker types for later +examination by calling jpeg_save_markers(); that method doesn't interfere +with the library's own processing of these markers.) + +jpeg_set_marker_processor() and jpeg_save_markers() are mutually exclusive +--- if you call one it overrides any previous call to the other, for the +particular marker type specified. + +A simple example of an external COM processor can be found in djpeg.c. +Also, see jpegtran.c for an example of using jpeg_save_markers. + + +Raw (downsampled) image data +---------------------------- + +Some applications need to supply already-downsampled image data to the JPEG +compressor, or to receive raw downsampled data from the decompressor. The +library supports this requirement by allowing the application to write or +read raw data, bypassing the normal preprocessing or postprocessing steps. +The interface is different from the standard one and is somewhat harder to +use. If your interest is merely in bypassing color conversion, we recommend +that you use the standard interface and simply set jpeg_color_space = +in_color_space (or jpeg_color_space = out_color_space for decompression). +The mechanism described in this section is necessary only to supply or +receive downsampled image data, in which not all components have the same +dimensions. + + +To compress raw data, you must supply the data in the colorspace to be used +in the JPEG file (please read the earlier section on Special color spaces) +and downsampled to the sampling factors specified in the JPEG parameters. +You must supply the data in the format used internally by the JPEG library, +namely a JSAMPIMAGE array. This is an array of pointers to two-dimensional +arrays, each of type JSAMPARRAY. Each 2-D array holds the values for one +color component. This structure is necessary since the components are of +different sizes. If the image dimensions are not a multiple of the MCU size, +you must also pad the data correctly (usually, this is done by replicating +the last column and/or row). The data must be padded to a multiple of a DCT +block in each component: that is, each downsampled row must contain a +multiple of 8 valid samples, and there must be a multiple of 8 sample rows +for each component. (For applications such as conversion of digital TV +images, the standard image size is usually a multiple of the DCT block size, +so that no padding need actually be done.) + +The procedure for compression of raw data is basically the same as normal +compression, except that you call jpeg_write_raw_data() in place of +jpeg_write_scanlines(). Before calling jpeg_start_compress(), you must do +the following: + * Set cinfo->raw_data_in to TRUE. (It is set FALSE by jpeg_set_defaults().) + This notifies the library that you will be supplying raw data. + * Ensure jpeg_color_space is correct --- an explicit jpeg_set_colorspace() + call is a good idea. Note that since color conversion is bypassed, + in_color_space is ignored, except that jpeg_set_defaults() uses it to + choose the default jpeg_color_space setting. + * Ensure the sampling factors, cinfo->comp_info[i].h_samp_factor and + cinfo->comp_info[i].v_samp_factor, are correct. Since these indicate the + dimensions of the data you are supplying, it's wise to set them + explicitly, rather than assuming the library's defaults are what you want. + +To pass raw data to the library, call jpeg_write_raw_data() in place of +jpeg_write_scanlines(). The two routines work similarly except that +jpeg_write_raw_data takes a JSAMPIMAGE data array rather than JSAMPARRAY. +The scanlines count passed to and returned from jpeg_write_raw_data is +measured in terms of the component with the largest v_samp_factor. + +jpeg_write_raw_data() processes one MCU row per call, which is to say +v_samp_factor*DCTSIZE sample rows of each component. The passed num_lines +value must be at least max_v_samp_factor*DCTSIZE, and the return value will +be exactly that amount (or possibly some multiple of that amount, in future +library versions). This is true even on the last call at the bottom of the +image; don't forget to pad your data as necessary. + +The required dimensions of the supplied data can be computed for each +component as + cinfo->comp_info[i].width_in_blocks*DCTSIZE samples per row + cinfo->comp_info[i].height_in_blocks*DCTSIZE rows in image +after jpeg_start_compress() has initialized those fields. If the valid data +is smaller than this, it must be padded appropriately. For some sampling +factors and image sizes, additional dummy DCT blocks are inserted to make +the image a multiple of the MCU dimensions. The library creates such dummy +blocks itself; it does not read them from your supplied data. Therefore you +need never pad by more than DCTSIZE samples. An example may help here. +Assume 2h2v downsampling of YCbCr data, that is + cinfo->comp_info[0].h_samp_factor = 2 for Y + cinfo->comp_info[0].v_samp_factor = 2 + cinfo->comp_info[1].h_samp_factor = 1 for Cb + cinfo->comp_info[1].v_samp_factor = 1 + cinfo->comp_info[2].h_samp_factor = 1 for Cr + cinfo->comp_info[2].v_samp_factor = 1 +and suppose that the nominal image dimensions (cinfo->image_width and +cinfo->image_height) are 101x101 pixels. Then jpeg_start_compress() will +compute downsampled_width = 101 and width_in_blocks = 13 for Y, +downsampled_width = 51 and width_in_blocks = 7 for Cb and Cr (and the same +for the height fields). You must pad the Y data to at least 13*8 = 104 +columns and rows, the Cb/Cr data to at least 7*8 = 56 columns and rows. The +MCU height is max_v_samp_factor = 2 DCT rows so you must pass at least 16 +scanlines on each call to jpeg_write_raw_data(), which is to say 16 actual +sample rows of Y and 8 each of Cb and Cr. A total of 7 MCU rows are needed, +so you must pass a total of 7*16 = 112 "scanlines". The last DCT block row +of Y data is dummy, so it doesn't matter what you pass for it in the data +arrays, but the scanlines count must total up to 112 so that all of the Cb +and Cr data gets passed. + +Output suspension is supported with raw-data compression: if the data +destination module suspends, jpeg_write_raw_data() will return 0. +In this case the same data rows must be passed again on the next call. + + +Decompression with raw data output implies bypassing all postprocessing: +you cannot ask for rescaling or color quantization, for instance. More +seriously, you must deal with the color space and sampling factors present in +the incoming file. If your application only handles, say, 2h1v YCbCr data, +you must check for and fail on other color spaces or other sampling factors. +The library will not convert to a different color space for you. + +To obtain raw data output, set cinfo->raw_data_out = TRUE before +jpeg_start_decompress() (it is set FALSE by jpeg_read_header()). Be sure to +verify that the color space and sampling factors are ones you can handle. +Then call jpeg_read_raw_data() in place of jpeg_read_scanlines(). The +decompression process is otherwise the same as usual. + +jpeg_read_raw_data() returns one MCU row per call, and thus you must pass a +buffer of at least max_v_samp_factor*DCTSIZE scanlines (scanline counting is +the same as for raw-data compression). The buffer you pass must be large +enough to hold the actual data plus padding to DCT-block boundaries. As with +compression, any entirely dummy DCT blocks are not processed so you need not +allocate space for them, but the total scanline count includes them. The +above example of computing buffer dimensions for raw-data compression is +equally valid for decompression. + +Input suspension is supported with raw-data decompression: if the data source +module suspends, jpeg_read_raw_data() will return 0. You can also use +buffered-image mode to read raw data in multiple passes. + + +Really raw data: DCT coefficients +--------------------------------- + +It is possible to read or write the contents of a JPEG file as raw DCT +coefficients. This facility is mainly intended for use in lossless +transcoding between different JPEG file formats. Other possible applications +include lossless cropping of a JPEG image, lossless reassembly of a +multi-strip or multi-tile TIFF/JPEG file into a single JPEG datastream, etc. + +To read the contents of a JPEG file as DCT coefficients, open the file and do +jpeg_read_header() as usual. But instead of calling jpeg_start_decompress() +and jpeg_read_scanlines(), call jpeg_read_coefficients(). This will read the +entire image into a set of virtual coefficient-block arrays, one array per +component. The return value is a pointer to an array of virtual-array +descriptors. Each virtual array can be accessed directly using the JPEG +memory manager's access_virt_barray method (see Memory management, below, +and also read structure.doc's discussion of virtual array handling). Or, +for simple transcoding to a different JPEG file format, the array list can +just be handed directly to jpeg_write_coefficients(). + +Each block in the block arrays contains quantized coefficient values in +normal array order (not JPEG zigzag order). The block arrays contain only +DCT blocks containing real data; any entirely-dummy blocks added to fill out +interleaved MCUs at the right or bottom edges of the image are discarded +during reading and are not stored in the block arrays. (The size of each +block array can be determined from the width_in_blocks and height_in_blocks +fields of the component's comp_info entry.) This is also the data format +expected by jpeg_write_coefficients(). + +When you are done using the virtual arrays, call jpeg_finish_decompress() +to release the array storage and return the decompression object to an idle +state; or just call jpeg_destroy() if you don't need to reuse the object. + +If you use a suspending data source, jpeg_read_coefficients() will return +NULL if it is forced to suspend; a non-NULL return value indicates successful +completion. You need not test for a NULL return value when using a +non-suspending data source. + +It is also possible to call jpeg_read_coefficients() to obtain access to the +decoder's coefficient arrays during a normal decode cycle in buffered-image +mode. This frammish might be useful for progressively displaying an incoming +image and then re-encoding it without loss. To do this, decode in buffered- +image mode as discussed previously, then call jpeg_read_coefficients() after +the last jpeg_finish_output() call. The arrays will be available for your use +until you call jpeg_finish_decompress(). + + +To write the contents of a JPEG file as DCT coefficients, you must provide +the DCT coefficients stored in virtual block arrays. You can either pass +block arrays read from an input JPEG file by jpeg_read_coefficients(), or +allocate virtual arrays from the JPEG compression object and fill them +yourself. In either case, jpeg_write_coefficients() is substituted for +jpeg_start_compress() and jpeg_write_scanlines(). Thus the sequence is + * Create compression object + * Set all compression parameters as necessary + * Request virtual arrays if needed + * jpeg_write_coefficients() + * jpeg_finish_compress() + * Destroy or re-use compression object +jpeg_write_coefficients() is passed a pointer to an array of virtual block +array descriptors; the number of arrays is equal to cinfo.num_components. + +The virtual arrays need only have been requested, not realized, before +jpeg_write_coefficients() is called. A side-effect of +jpeg_write_coefficients() is to realize any virtual arrays that have been +requested from the compression object's memory manager. Thus, when obtaining +the virtual arrays from the compression object, you should fill the arrays +after calling jpeg_write_coefficients(). The data is actually written out +when you call jpeg_finish_compress(); jpeg_write_coefficients() only writes +the file header. + +When writing raw DCT coefficients, it is crucial that the JPEG quantization +tables and sampling factors match the way the data was encoded, or the +resulting file will be invalid. For transcoding from an existing JPEG file, +we recommend using jpeg_copy_critical_parameters(). This routine initializes +all the compression parameters to default values (like jpeg_set_defaults()), +then copies the critical information from a source decompression object. +The decompression object should have just been used to read the entire +JPEG input file --- that is, it should be awaiting jpeg_finish_decompress(). + +jpeg_write_coefficients() marks all tables stored in the compression object +as needing to be written to the output file (thus, it acts like +jpeg_start_compress(cinfo, TRUE)). This is for safety's sake, to avoid +emitting abbreviated JPEG files by accident. If you really want to emit an +abbreviated JPEG file, call jpeg_suppress_tables(), or set the tables' +individual sent_table flags, between calling jpeg_write_coefficients() and +jpeg_finish_compress(). + + +Progress monitoring +------------------- + +Some applications may need to regain control from the JPEG library every so +often. The typical use of this feature is to produce a percent-done bar or +other progress display. (For a simple example, see cjpeg.c or djpeg.c.) +Although you do get control back frequently during the data-transferring pass +(the jpeg_read_scanlines or jpeg_write_scanlines loop), any additional passes +will occur inside jpeg_finish_compress or jpeg_start_decompress; those +routines may take a long time to execute, and you don't get control back +until they are done. + +You can define a progress-monitor routine which will be called periodically +by the library. No guarantees are made about how often this call will occur, +so we don't recommend you use it for mouse tracking or anything like that. +At present, a call will occur once per MCU row, scanline, or sample row +group, whichever unit is convenient for the current processing mode; so the +wider the image, the longer the time between calls. During the data +transferring pass, only one call occurs per call of jpeg_read_scanlines or +jpeg_write_scanlines, so don't pass a large number of scanlines at once if +you want fine resolution in the progress count. (If you really need to use +the callback mechanism for time-critical tasks like mouse tracking, you could +insert additional calls inside some of the library's inner loops.) + +To establish a progress-monitor callback, create a struct jpeg_progress_mgr, +fill in its progress_monitor field with a pointer to your callback routine, +and set cinfo->progress to point to the struct. The callback will be called +whenever cinfo->progress is non-NULL. (This pointer is set to NULL by +jpeg_create_compress or jpeg_create_decompress; the library will not change +it thereafter. So if you allocate dynamic storage for the progress struct, +make sure it will live as long as the JPEG object does. Allocating from the +JPEG memory manager with lifetime JPOOL_PERMANENT will work nicely.) You +can use the same callback routine for both compression and decompression. + +The jpeg_progress_mgr struct contains four fields which are set by the library: + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +During any one pass, pass_counter increases from 0 up to (not including) +pass_limit; the step size is usually but not necessarily 1. The pass_limit +value may change from one pass to another. The expected total number of +passes is in total_passes, and the number of passes already completed is in +completed_passes. Thus the fraction of work completed may be estimated as + completed_passes + (pass_counter/pass_limit) + -------------------------------------------- + total_passes +ignoring the fact that the passes may not be equal amounts of work. + +When decompressing, pass_limit can even change within a pass, because it +depends on the number of scans in the JPEG file, which isn't always known in +advance. The computed fraction-of-work-done may jump suddenly (if the library +discovers it has overestimated the number of scans) or even decrease (in the +opposite case). It is not wise to put great faith in the work estimate. + +When using the decompressor's buffered-image mode, the progress monitor work +estimate is likely to be completely unhelpful, because the library has no way +to know how many output passes will be demanded of it. Currently, the library +sets total_passes based on the assumption that there will be one more output +pass if the input file end hasn't yet been read (jpeg_input_complete() isn't +TRUE), but no more output passes if the file end has been reached when the +output pass is started. This means that total_passes will rise as additional +output passes are requested. If you have a way of determining the input file +size, estimating progress based on the fraction of the file that's been read +will probably be more useful than using the library's value. + + +Memory management +----------------- + +This section covers some key facts about the JPEG library's built-in memory +manager. For more info, please read structure.doc's section about the memory +manager, and consult the source code if necessary. + +All memory and temporary file allocation within the library is done via the +memory manager. If necessary, you can replace the "back end" of the memory +manager to control allocation yourself (for example, if you don't want the +library to use malloc() and free() for some reason). + +Some data is allocated "permanently" and will not be freed until the JPEG +object is destroyed. Most data is allocated "per image" and is freed by +jpeg_finish_compress, jpeg_finish_decompress, or jpeg_abort. You can call the +memory manager yourself to allocate structures that will automatically be +freed at these times. Typical code for this is + ptr = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, size); +Use JPOOL_PERMANENT to get storage that lasts as long as the JPEG object. +Use alloc_large instead of alloc_small for anything bigger than a few Kbytes. +There are also alloc_sarray and alloc_barray routines that automatically +build 2-D sample or block arrays. + +The library's minimum space requirements to process an image depend on the +image's width, but not on its height, because the library ordinarily works +with "strip" buffers that are as wide as the image but just a few rows high. +Some operating modes (eg, two-pass color quantization) require full-image +buffers. Such buffers are treated as "virtual arrays": only the current strip +need be in memory, and the rest can be swapped out to a temporary file. + +If you use the simplest memory manager back end (jmemnobs.c), then no +temporary files are used; virtual arrays are simply malloc()'d. Images bigger +than memory can be processed only if your system supports virtual memory. +The other memory manager back ends support temporary files of various flavors +and thus work in machines without virtual memory. They may also be useful on +Unix machines if you need to process images that exceed available swap space. + +When using temporary files, the library will make the in-memory buffers for +its virtual arrays just big enough to stay within a "maximum memory" setting. +Your application can set this limit by setting cinfo->mem->max_memory_to_use +after creating the JPEG object. (Of course, there is still a minimum size for +the buffers, so the max-memory setting is effective only if it is bigger than +the minimum space needed.) If you allocate any large structures yourself, you +must allocate them before jpeg_start_compress() or jpeg_start_decompress() in +order to have them counted against the max memory limit. Also keep in mind +that space allocated with alloc_small() is ignored, on the assumption that +it's too small to be worth worrying about; so a reasonable safety margin +should be left when setting max_memory_to_use. + +If you use the jmemname.c or jmemdos.c memory manager back end, it is +important to clean up the JPEG object properly to ensure that the temporary +files get deleted. (This is especially crucial with jmemdos.c, where the +"temporary files" may be extended-memory segments; if they are not freed, +DOS will require a reboot to recover the memory.) Thus, with these memory +managers, it's a good idea to provide a signal handler that will trap any +early exit from your program. The handler should call either jpeg_abort() +or jpeg_destroy() for any active JPEG objects. A handler is not needed with +jmemnobs.c, and shouldn't be necessary with jmemansi.c or jmemmac.c either, +since the C library is supposed to take care of deleting files made with +tmpfile(). + + +Memory usage +------------ + +Working memory requirements while performing compression or decompression +depend on image dimensions, image characteristics (such as colorspace and +JPEG process), and operating mode (application-selected options). + +As of v6b, the decompressor requires: + 1. About 24K in more-or-less-fixed-size data. This varies a bit depending + on operating mode and image characteristics (particularly color vs. + grayscale), but it doesn't depend on image dimensions. + 2. Strip buffers (of size proportional to the image width) for IDCT and + upsampling results. The worst case for commonly used sampling factors + is about 34 bytes * width in pixels for a color image. A grayscale image + only needs about 8 bytes per pixel column. + 3. A full-image DCT coefficient buffer is needed to decode a multi-scan JPEG + file (including progressive JPEGs), or whenever you select buffered-image + mode. This takes 2 bytes/coefficient. At typical 2x2 sampling, that's + 3 bytes per pixel for a color image. Worst case (1x1 sampling) requires + 6 bytes/pixel. For grayscale, figure 2 bytes/pixel. + 4. To perform 2-pass color quantization, the decompressor also needs a + 128K color lookup table and a full-image pixel buffer (3 bytes/pixel). +This does not count any memory allocated by the application, such as a +buffer to hold the final output image. + +The above figures are valid for 8-bit JPEG data precision and a machine with +32-bit ints. For 12-bit JPEG data, double the size of the strip buffers and +quantization pixel buffer. The "fixed-size" data will be somewhat smaller +with 16-bit ints, larger with 64-bit ints. Also, CMYK or other unusual +color spaces will require different amounts of space. + +The full-image coefficient and pixel buffers, if needed at all, do not +have to be fully RAM resident; you can have the library use temporary +files instead when the total memory usage would exceed a limit you set. +(But if your OS supports virtual memory, it's probably better to just use +jmemnobs and let the OS do the swapping.) + +The compressor's memory requirements are similar, except that it has no need +for color quantization. Also, it needs a full-image DCT coefficient buffer +if Huffman-table optimization is asked for, even if progressive mode is not +requested. + +If you need more detailed information about memory usage in a particular +situation, you can enable the MEM_STATS code in jmemmgr.c. + + +Library compile-time options +---------------------------- + +A number of compile-time options are available by modifying jmorecfg.h. + +The JPEG standard provides for both the baseline 8-bit DCT process and +a 12-bit DCT process. The IJG code supports 12-bit lossy JPEG if you define +BITS_IN_JSAMPLE as 12 rather than 8. Note that this causes JSAMPLE to be +larger than a char, so it affects the surrounding application's image data. +The sample applications cjpeg and djpeg can support 12-bit mode only for PPM +and GIF file formats; you must disable the other file formats to compile a +12-bit cjpeg or djpeg. (install.doc has more information about that.) +At present, a 12-bit library can handle *only* 12-bit images, not both +precisions. (If you need to include both 8- and 12-bit libraries in a single +application, you could probably do it by defining NEED_SHORT_EXTERNAL_NAMES +for just one of the copies. You'd have to access the 8-bit and 12-bit copies +from separate application source files. This is untested ... if you try it, +we'd like to hear whether it works!) + +Note that a 12-bit library always compresses in Huffman optimization mode, +in order to generate valid Huffman tables. This is necessary because our +default Huffman tables only cover 8-bit data. If you need to output 12-bit +files in one pass, you'll have to supply suitable default Huffman tables. +You may also want to supply your own DCT quantization tables; the existing +quality-scaling code has been developed for 8-bit use, and probably doesn't +generate especially good tables for 12-bit. + +The maximum number of components (color channels) in the image is determined +by MAX_COMPONENTS. The JPEG standard allows up to 255 components, but we +expect that few applications will need more than four or so. + +On machines with unusual data type sizes, you may be able to improve +performance or reduce memory space by tweaking the various typedefs in +jmorecfg.h. In particular, on some RISC CPUs, access to arrays of "short"s +is quite slow; consider trading memory for speed by making JCOEF, INT16, and +UINT16 be "int" or "unsigned int". UINT8 is also a candidate to become int. +You probably don't want to make JSAMPLE be int unless you have lots of memory +to burn. + +You can reduce the size of the library by compiling out various optional +functions. To do this, undefine xxx_SUPPORTED symbols as necessary. + +You can also save a few K by not having text error messages in the library; +the standard error message table occupies about 5Kb. This is particularly +reasonable for embedded applications where there's no good way to display +a message anyway. To do this, remove the creation of the message table +(jpeg_std_message_table[]) from jerror.c, and alter format_message to do +something reasonable without it. You could output the numeric value of the +message code number, for example. If you do this, you can also save a couple +more K by modifying the TRACEMSn() macros in jerror.h to expand to nothing; +you don't need trace capability anyway, right? + + +Portability considerations +-------------------------- + +The JPEG library has been written to be extremely portable; the sample +applications cjpeg and djpeg are slightly less so. This section summarizes +the design goals in this area. (If you encounter any bugs that cause the +library to be less portable than is claimed here, we'd appreciate hearing +about them.) + +The code works fine on ANSI C, C++, and pre-ANSI C compilers, using any of +the popular system include file setups, and some not-so-popular ones too. +See install.doc for configuration procedures. + +The code is not dependent on the exact sizes of the C data types. As +distributed, we make the assumptions that + char is at least 8 bits wide + short is at least 16 bits wide + int is at least 16 bits wide + long is at least 32 bits wide +(These are the minimum requirements of the ANSI C standard.) Wider types will +work fine, although memory may be used inefficiently if char is much larger +than 8 bits or short is much bigger than 16 bits. The code should work +equally well with 16- or 32-bit ints. + +In a system where these assumptions are not met, you may be able to make the +code work by modifying the typedefs in jmorecfg.h. However, you will probably +have difficulty if int is less than 16 bits wide, since references to plain +int abound in the code. + +char can be either signed or unsigned, although the code runs faster if an +unsigned char type is available. If char is wider than 8 bits, you will need +to redefine JOCTET and/or provide custom data source/destination managers so +that JOCTET represents exactly 8 bits of data on external storage. + +The JPEG library proper does not assume ASCII representation of characters. +But some of the image file I/O modules in cjpeg/djpeg do have ASCII +dependencies in file-header manipulation; so does cjpeg's select_file_type() +routine. + +The JPEG library does not rely heavily on the C library. In particular, C +stdio is used only by the data source/destination modules and the error +handler, all of which are application-replaceable. (cjpeg/djpeg are more +heavily dependent on stdio.) malloc and free are called only from the memory +manager "back end" module, so you can use a different memory allocator by +replacing that one file. + +The code generally assumes that C names must be unique in the first 15 +characters. However, global function names can be made unique in the +first 6 characters by defining NEED_SHORT_EXTERNAL_NAMES. + +More info about porting the code may be gleaned by reading jconfig.doc, +jmorecfg.h, and jinclude.h. + + +Notes for MS-DOS implementors +----------------------------- + +The IJG code is designed to work efficiently in 80x86 "small" or "medium" +memory models (i.e., data pointers are 16 bits unless explicitly declared +"far"; code pointers can be either size). You may be able to use small +model to compile cjpeg or djpeg by itself, but you will probably have to use +medium model for any larger application. This won't make much difference in +performance. You *will* take a noticeable performance hit if you use a +large-data memory model (perhaps 10%-25%), and you should avoid "huge" model +if at all possible. + +The JPEG library typically needs 2Kb-3Kb of stack space. It will also +malloc about 20K-30K of near heap space while executing (and lots of far +heap, but that doesn't count in this calculation). This figure will vary +depending on selected operating mode, and to a lesser extent on image size. +There is also about 5Kb-6Kb of constant data which will be allocated in the +near data segment (about 4Kb of this is the error message table). +Thus you have perhaps 20K available for other modules' static data and near +heap space before you need to go to a larger memory model. The C library's +static data will account for several K of this, but that still leaves a good +deal for your needs. (If you are tight on space, you could reduce the sizes +of the I/O buffers allocated by jdatasrc.c and jdatadst.c, say from 4K to +1K. Another possibility is to move the error message table to far memory; +this should be doable with only localized hacking on jerror.c.) + +About 2K of the near heap space is "permanent" memory that will not be +released until you destroy the JPEG object. This is only an issue if you +save a JPEG object between compression or decompression operations. + +Far data space may also be a tight resource when you are dealing with large +images. The most memory-intensive case is decompression with two-pass color +quantization, or single-pass quantization to an externally supplied color +map. This requires a 128Kb color lookup table plus strip buffers amounting +to about 40 bytes per column for typical sampling ratios (eg, about 25600 +bytes for a 640-pixel-wide image). You may not be able to process wide +images if you have large data structures of your own. + +Of course, all of these concerns vanish if you use a 32-bit flat-memory-model +compiler, such as DJGPP or Watcom C. We highly recommend flat model if you +can use it; the JPEG library is significantly faster in flat model. diff --git a/src/dep/src/irrlicht/jpeglib/ltconfig b/src/dep/src/irrlicht/jpeglib/ltconfig new file mode 100644 index 0000000..679dd73 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/ltconfig @@ -0,0 +1,1512 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1998 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +echo=echo +if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then : +else + # The Solaris and AIX default echo program unquotes backslashes. + # This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # So, we emulate echo with printf '%s\n' + echo="printf %s\\n" + if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then : + else + # Oops. We have no working printf. Try to find a not-so-buggy echo. + echo=echo + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + for dir in $PATH /usr/ucb; do + if test -f $dir/echo && test "X`$dir/echo '\t'`" = 'X\t'; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.2 +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking. +enable_static=yes +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +nonopt= +verify_host=yes +with_gcc=no +with_gnu_ld=no + +old_AR="$AR" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LD="$LD" +old_LN_S="$LN_S" +old_NM="$NM" +old_RANLIB="$RANLIB" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test -f "$ltmain"; then : +else + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to ltmain.sh. + srcdir=`$echo "$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + "") + if host_alias=`$ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case "$host_os" in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +case "$host_os" in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR cru $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +# Set a sane default for `AR'. +test -z "$AR" && AR=ar + +# If RANLIB is not set, then run the test. +if test "${RANLIB+set}" != "set"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + + echo "$ac_t$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib;$old_postinstall_cmds" +fi + +# Check to see if we are using GCC. +if test "$with_gcc" != yes || test -z "$CC"; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + for dir in $PATH; do + IFS="$save_ifs" + test -z "$dir" && dir=. + if test -f $dir/gcc; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + echo "$progname:424: checking whether we are using GNU C" >&5 + + $rm conftest.c + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + fi + $rm conftest.c + echo "$ac_t$with_gcc" 1>&6 +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +pic_flag= +special_shlib_compile_flags= +wl= +link_static_flag= +no_builtin_flag= + +if test "$with_gcc" = yes; then + wl='-Wl,' + link_static_flag='-static' + no_builtin_flag=' -fno-builtin' + + case "$host_os" in + aix3* | aix4* | irix5* | irix6* | osf3* | osf4*) + # PIC is the default for these OSes. + ;; + os2*) + # We can build DLLs from non-PIC. + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + pic_flag='-m68020 -resident32 -malways-restore-a4' + ;; + *) + pic_flag='-fPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host_os" in + aix3* | aix4*) + # All AIX code is PIC. + link_static_flag='-bnso -bI:/lib/syscalls.exp' + ;; + + hpux9* | hpux10*) + # Is there a better link_static_flag that works with the bundled CC? + wl='-Wl,' + link_static_flag="${wl}-a ${wl}archive" + pic_flag='+Z' + ;; + + irix5* | irix6*) + wl='-Wl,' + link_static_flag='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + os2*) + # We can build DLLs from non-PIC. + ;; + + osf3* | osf4*) + # All OSF/1 code is PIC. + wl='-Wl,' + link_static_flag='-non_shared' + ;; + + sco3.2v5*) + pic_flag='-Kpic' + link_static_flag='-dn' + special_shlib_compile_flags='-belf' + ;; + + solaris2*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + sunos4*) + pic_flag='-PIC' + link_static_flag='-Bstatic' + wl='-Qoption ld ' + ;; + + sysv4.2uw2*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + uts4*) + pic_flag='-pic' + link_static_flag='-Bstatic' + ;; + + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$pic_flag"; then + echo "$ac_t$pic_flag" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 + $rm conftest* + echo > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $pic_flag -DPIC" + echo "$progname:547: checking if $compiler PIC flag $pic_flag works" >&5 + if { (eval echo $progname:548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= + else + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + can_build_shared=no + pic_flag= + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + echo "$ac_t"none 1>&6 +fi + +# Check for any special shared library compilation flags. +if test -n "$special_shlib_compile_flags"; then + echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : + else + echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 + can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 +$rm conftest* +echo 'main(){return(0);}' > conftest.c +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $link_static_flag" +echo "$progname:591: checking if $compiler static flag $link_static_flag works" >&5 +if { (eval echo $progname:592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + echo "$ac_t$link_static_flag" 1>&6 +else + echo "$ac_t"none 1>&6 + link_static_flag= +fi +LDFLAGS="$save_LDFLAGS" +$rm conftest* + +if test -z "$LN_S"; then + # Check to see if we can use ln -s, or we need hard links. + echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 + $rm conftestdata + if ln -s X conftestdata 2>/dev/null; then + $rm conftestdata + LN_S="ln -s" + else + LN_S=ln + fi + if test "$LN_S" = "ln -s"; then + echo "$ac_t"yes 1>&6 + else + echo "$ac_t"no 1>&6 + fi +fi + +# Make sure LD is an absolute path. +if test -z "$LD"; then + ac_prog=ld + if test "$with_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 + echo "$progname:624: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + /* | [A-Za-z]:\\*) + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we are not using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld... $ac_c" 1>&6 + echo "$progname:642: checking for GNU ld" >&5 + else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 + echo "$progname:645: checking for non-GNU ld" >&5 + fi + + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog"; then + LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" + fi + + if test -n "$LD"; then + echo "$ac_t$LD" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$LD"; then + echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 + exit 1 + fi +fi + +# Check to see if it really is or is not GNU ld. +echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 +# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + with_gnu_ld=yes +else + with_gnu_ld=no +fi +echo "$ac_t$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +allow_undefined_flag= +no_undefined_flag= +archive_cmds= +old_archive_from_new_cmds= +export_dynamic_flag_spec= +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= + +case "$host_os" in +amigaos* | sunos4*) + # On these operating systems, we should treat GNU ld like the system ld. + gnu_ld_acts_native=yes + ;; +*) + gnu_ld_acts_native=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes && test "$gnu_ld_acts_native" != yes; then + + # See if GNU ld supports shared libraries. + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs' + runpath_var=LD_RUN_PATH + ld_shlibs=yes + else + ld_shlibs=no + fi + + if test "$ld_shlibs" = yes; then + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host_os" in + aix3*) + allow_undefined_flag=unsupported + archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE;$AR cru $lib $objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4*) + allow_undefined_flag=unsupported + archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry;$AR cru $lib $objdir/$soname' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data;$echo "#define NAME $libname" > $objdir/a2ixlibrary.data;$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data;$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data;$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data;$AR cru $lib$libobjs;$RANLIB $lib;(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib$libobjs /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib$libobjs' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3, at last, uses gcc -shared to do shared libraries. + freebsd3*) + archive_cmds='$CC -shared -o $lib$libobjs' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs;mv $objdir/$soname $lib' + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs' + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + ;; + + netbsd*) + # Tested with NetBSD 1.2 ld + archive_cmds='$LD -Bshareable -o $lib$libobjs' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib$libobjs' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;$echo DATA >> $objdir/$libname.def;$echo " SINGLE NONSHARED" >> $objdir/$libname.def;$echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' + ;; + + osf3* | osf4*) + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -o $lib$libobjs' + hardcode_direct=yes + ;; + + solaris2*) + no_undefined_flag=' -z text' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib$libobjs' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + + # Solaris 2 before 2.5 hardcodes -L paths. + case "$host_os" in + solaris2.[0-4]*) + hardcode_minus_L=yes + ;; + esac + ;; + + sunos4*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared -o $lib$libobjs' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs' + fi + + if test "$with_gnu_ld" = yes; then + export_dynamic_flag_spec='${wl}-export-dynamic' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib$libobjs' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + can_build_shared=no + ;; + esac +fi +echo "$ac_t$ld_shlibs" 1>&6 + +if test -z "$NM"; then + echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 + case "$NM" in + /* | [A-Za-z]:\\*) ;; # Let the user override the test with a path. + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -B" + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -p" + else + NM="$ac_dir/nm" + fi + break + fi + done + IFS="$ac_save_ifs" + test -z "$NM" && NM=nm + ;; + esac + echo "$ac_t$NM" 1>&6 +fi + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRSTU]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \1' + +# Define system-specific variables. +case "$host_os" in +aix*) + symcode='[BCDTU]' + ;; +irix*) + # Cannot use undefined symbols on IRIX because inlined functions mess us up. + symcode='[BCDEGRST]' + ;; +solaris2*) + symcode='[BDTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTUW]' +fi + +# Write the raw and C identifiers. +global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'" + +# Check to see that the pipe works correctly. +pipe_works=no +$rm conftest* +cat > conftest.c <&5 +if { (eval echo $progname:972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:975: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + wcout=`wc "$nlist" 2>/dev/null` + count=`$echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'` + (test "$count" -ge 0) 2>/dev/null || count=-1 + else + rm -f "$nlist"T + count=-1 + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define __ptr_t void * +#else +# define __ptr_t char * +#endif + +/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */ +int dld_preloaded_symbol_count = $count; + +/* The mapping between symbol names and symbols. */ +struct { + char *name; + __ptr_t address; +} +dld_preloaded_symbols[] = +{ +EOF + sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (__ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.o conftestm.o + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS='conftestm.o' + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi +else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 +fi +$rm conftest* + +# Do not use the global_symbol_pipe unless it works. +echo "$ac_t$pipe_works" 1>&6 +test "$pipe_works" = yes || global_symbol_pipe= + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && \ + test "$hardcode_minus_L" != no && \ + test "$hardcode_shlibpath_var" != no; then + + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +elif test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" != yes; then + # We cannot hardcode anything. + hardcode_action=unsupported +else + # We can only hardcode existing directories. + hardcode_action=relink +fi +echo "$ac_t$hardcode_action" 1>&6 +test "$hardcode_action" = unsupported && can_build_shared=no + + +reload_flag= +reload_cmds='$LD$reload_flag -o $output$reload_objs' +echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 +# PORTME Some linker may need a different reload flag. +reload_flag='-r' +echo "$ac_t$reload_flag" +test -n "$reload_flag" && reload_flag=" $reload_flag" + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +version_type=none +dynamic_linker="$host_os ld.so" + +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host_os" in +aix3* | aix4*) + version_type=linux + library_names_spec='${libname}${release}.so.$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so.$major' + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +freebsd2* | freebsd3*) + version_type=sunos + library_names_spec='${libname}${release}.so.$versuffix $libname.so' + finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +gnu*) + version_type=sunos + library_names_spec='${libname}${release}.so.$versuffix' + shlibpath_var=LD_LIBRARY_PATH + ;; + +hpux9* | hpux10*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + shlibpath_var=SHLIB_PATH + library_names_spec='${libname}${release}.sl.$versuffix ${libname}${release}.sl.$major $libname.sl' + soname_spec='${libname}${release}.sl.$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=osf + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so.$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' + soname_spec='${libname}${release}.so.$major' + finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + + if test -f /lib/ld.so.1; then + dynamic_linker='GNU ld.so' + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in + powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi + ;; + +netbsd* | openbsd*) + version_type=sunos + library_names_spec='${libname}${release}.so.$versuffix' + finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4*) + version_type=osf + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so.$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so.$major' + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris2*) + version_type=linux + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' + soname_spec='${libname}${release}.so.$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so.$versuffix' + finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4.2uw2*) + version_type=linux + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' + soname_spec='${libname}${release}.so.$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' + soname_spec='${libname}${release}.so.$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds;\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" + +# Now quote all the things that may contain metacharacters. +for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \ + old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \ + link_static_flag no_builtin_flag export_dynamic_flag_spec \ + libname_spec library_names_spec soname_spec RANLIB \ + old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds postinstall_cmds postuninstall_cmds \ + allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe \ + hardcode_libdir_flag_spec hardcode_libdir_separator; do + + case "$var" in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | archive_cmds | \ + postinstall_cmds | postuninstall_cmds | finish_cmds) + # Double-quote double-evaled strings. + eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`" + ;; + *) + eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`" + ;; + esac +done + +ofile=libtool +trap "$rm $ofile; exit 1" 1 2 15 +echo creating $ofile +$rm $ofile +cat < $ofile +#! /bin/sh + +# libtool - Provide generalized library-building support services. +# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-1998 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This program was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\ +# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +# An echo program that does not interpret backslashes. +echo="$ltecho" + +# The version of $progname that generated this script. +LTCONFIG_VERSION="$VERSION" + +# Shell to use when invoking shell scripts. +SHELL=${CONFIG_SHELL-/bin/sh} + +# Whether or not to build libtool libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build old-style libraries. +build_old_libs=$enable_static + +# The host system. +host_alias="$host_alias" +host="$host" + +# The archiver. +AR="$AR" + +# The default C compiler. +CC="$CC" + +# The linker used to build libraries. +LD="$LD" + +# Whether we need hard or soft links. +LN_S="$LN_S" + +# A BSD-compatible nm program. +NM="$NM" + +# The name of the directory that contains temporary libtool files. +objdir="$objdir" + +# How to create reloadable object files. +reload_flag="$reload_flag" +reload_cmds="$reload_cmds" + +# How to pass a linker flag through the compiler. +wl="$wl" + +# Additional compiler flags for building library objects. +pic_flag="$pic_flag" + +# Compiler flag to prevent dynamic linking. +link_static_flag="$link_static_flag" + +# Compiler flag to turn off builtin functions. +no_builtin_flag="$no_builtin_flag" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="$export_dynamic_flag_spec" + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec="$libname_spec" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="$library_names_spec" + +# The coded name of the library, if different from the real name. +soname_spec="$soname_spec" + +# Commands used to build and install an old-style archive. +RANLIB="$RANLIB" +old_archive_cmds="$old_archive_cmds" +old_postinstall_cmds="$old_postinstall_cmds" +old_postuninstall_cmds="$old_postuninstall_cmds" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="$old_archive_from_new_cmds" + +# Commands used to build and install a shared archive. +archive_cmds="$archive_cmds" +postinstall_cmds="$postinstall_cmds" +postuninstall_cmds="$postuninstall_cmds" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="$allow_undefined_flag" + +# Flag that forces no undefined symbols. +no_undefined_flag="$no_undefined_flag" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="$finish_cmds" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="$finish_eval" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="$global_symbol_pipe" + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="$hardcode_libdir_separator" + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +EOF + +case "$host_os" in +aix3*) + cat <<\EOF >> $ofile +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES +fi + +EOF + ;; +esac + +# Append the ltmain.sh script. +cat "$ltmain" >> $ofile || (rm -f $ofile; exit 1) + +chmod +x $ofile +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/src/dep/src/irrlicht/jpeglib/ltmain.sh b/src/dep/src/irrlicht/jpeglib/ltmain.sh new file mode 100644 index 0000000..fe2d850 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/ltmain.sh @@ -0,0 +1,2453 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1998 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# The name of this program. +progname=`$echo "$0" | sed 's%^.*/%%'` +modename="$progname" + +# Constants. +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.2 + +default_mode= +help="Try \`$progname --help' for more information." +magic="%%%MAGIC variable%%%" +mkdir="mkdir" +mv="mv -f" +rm="rm -f" + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test "$LTCONFIG_VERSION" != "$VERSION"; then + echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION" + exit 0 + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + $echo "$modename: you cannot specify the output filename with \`-o'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + + # Recognize several different file suffixes. + xform='[cCFSfms]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e 's/\.lo$/.o/'` ;; + *) + $echo "$modename: cannot determine name of library object from \`$srcfile'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + $run $rm $obj $libobj + trap "$run $rm $obj $libobj; exit 1" 1 2 15 + else + $run $rm $libobj + trap "$run $rm $libobj; exit 1" 1 2 15 + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + $show "$base_compile$pic_flag -DPIC $srcfile" + if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then : + else + test -n "$obj" && $run $rm $obj + exit 1 + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag"; then + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj + exit $? + fi + + # Just move the object, then go on to compile the next one + $show "$mv $obj $libobj" + $run $mv $obj $libobj || exit 1 + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + # Suppress compiler output if we already did a PIC compilation. + $show "$base_compile $srcfile$suppress_output" + if $run eval "$base_compile \$srcfile$suppress_output"; then : + else + $run $rm $obj $libobj + exit 1 + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + CC="$nonopt" + allow_undefined=yes + compile_command="$CC" + finalize_command="$CC" + + compile_shlibpath= + finalize_shlibpath= + deplibs= + dlfiles= + dlprefiles= + export_dynamic=no + hardcode_libdirs= + libobjs= + link_against_libtool_libs= + ltlibs= + objs= + prev= + prevarg= + release= + rpath= + perm_rpath= + temp_rpath= + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case "$arg" in + -all-static | -static) + if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + for arg + do + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + *) + dlprefiles="$dlprefiles $arg" + test "$prev" = dlfiles && dlfiles="$dlfiles $arg" + prev= + ;; + esac + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath) + rpath="$rpath $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + if test "$export_dynamic" != yes; then + export_dynamic=yes + if test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + else + arg= + fi + + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + fi + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'` + case "$dir" in + /* | [A-Za-z]:\\*) + # Add the corresponding hardcode_libdir_flag, if it is not identical. + ;; + *) + $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2 + exit 1 + ;; + esac + deplibs="$deplibs $arg" + ;; + + -l*) deplibs="$deplibs $arg" ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.a) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e 's/\.lo$/\.o/'` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$libdir"; then + $echo "$modename: \`$arg' contains no -rpath information" 1>&2 + exit 1 + fi + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname"; then + # If there is no dlname, we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test "$build_libtool_libs" = yes && test -n "$library_names"; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # This is the magic to use -rpath. + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + # Put the magic libdir with the hardcode flag. + hardcode_libdirs="$libdir" + libdir="@HARDCODE_LIBDIRS@" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + libdir= + fi + fi + + if test -n "$libdir"; then + eval flag=\"$hardcode_libdir_flag_spec\" + + compile_command="$compile_command $flag" + finalize_command="$finalize_command $flag" + fi + elif test -n "$runpath_var"; then + # Do the same for the permanent run path. + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + + + case "$hardcode_action" in + immediate) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + elif test "$hardcode_minus_L" = no; then + compile_command="$compile_command -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + compile_shlibpath="$compile_shlibpath$dir:" + compile_command="$compile_command -l$name" + fi + ;; + + relink) + # We need an absolute path. + case "$dir" in + /* | [A-Za-z]:\\*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + compile_command="$compile_command -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + compile_shlibpath="$compile_shlibpath$dir:" + compile_command="$compile_command -l$name" + fi + ;; + + *) + $echo "$modename: \`$hardcode_action' is an unknown hardcode action" 1>&2 + exit 1 + ;; + esac + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + finalize_command="$finalize_command -L$libdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + finalize_shlibpath="$finalize_shlibpath$libdir:" + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + finalize_command="$finalize_command -L$libdir -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + compile_command="$compile_command -L$dir -l$name" + finalize_command="$finalize_command -L$dir -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$vinfo" && test -n "$release"; then + $echo "$modename: you cannot specify both \`-version-info' and \`-release'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + oldlib= + oldobjs= + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + */* | *\\*) + $echo "$modename: output file \`$output' must have no directory components" 1>&2 + exit 1 + ;; + + *.a) + # Now set the variables for building old libraries. + build_libtool_libs=no + build_old_libs=yes + oldlib="$output" + $show "$rm $oldlib" + $run $rm $oldlib + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$output" in + lib*) ;; + *) + $echo "$modename: libtool library \`$arg' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + name=`$echo "X$output" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + current=0 + revision=0 + age=0 + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles"; then + $echo "$modename: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2 + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$rpath"; then + $echo "$modename: you must specify an installation directory with \`-rpath'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo + IFS="$save_ifs" + + if test -n "$5"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + test -n "$2" && current="$2" + test -n "$3" && revision="$3" + test -n "$4" && age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + version_vars="version_type current age revision" + case "$version_type" in + none) ;; + + linux) + version_vars="$version_vars major versuffix" + major=`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + version_vars="$version_vars versuffix verstring" + major=`expr $current - $age` + versuffix="$current.$age.$revision" + verstring="$versuffix" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + version_vars="$version_vars major versuffix" + major="$current" + versuffix="$current.$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Create the output directory, or remove our outputs if we need to. + if test -d $objdir; then + $show "$rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*" + $run $rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.* + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + # Add libc to deplibs on all systems. + dependency_libs="$deplibs" + deplibs="$deplibs -lc" + + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are PIC. + test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//g'` + + # Do each of the archive commands. + eval cmds=\"$archive_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + $show "(cd $objdir && $LN_S $realname $linkname)" + $run eval '(cd $objdir && $LN_S $realname $linkname)' || exit $? + done + + # If -export-dynamic was specified, set the dlname. + if test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + + # Now set the variables for building old libraries. + oldlib="$objdir/$libname.a" + ;; + + *.lo | *.o) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into reloadable objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles"; then + $echo "$modename: warning: \`-dlopen' is ignored while creating objects" 1>&2 + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored while creating objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored while creating objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e 's/\.lo$/.o/'` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Create the old-style object. + reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'` + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + test -z "$libobj" && exit 0 + + if test "$build_libtool_libs" != yes; then + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit 1 + fi + + exit 0 + ;; + + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored while linking programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2 + fi + + if test -n "$rpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + # Put the magic libdir with the hardcode flag. + hardcode_libdirs="$libdir" + libdir="@HARDCODE_LIBDIRS@" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + libdir= + fi + fi + + if test -n "$libdir"; then + eval flag=\"$hardcode_libdir_flag_spec\" + + compile_command="$compile_command $flag" + finalize_command="$finalize_command $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + fi + + # Substitute the hardcoded libdirs into the compile commands. + if test -n "$hardcode_libdir_separator"; then + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"` + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + finalize_command=`$echo "X$finalize_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + fi + + if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${output}S.c" + else + dlsyms= + fi + + if test -n "$dlsyms"; then + # Add our own program objects to the preloaded list. + dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'` + + # Discover the nlist of each of the dlfiles. + nlist="$objdir/${output}.nm" + + if test -d $objdir; then + $show "$rm $nlist ${nlist}T" + $run $rm "$nlist" "${nlist}T" + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + # Parse the name list into a source file. + $show "creating $objdir/$dlsyms" + if test -z "$run"; then + # Make sure we at least have an empty file. + test -f "$nlist" || : > "$nlist" + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + wcout=`wc "$nlist" 2>/dev/null` + count=`echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'` + (test "$count" -ge 0) 2>/dev/null || count=-1 + else + $rm "$nlist"T + count=-1 + fi + + case "$dlsyms" in + "") ;; + *.c) + $echo > "$objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define dld_preloaded_symbol_count some_other_symbol +#define dld_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test -f "$nlist"; then + sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms" + else + echo '/* NONE */' >> "$objdir/$dlsyms" + fi + + $echo >> "$objdir/$dlsyms" "\ + +#undef dld_preloaded_symbol_count +#undef dld_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define __ptr_t void * +#else +# define __ptr_t char * +#endif + +/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */ +int dld_preloaded_symbol_count = $count; + +/* The mapping between symbol names and symbols. */ +struct { + char *name; + __ptr_t address; +} +dld_preloaded_symbols[] = +{\ +" + + if test -f "$nlist"; then + sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms" + fi + + $echo >> "$objdir/$dlsyms" "\ + {0, (__ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif\ +" + ;; + + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + fi + + # Now compile the dynamic symbol file. + $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")" + $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $? + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"` + elif test "$export_dynamic" != yes; then + test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2 + else + # We keep going just in case the user didn't refer to + # dld_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + + # We have no uninstalled library dependencies, so finalize right now. + $show "$compile_command" + $run eval "$compile_command" + exit $? + fi + + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'%g'` + finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'T%g'` + + # Create the binary in the object directory, then wrap it. + if test -d $objdir; then : + else + $show "$mkdir $objdir" + $run $mkdir $objdir + status=$? + if test $status -eq 0 || test -d $objdir; then : + else + exit $status + fi + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + /* | [A-Za-z]:\\*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + # Delete the old output file. + $run $rm $output + + if test -n "$compile_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command" + finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command" + fi + + case "$hardcode_action" in + relink) + # AGH! Flame the AIX and HP-UX people for me, will ya? + $echo "$modename: warning: using a buggy system linker" 1>&2 + $echo "$modename: relinking will be required before \`$output' can be installed" 1>&2 + ;; + esac + + $show "$compile_command" + $run eval "$compile_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the finalize command for shipping. + finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"` + + # Quote $echo for shipping. + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! /bin/sh + +# $output - temporary wrapper script for $objdir/$output +# Generated by ltmain.sh - GNU $PACKAGE $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of \``pwd`'. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + link_against_libtool_libs='$link_against_libtool_libs' + finalize_command=\"$finalize_command\" +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" = \"$magic\"; then : + else + echo=\"$qecho\" + file=\"\$0\" + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + /* | [A-Za-z]:\\*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" + + progdir=\"\$thisdir/$objdir\" + program='$output' + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\` + + export $shlibpath_var +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} + + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + if test "$build_old_libs" = "yes"; then + # Transform .lo files to .o files. + oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'` + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.a" + + $show "creating $output" + + # Only create the output if not a dry run. + if test -z "$run"; then + $echo > $output "\ +# $output - a libtool library file +# Generated by ltmain.sh - GNU $PACKAGE $VERSION + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $objdir && $LN_S ../$output $output)" + $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1 + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional /bin/sh argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL"; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir= + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test -n "$isdir"; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + /* | [A-Za-z]:\\*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + test "X$dlname" = "X$realname" && dlname= + + if test $# -gt 0; then + # Delete the old symlinks. + rmcmd="$rm" + for linkname + do + rmcmd="$rmcmd $destdir/$linkname" + done + $show "$rmcmd" + $run $rmcmd + + # ... and create new ones. + for linkname + do + test "X$dlname" = "X$linkname" && dlname= + $show "(cd $destdir && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $LN_S $realname $linkname)" + done + fi + + if test -n "$dlname"; then + # Install the dynamically-loadable library. + $show "$install_prog $dir/$dlname $destdir/$dlname" + $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $? + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + $show "$install_prog $file $destdir/$name" + $run eval "$install_prog $file $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e 's/\.lo$/\.o/'` + ;; + *.o) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e 's/\.lo$/\.o/'` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + link_against_libtool_libs= + finalize_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -z "$libdir"; then + $echo "$modename: warning: \`$lib' contains no -rpath information" 1>&2 + elif test -f "$libfile"; then : + else + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + if test "$hardcode_action" = relink; then + if test "$finalize" = yes; then + $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2 + $show "$finalize_command" + if $run eval "$finalize_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + file="$objdir/$file"T + else + $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $dest" + $run eval "$install_prog\$stripme \$file \$dest" || exit $? + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" + fi + done + fi + + echo "------------------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "To link against installed libraries in a given directory, LIBDIR," + echo "you must use the \`-LLIBDIR' flag during linking." + echo + echo " You will also need to do one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "------------------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test -f "$file"; then : + else + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + test "X$n" = "X$dlname" && dlname= + done + test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname" + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS=';' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e 's/\.lo$/\.o/'` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + +-n, --dry-run display commands without modifying any files + --features display configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to dld_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only +library objects (\`.lo' files) may be specified, and \`-rpath' is required. + +If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar' +and \`ranlib'. + +If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is +created, otherwise an executable program is created." + ;; + +uninstall) + $echo +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/src/dep/src/irrlicht/jpeglib/makcjpeg.st b/src/dep/src/irrlicht/jpeglib/makcjpeg.st new file mode 100644 index 0000000..06bdf56 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makcjpeg.st @@ -0,0 +1,38 @@ +; Project file for Independent JPEG Group's software +; +; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C. +; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de), +; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de), +; and Guido Vollbeding (guivol@esc.de). +; +; To use this file, rename it to cjpeg.prj. +; If you are using Turbo C, change filenames beginning with "pc..." to "tc..." +; Read installation instructions before trying to make the program! +; +; +; * * * Output file * * * +cjpeg.ttp +; +; * * * COMPILER OPTIONS * * * +.C[-P] ; absolute calls +.C[-M] ; and no string merging, folks +.C[-w-cln] ; no "constant is long" warnings +.C[-w-par] ; no "parameter xxxx unused" +.C[-w-rch] ; no "unreachable code" +.C[-wsig] ; warn if significant digits may be lost += +; * * * * List of modules * * * * +pcstart.o +cjpeg.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,jversion.h) +cdjpeg.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdswitch.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdppm.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdgif.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdtarga.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdbmp.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdrle.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +libjpeg.lib ; built by libjpeg.prj +pcfltlib.lib ; floating point library +; the float library can be omitted if you've turned off DCT_FLOAT_SUPPORTED +pcstdlib.lib ; standard library +pcextlib.lib ; extended library diff --git a/src/dep/src/irrlicht/jpeglib/makdjpeg.st b/src/dep/src/irrlicht/jpeglib/makdjpeg.st new file mode 100644 index 0000000..873fd0f --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makdjpeg.st @@ -0,0 +1,38 @@ +; Project file for Independent JPEG Group's software +; +; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C. +; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de), +; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de), +; and Guido Vollbeding (guivol@esc.de). +; +; To use this file, rename it to djpeg.prj. +; If you are using Turbo C, change filenames beginning with "pc..." to "tc..." +; Read installation instructions before trying to make the program! +; +; +; * * * Output file * * * +djpeg.ttp +; +; * * * COMPILER OPTIONS * * * +.C[-P] ; absolute calls +.C[-M] ; and no string merging, folks +.C[-w-cln] ; no "constant is long" warnings +.C[-w-par] ; no "parameter xxxx unused" +.C[-w-rch] ; no "unreachable code" +.C[-wsig] ; warn if significant digits may be lost += +; * * * * List of modules * * * * +pcstart.o +djpeg.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,jversion.h) +cdjpeg.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdcolmap.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +wrppm.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +wrgif.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +wrtarga.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +wrbmp.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +wrrle.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +libjpeg.lib ; built by libjpeg.prj +pcfltlib.lib ; floating point library +; the float library can be omitted if you've turned off DCT_FLOAT_SUPPORTED +pcstdlib.lib ; standard library +pcextlib.lib ; extended library diff --git a/src/dep/src/irrlicht/jpeglib/makeapps.ds b/src/dep/src/irrlicht/jpeglib/makeapps.ds new file mode 100644 index 0000000..8535d4d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makeapps.ds @@ -0,0 +1,828 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=cjpeg - Win32 +!MESSAGE No configuration specified. Defaulting to cjpeg - Win32. +!ENDIF + +!IF "$(CFG)" != "cjpeg - Win32" && "$(CFG)" != "djpeg - Win32" &&\ + "$(CFG)" != "jpegtran - Win32" && "$(CFG)" != "rdjpgcom - Win32" &&\ + "$(CFG)" != "wrjpgcom - Win32" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "apps.mak" CFG="cjpeg - Win32" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cjpeg - Win32" (based on "Win32 (x86) Console Application") +!MESSAGE "djpeg - Win32" (based on "Win32 (x86) Console Application") +!MESSAGE "jpegtran - Win32" (based on "Win32 (x86) Console Application") +!MESSAGE "rdjpgcom - Win32" (based on "Win32 (x86) Console Application") +!MESSAGE "wrjpgcom - Win32" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "cjpeg - Win32" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cjpeg - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cjpeg\Release" +# PROP BASE Intermediate_Dir "cjpeg\Release" +# PROP BASE Target_Dir "cjpeg" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "cjpeg\Release" +# PROP Intermediate_Dir "cjpeg\Release" +# PROP Target_Dir "cjpeg" +OUTDIR=.\cjpeg\Release +INTDIR=.\cjpeg\Release + +ALL : "$(OUTDIR)\cjpeg.exe" + +CLEAN : + -@erase "$(INTDIR)\cjpeg.obj" + -@erase "$(INTDIR)\rdppm.obj" + -@erase "$(INTDIR)\rdgif.obj" + -@erase "$(INTDIR)\rdtarga.obj" + -@erase "$(INTDIR)\rdrle.obj" + -@erase "$(INTDIR)\rdbmp.obj" + -@erase "$(INTDIR)\rdswitch.obj" + -@erase "$(INTDIR)\cdjpeg.obj" + -@erase "$(OUTDIR)\cjpeg.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/cjpeg.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\cjpeg\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/cjpeg.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/cjpeg.pdb" /machine:I386 /out:"$(OUTDIR)/cjpeg.exe" +LINK32_OBJS= \ + "$(INTDIR)\cjpeg.obj" \ + "$(INTDIR)\rdppm.obj" \ + "$(INTDIR)\rdgif.obj" \ + "$(INTDIR)\rdtarga.obj" \ + "$(INTDIR)\rdrle.obj" \ + "$(INTDIR)\rdbmp.obj" \ + "$(INTDIR)\rdswitch.obj" \ + "$(INTDIR)\cdjpeg.obj" \ + + +"$(OUTDIR)\cjpeg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "djpeg - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "djpeg\Release" +# PROP BASE Intermediate_Dir "djpeg\Release" +# PROP BASE Target_Dir "djpeg" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "djpeg\Release" +# PROP Intermediate_Dir "djpeg\Release" +# PROP Target_Dir "djpeg" +OUTDIR=.\djpeg\Release +INTDIR=.\djpeg\Release + +ALL : "$(OUTDIR)\djpeg.exe" + +CLEAN : + -@erase "$(INTDIR)\djpeg.obj" + -@erase "$(INTDIR)\wrppm.obj" + -@erase "$(INTDIR)\wrgif.obj" + -@erase "$(INTDIR)\wrtarga.obj" + -@erase "$(INTDIR)\wrrle.obj" + -@erase "$(INTDIR)\wrbmp.obj" + -@erase "$(INTDIR)\rdcolmap.obj" + -@erase "$(INTDIR)\cdjpeg.obj" + -@erase "$(OUTDIR)\djpeg.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/djpeg.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\djpeg\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/djpeg.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/djpeg.pdb" /machine:I386 /out:"$(OUTDIR)/djpeg.exe" +LINK32_OBJS= \ + "$(INTDIR)\djpeg.obj" \ + "$(INTDIR)\wrppm.obj" \ + "$(INTDIR)\wrgif.obj" \ + "$(INTDIR)\wrtarga.obj" \ + "$(INTDIR)\wrrle.obj" \ + "$(INTDIR)\wrbmp.obj" \ + "$(INTDIR)\rdcolmap.obj" \ + "$(INTDIR)\cdjpeg.obj" \ + + +"$(OUTDIR)\djpeg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "jpegtran - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "jpegtran\Release" +# PROP BASE Intermediate_Dir "jpegtran\Release" +# PROP BASE Target_Dir "jpegtran" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "jpegtran\Release" +# PROP Intermediate_Dir "jpegtran\Release" +# PROP Target_Dir "jpegtran" +OUTDIR=.\jpegtran\Release +INTDIR=.\jpegtran\Release + +ALL : "$(OUTDIR)\jpegtran.exe" + +CLEAN : + -@erase "$(INTDIR)\jpegtran.obj" + -@erase "$(INTDIR)\rdswitch.obj" + -@erase "$(INTDIR)\cdjpeg.obj" + -@erase "$(INTDIR)\transupp.obj" + -@erase "$(OUTDIR)\jpegtran.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/jpegtran.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\jpegtran\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/jpegtran.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/jpegtran.pdb" /machine:I386 /out:"$(OUTDIR)/jpegtran.exe" +LINK32_OBJS= \ + "$(INTDIR)\jpegtran.obj" \ + "$(INTDIR)\rdswitch.obj" \ + "$(INTDIR)\cdjpeg.obj" \ + "$(INTDIR)\transupp.obj" \ + + +"$(OUTDIR)\jpegtran.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "rdjpgcom - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "rdjpgcom\Release" +# PROP BASE Intermediate_Dir "rdjpgcom\Release" +# PROP BASE Target_Dir "rdjpgcom" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "rdjpgcom\Release" +# PROP Intermediate_Dir "rdjpgcom\Release" +# PROP Target_Dir "rdjpgcom" +OUTDIR=.\rdjpgcom\Release +INTDIR=.\rdjpgcom\Release + +ALL : "$(OUTDIR)\rdjpgcom.exe" + +CLEAN : + -@erase "$(INTDIR)\rdjpgcom.obj" + -@erase "$(OUTDIR)\rdjpgcom.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/rdjpgcom.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\rdjpgcom\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/rdjpgcom.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/rdjpgcom.pdb" /machine:I386 /out:"$(OUTDIR)/rdjpgcom.exe" +LINK32_OBJS= \ + "$(INTDIR)\rdjpgcom.obj" + +"$(OUTDIR)\rdjpgcom.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "wrjpgcom - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "wrjpgcom\Release" +# PROP BASE Intermediate_Dir "wrjpgcom\Release" +# PROP BASE Target_Dir "wrjpgcom" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "wrjpgcom\Release" +# PROP Intermediate_Dir "wrjpgcom\Release" +# PROP Target_Dir "wrjpgcom" +OUTDIR=.\wrjpgcom\Release +INTDIR=.\wrjpgcom\Release + +ALL : "$(OUTDIR)\wrjpgcom.exe" + +CLEAN : + -@erase "$(INTDIR)\wrjpgcom.obj" + -@erase "$(OUTDIR)\wrjpgcom.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/wrjpgcom.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\wrjpgcom\Release/ +CPP_SBRS=.\. +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/wrjpgcom.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\ + odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/wrjpgcom.pdb" /machine:I386 /out:"$(OUTDIR)/wrjpgcom.exe" +LINK32_OBJS= \ + "$(INTDIR)\wrjpgcom.obj" + +"$(OUTDIR)\wrjpgcom.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "cjpeg - Win32" + +!IF "$(CFG)" == "cjpeg - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="cjpeg.c" +DEP_CPP_CJPEG=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + "jversion.h"\ + + +"$(INTDIR)\cjpeg.obj" : $(SOURCE) $(DEP_CPP_CJPEG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="cdjpeg.c" +DEP_CPP_CDJPE=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdswitch.c" +DEP_CPP_RDSWI=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdswitch.obj" : $(SOURCE) $(DEP_CPP_RDSWI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdppm.c" +DEP_CPP_RDPPM=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdppm.obj" : $(SOURCE) $(DEP_CPP_RDPPM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdgif.c" +DEP_CPP_RDGIF=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdgif.obj" : $(SOURCE) $(DEP_CPP_RDGIF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdtarga.c" +DEP_CPP_RDTAR=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdtarga.obj" : $(SOURCE) $(DEP_CPP_RDTAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdbmp.c" +DEP_CPP_RDBMP=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdbmp.obj" : $(SOURCE) $(DEP_CPP_RDBMP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdrle.c" +DEP_CPP_RDRLE=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdrle.obj" : $(SOURCE) $(DEP_CPP_RDRLE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "djpeg - Win32" + +!IF "$(CFG)" == "djpeg - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="djpeg.c" +DEP_CPP_DJPEG=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + "jversion.h"\ + + +"$(INTDIR)\djpeg.obj" : $(SOURCE) $(DEP_CPP_DJPEG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="cdjpeg.c" +DEP_CPP_CDJPE=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdcolmap.c" +DEP_CPP_RDCOL=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdcolmap.obj" : $(SOURCE) $(DEP_CPP_RDCOL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="wrppm.c" +DEP_CPP_WRPPM=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\wrppm.obj" : $(SOURCE) $(DEP_CPP_WRPPM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="wrgif.c" +DEP_CPP_WRGIF=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\wrgif.obj" : $(SOURCE) $(DEP_CPP_WRGIF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="wrtarga.c" +DEP_CPP_WRTAR=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\wrtarga.obj" : $(SOURCE) $(DEP_CPP_WRTAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="wrbmp.c" +DEP_CPP_WRBMP=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\wrbmp.obj" : $(SOURCE) $(DEP_CPP_WRBMP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="wrrle.c" +DEP_CPP_WRRLE=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\wrrle.obj" : $(SOURCE) $(DEP_CPP_WRRLE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "jpegtran - Win32" + +!IF "$(CFG)" == "jpegtran - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="jpegtran.c" +DEP_CPP_JPEGT=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + "transupp.h"\ + "jversion.h"\ + + +"$(INTDIR)\jpegtran.obj" : $(SOURCE) $(DEP_CPP_JPEGT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="cdjpeg.c" +DEP_CPP_CDJPE=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="rdswitch.c" +DEP_CPP_RDSWI=\ + "cdjpeg.h"\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + "cderror.h"\ + + +"$(INTDIR)\rdswitch.obj" : $(SOURCE) $(DEP_CPP_RDSWI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="transupp.c" +DEP_CPP_TRANS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "transupp.h"\ + + +"$(INTDIR)\transupp.obj" : $(SOURCE) $(DEP_CPP_TRANS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "rdjpgcom - Win32" + +!IF "$(CFG)" == "rdjpgcom - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="rdjpgcom.c" +DEP_CPP_RDJPG=\ + "jinclude.h"\ + "jconfig.h"\ + + +"$(INTDIR)\rdjpgcom.obj" : $(SOURCE) $(DEP_CPP_RDJPG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "wrjpgcom - Win32" + +!IF "$(CFG)" == "wrjpgcom - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="wrjpgcom.c" +DEP_CPP_WRJPG=\ + "jinclude.h"\ + "jconfig.h"\ + + +"$(INTDIR)\wrjpgcom.obj" : $(SOURCE) $(DEP_CPP_WRJPG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ + diff --git a/src/dep/src/irrlicht/jpeglib/makefile.ansi b/src/dep/src/irrlicht/jpeglib/makefile.ansi new file mode 100644 index 0000000..39e8462 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.ansi @@ -0,0 +1,214 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is suitable for Unix-like systems with ANSI-capable compilers. +# If you have a non-ANSI compiler, makefile.unix is a better starting point. + +# Read installation instructions before saying "make" !! + +# The name of your C compiler: +CC= cc + +# You may need to adjust these cc options: +CFLAGS= -O +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Link-time cc options: +LDFLAGS= + +# To link any special libraries, add the necessary -l commands here. +LDLIBS= + +# Put here the object file name for the correct system-dependent memory +# manager file. For Unix this is usually jmemnobs.o, but you may want +# to use jmemansi.o or jmemname.o if you have limited swap space. +SYSDEPMEM= jmemnobs.o + +# miscellaneous OS-dependent stuff +# linker +LN= $(CC) +# file deletion command +RM= rm -f +# library (.a) file creation command +AR= ar rc +# second step in .a creation (use "touch" if not needed) +AR2= ranlib + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \ + jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \ + jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \ + jfdctint.o +# decompression library object files +DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \ + jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \ + jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \ + jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o +# These objectfiles are included in libjpeg.a +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \ + cdjpeg.o +DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \ + cdjpeg.o +TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o + + +all: libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom + +libjpeg.a: $(LIBOBJECTS) + $(RM) libjpeg.a + $(AR) libjpeg.a $(LIBOBJECTS) + $(AR2) libjpeg.a + +cjpeg: $(COBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS) + +djpeg: $(DOBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS) + +jpegtran: $(TROBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS) + +rdjpgcom: rdjpgcom.o + $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS) + +wrjpgcom: wrjpgcom.o + $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS) + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: + $(RM) *.o cjpeg djpeg jpegtran libjpeg.a rdjpgcom wrjpgcom + $(RM) core testout* + +test: cjpeg djpeg jpegtran + $(RM) testout* + ./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + ./cjpeg -dct int -outfile testout.jpg testimg.ppm + ./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + ./jpegtran -outfile testoutt.jpg testprog.jpg + cmp testimg.ppm testout.ppm + cmp testimg.bmp testout.bmp + cmp testimg.jpg testout.jpg + cmp testimg.ppm testoutp.ppm + cmp testimgp.jpg testoutp.jpg + cmp testorig.jpg testoutt.jpg + + +jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.bcc b/src/dep/src/irrlicht/jpeglib/makefile.bcc new file mode 100644 index 0000000..92e3218 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.bcc @@ -0,0 +1,285 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is suitable for Borland C on MS-DOS or OS/2. +# It works with Borland C++ for DOS, revision 3.0 or later, +# and has been tested with Borland C++ for OS/2. +# Watch out for optimization bugs in the OS/2 compilers --- see notes below! +# Thanks to Tom Wright and Ge' Weijers (original DOS) and +# Ken Porter (OS/2) for this file. + +# Read installation instructions before saying "make" !! + +# Are we under DOS or OS/2? +!if !$d(DOS) && !$d(OS2) +!if $d(__OS2__) +OS2=1 +!else +DOS=1 +!endif +!endif + +# The name of your C compiler: +CC= bcc + +# You may need to adjust these cc options: +!if $d(DOS) +CFLAGS= -O2 -mm -w-par -w-stu -w-ccc -w-rch +!else +CFLAGS= -O1 -w-par -w-stu -w-ccc -w-rch +!endif +# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z). +# -O2 is buggy in Borland OS/2 C++ revision 2.0, so use -O1 there for now. +# If you have Borland OS/2 C++ revision 1.0, use -O or no optimization at all. +# -mm selects medium memory model (near data, far code pointers; DOS only!) +# -w-par suppresses warnings about unused function parameters +# -w-stu suppresses warnings about incomplete structures +# -w-ccc suppresses warnings about compile-time-constant conditions +# -w-rch suppresses warnings about unreachable code +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Link-time cc options: +!if $d(DOS) +LDFLAGS= -mm +# memory model option here must match CFLAGS! +!else +LDFLAGS= +# -lai full-screen app +# -lc case-significant link +!endif + +# Put here the object file name for the correct system-dependent memory +# manager file. +# For DOS, we recommend jmemdos.c and jmemdosa.asm. +# For OS/2, we recommend jmemnobs.c (flat memory!) +# SYSDEPMEMLIB must list the same files with "+" signs for the librarian. +!if $d(DOS) +SYSDEPMEM= jmemdos.obj jmemdosa.obj +SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj +!else +SYSDEPMEM= jmemnobs.obj +SYSDEPMEMLIB= +jmemnobs.obj +!endif + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \ + jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \ + jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \ + jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj +# decompression library object files +DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \ + jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \ + jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \ + jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \ + jquant1.obj jquant2.obj jdmerge.obj +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \ + rdswitch.obj cdjpeg.obj +DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \ + rdcolmap.obj cdjpeg.obj +TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj + + +all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + +libjpeg.lib: $(LIBOBJECTS) + - del libjpeg.lib + tlib libjpeg.lib /E /C @&&| ++jcapimin.obj +jcapistd.obj +jctrans.obj +jcparam.obj +jdatadst.obj & ++jcinit.obj +jcmaster.obj +jcmarker.obj +jcmainct.obj +jcprepct.obj & ++jccoefct.obj +jccolor.obj +jcsample.obj +jchuff.obj +jcphuff.obj & ++jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj +jfdctint.obj +jdapimin.obj & ++jdapistd.obj +jdtrans.obj +jdatasrc.obj +jdmaster.obj +jdinput.obj & ++jdmarker.obj +jdhuff.obj +jdphuff.obj +jdmainct.obj +jdcoefct.obj & ++jdpostct.obj +jddctmgr.obj +jidctfst.obj +jidctflt.obj +jidctint.obj & ++jidctred.obj +jdsample.obj +jdcolor.obj +jquant1.obj +jquant2.obj & ++jdmerge.obj +jcomapi.obj +jutils.obj +jerror.obj +jmemmgr.obj & +$(SYSDEPMEMLIB) +| + +cjpeg.exe: $(COBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) -ecjpeg.exe $(COBJECTS) libjpeg.lib + +djpeg.exe: $(DOBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) -edjpeg.exe $(DOBJECTS) libjpeg.lib + +jpegtran.exe: $(TROBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) -ejpegtran.exe $(TROBJECTS) libjpeg.lib + +rdjpgcom.exe: rdjpgcom.c +!if $d(DOS) + $(CC) -ms -O rdjpgcom.c +!else + $(CC) $(CFLAGS) rdjpgcom.c +!endif + +# On DOS, wrjpgcom needs large model so it can malloc a 64K chunk +wrjpgcom.exe: wrjpgcom.c +!if $d(DOS) + $(CC) -ml -O wrjpgcom.c +!else + $(CC) $(CFLAGS) wrjpgcom.c +!endif + +# This "{}" syntax allows Borland Make to "batch" source files. +# In this way, each run of the compiler can build many modules. +.c.obj: + $(CC) $(CFLAGS) -c{ $<} + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: + - del *.obj + - del libjpeg.lib + - del cjpeg.exe + - del djpeg.exe + - del jpegtran.exe + - del rdjpgcom.exe + - del wrjpgcom.exe + - del testout*.* + +test: cjpeg.exe djpeg.exe jpegtran.exe + - del testout*.* + djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + cjpeg -dct int -outfile testout.jpg testimg.ppm + djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + jpegtran -outfile testoutt.jpg testprog.jpg +!if $d(DOS) + fc /b testimg.ppm testout.ppm + fc /b testimg.bmp testout.bmp + fc /b testimg.jpg testout.jpg + fc /b testimg.ppm testoutp.ppm + fc /b testimgp.jpg testoutp.jpg + fc /b testorig.jpg testoutt.jpg +!else + echo n > n.tmp + comp testimg.ppm testout.ppm < n.tmp + comp testimg.bmp testout.bmp < n.tmp + comp testimg.jpg testout.jpg < n.tmp + comp testimg.ppm testoutp.ppm < n.tmp + comp testimgp.jpg testoutp.jpg < n.tmp + comp testorig.jpg testoutt.jpg < n.tmp + del n.tmp +!endif + + +jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +jmemdosa.obj: jmemdosa.asm + tasm /mx jmemdosa.asm diff --git a/src/dep/src/irrlicht/jpeglib/makefile.cfg b/src/dep/src/irrlicht/jpeglib/makefile.cfg new file mode 100644 index 0000000..4e54bb0 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.cfg @@ -0,0 +1,319 @@ +# Makefile for Independent JPEG Group's software + +# makefile.cfg is edited by configure to produce a custom Makefile. + +# Read installation instructions before saying "make" !! + +# For compiling with source and object files in different directories. +srcdir = @srcdir@ +VPATH = @srcdir@ + +# Where to install the programs and man pages. +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib +includedir = $(prefix)/include +binprefix = +manprefix = +manext = 1 +mandir = $(prefix)/man/man$(manext) + +# The name of your C compiler: +CC= @CC@ + +# You may need to adjust these cc options: +CFLAGS= @CFLAGS@ @CPPFLAGS@ @INCLUDEFLAGS@ +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. +# However, any special defines for ansi2knr.c may be included here: +ANSI2KNRFLAGS= @ANSI2KNRFLAGS@ + +# Link-time cc options: +LDFLAGS= @LDFLAGS@ + +# To link any special libraries, add the necessary -l commands here. +LDLIBS= @LIBS@ + +# If using GNU libtool, LIBTOOL references it; if not, LIBTOOL is empty. +LIBTOOL = @LIBTOOL@ +# $(O) expands to "lo" if using libtool, plain "o" if not. +# Similarly, $(A) expands to "la" or "a". +O = @O@ +A = @A@ + +# Library version ID; libtool uses this for the shared library version number. +# Note: we suggest this match the macro of the same name in jpeglib.h. +JPEG_LIB_VERSION = @JPEG_LIB_VERSION@ + +# Put here the object file name for the correct system-dependent memory +# manager file. For Unix this is usually jmemnobs.o, but you may want +# to use jmemansi.o or jmemname.o if you have limited swap space. +SYSDEPMEM= @MEMORYMGR@ + +# miscellaneous OS-dependent stuff +SHELL= /bin/sh +# linker +LN= @LN@ +# file deletion command +RM= rm -f +# directory creation command +MKDIR= mkdir +# library (.a) file creation command +AR= ar rc +# second step in .a creation (use "touch" if not needed) +AR2= @RANLIB@ +# installation program +INSTALL= @INSTALL@ +INSTALL_PROGRAM= @INSTALL_PROGRAM@ +INSTALL_LIB= @INSTALL_LIB@ +INSTALL_DATA= @INSTALL_DATA@ + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.$(O) jutils.$(O) jerror.$(O) jmemmgr.$(O) $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.$(O) jcapistd.$(O) jctrans.$(O) jcparam.$(O) \ + jdatadst.$(O) jcinit.$(O) jcmaster.$(O) jcmarker.$(O) jcmainct.$(O) \ + jcprepct.$(O) jccoefct.$(O) jccolor.$(O) jcsample.$(O) jchuff.$(O) \ + jcphuff.$(O) jcdctmgr.$(O) jfdctfst.$(O) jfdctflt.$(O) \ + jfdctint.$(O) +# decompression library object files +DLIBOBJECTS= jdapimin.$(O) jdapistd.$(O) jdtrans.$(O) jdatasrc.$(O) \ + jdmaster.$(O) jdinput.$(O) jdmarker.$(O) jdhuff.$(O) jdphuff.$(O) \ + jdmainct.$(O) jdcoefct.$(O) jdpostct.$(O) jddctmgr.$(O) \ + jidctfst.$(O) jidctflt.$(O) jidctint.$(O) jidctred.$(O) \ + jdsample.$(O) jdcolor.$(O) jquant1.$(O) jquant2.$(O) jdmerge.$(O) +# These objectfiles are included in libjpeg.a +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.$(O) rdppm.$(O) rdgif.$(O) rdtarga.$(O) rdrle.$(O) \ + rdbmp.$(O) rdswitch.$(O) cdjpeg.$(O) +DOBJECTS= djpeg.$(O) wrppm.$(O) wrgif.$(O) wrtarga.$(O) wrrle.$(O) \ + wrbmp.$(O) rdcolmap.$(O) cdjpeg.$(O) +TROBJECTS= jpegtran.$(O) rdswitch.$(O) cdjpeg.$(O) transupp.$(O) + + +all: @A2K_DEPS@ libjpeg.$(A) cjpeg djpeg jpegtran rdjpgcom wrjpgcom + +# Special compilation rules to support ansi2knr and libtool. +.SUFFIXES: .lo .la + +# How to compile with libtool. +@COM_LT@.c.lo: +@COM_LT@ $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/$*.c + +# How to use ansi2knr, when not using libtool. +@COM_A2K@.c.o: +@COM_A2K@ ./ansi2knr $(srcdir)/$*.c knr/$*.c +@COM_A2K@ $(CC) $(CFLAGS) -c knr/$*.c +@COM_A2K@ $(RM) knr/$*.c + +# How to use ansi2knr AND libtool. +@COM_A2K@.c.lo: +@COM_A2K@ ./ansi2knr $(srcdir)/$*.c knr/$*.c +@COM_A2K@ $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c knr/$*.c +@COM_A2K@ $(RM) knr/$*.c + +ansi2knr: ansi2knr.c + $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr $(srcdir)/ansi2knr.c + $(MKDIR) knr + +# the library: + +# without libtool: +libjpeg.a: @A2K_DEPS@ $(LIBOBJECTS) + $(RM) libjpeg.a + $(AR) libjpeg.a $(LIBOBJECTS) + $(AR2) libjpeg.a + +# with libtool: +libjpeg.la: @A2K_DEPS@ $(LIBOBJECTS) + $(LIBTOOL) --mode=link $(CC) -o libjpeg.la $(LIBOBJECTS) \ + -rpath $(libdir) -version-info $(JPEG_LIB_VERSION) + +# sample programs: + +cjpeg: $(COBJECTS) libjpeg.$(A) + $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.$(A) $(LDLIBS) + +djpeg: $(DOBJECTS) libjpeg.$(A) + $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.$(A) $(LDLIBS) + +jpegtran: $(TROBJECTS) libjpeg.$(A) + $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.$(A) $(LDLIBS) + +rdjpgcom: rdjpgcom.$(O) + $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.$(O) $(LDLIBS) + +wrjpgcom: wrjpgcom.$(O) + $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.$(O) $(LDLIBS) + +# Installation rules: + +install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom @FORCE_INSTALL_LIB@ + $(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg + $(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg + $(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran + $(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom + $(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom + $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext) + $(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext) + $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext) + $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext) + $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext) + +install-lib: libjpeg.$(A) install-headers + $(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A) + +install-headers: jconfig.h + $(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h + $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h + $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h + $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h + +clean: + $(RM) *.o *.lo libjpeg.a libjpeg.la + $(RM) cjpeg djpeg jpegtran rdjpgcom wrjpgcom + $(RM) ansi2knr core testout* config.log config.status + $(RM) -r knr .libs _libs + +distclean: clean + $(RM) Makefile jconfig.h libtool config.cache + +test: cjpeg djpeg jpegtran + $(RM) testout* + ./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg + ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg + ./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm + ./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg + ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm + ./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg + cmp $(srcdir)/testimg.ppm testout.ppm + cmp $(srcdir)/testimg.bmp testout.bmp + cmp $(srcdir)/testimg.jpg testout.jpg + cmp $(srcdir)/testimg.ppm testoutp.ppm + cmp $(srcdir)/testimgp.jpg testoutp.jpg + cmp $(srcdir)/testorig.jpg testoutt.jpg + +check: test + +# Mistake catcher: + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +# GNU Make likes to know which target names are not really files to be made: +.PHONY: all install install-lib install-headers clean distclean test check + + +jcapimin.$(O): jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.$(O): jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.$(O): jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.$(O): jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.$(O): jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.$(O): jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.$(O): jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.$(O): jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.$(O): jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.$(O): jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.$(O): jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.$(O): jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.$(O): jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.$(O): jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.$(O): jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.$(O): jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.$(O): jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.$(O): jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.$(O): jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.$(O): jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.$(O): jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.$(O): jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.$(O): jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.$(O): jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.$(O): jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.$(O): jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.$(O): jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.$(O): jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.$(O): jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.$(O): jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.$(O): jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.$(O): jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.$(O): jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.$(O): jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.$(O): jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.$(O): jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.$(O): jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.$(O): jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.$(O): jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.$(O): jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.$(O): jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.$(O): jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.$(O): jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.$(O): jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.$(O): jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.$(O): jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.$(O): jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.$(O): jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.$(O): jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.$(O): jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.$(O): cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.$(O): djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.$(O): jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.$(O): rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.$(O): wrjpgcom.c jinclude.h jconfig.h +cdjpeg.$(O): cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.$(O): rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.$(O): rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.$(O): transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.$(O): rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.$(O): wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.$(O): rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.$(O): wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.$(O): rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.$(O): wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.$(O): rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.$(O): wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.$(O): rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.$(O): wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.dj b/src/dep/src/irrlicht/jpeglib/makefile.dj new file mode 100644 index 0000000..4355ce2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.dj @@ -0,0 +1,220 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is for DJGPP (Delorie's GNU C port on MS-DOS), v2.0 or later. +# Thanks to Frank J. Donahoe for this version. + +# Read installation instructions before saying "make" !! + +# The name of your C compiler: +CC= gcc + +# You may need to adjust these cc options: +CFLAGS= -O2 -Wall -I. +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Link-time cc options: +LDFLAGS= -s + +# To link any special libraries, add the necessary -l commands here. +LDLIBS= + +# Put here the object file name for the correct system-dependent memory +# manager file. For DJGPP this is usually jmemnobs.o, but you could +# use jmemname.o if you want to use named temp files instead of swap space. +SYSDEPMEM= jmemnobs.o + +# miscellaneous OS-dependent stuff +# linker +LN= $(CC) +# file deletion command +RM= del +# library (.a) file creation command +AR= ar rc +# second step in .a creation (use "touch" if not needed) +AR2= ranlib + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \ + jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \ + jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \ + jfdctint.o +# decompression library object files +DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \ + jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \ + jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \ + jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o +# These objectfiles are included in libjpeg.a +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \ + cdjpeg.o +DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \ + cdjpeg.o +TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o + + +all: libjpeg.a cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + +libjpeg.a: $(LIBOBJECTS) + $(RM) libjpeg.a + $(AR) libjpeg.a $(LIBOBJECTS) + $(AR2) libjpeg.a + +cjpeg.exe: $(COBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o cjpeg.exe $(COBJECTS) libjpeg.a $(LDLIBS) + +djpeg.exe: $(DOBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o djpeg.exe $(DOBJECTS) libjpeg.a $(LDLIBS) + +jpegtran.exe: $(TROBJECTS) libjpeg.a + $(LN) $(LDFLAGS) -o jpegtran.exe $(TROBJECTS) libjpeg.a $(LDLIBS) + +rdjpgcom.exe: rdjpgcom.o + $(LN) $(LDFLAGS) -o rdjpgcom.exe rdjpgcom.o $(LDLIBS) + +wrjpgcom.exe: wrjpgcom.o + $(LN) $(LDFLAGS) -o wrjpgcom.exe wrjpgcom.o $(LDLIBS) + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: + $(RM) *.o + $(RM) cjpeg.exe + $(RM) djpeg.exe + $(RM) jpegtran.exe + $(RM) rdjpgcom.exe + $(RM) wrjpgcom.exe + $(RM) libjpeg.a + $(RM) testout*.* + +test: cjpeg.exe djpeg.exe jpegtran.exe + $(RM) testout*.* + ./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + ./cjpeg -dct int -outfile testout.jpg testimg.ppm + ./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + ./jpegtran -outfile testoutt.jpg testprog.jpg + fc /b testimg.ppm testout.ppm + fc /b testimg.bmp testout.bmp + fc /b testimg.jpg testout.jpg + fc /b testimg.ppm testoutp.ppm + fc /b testimgp.jpg testoutp.jpg + fc /b testorig.jpg testoutt.jpg + + +jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.manx b/src/dep/src/irrlicht/jpeglib/makefile.manx new file mode 100644 index 0000000..7cbc752 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.manx @@ -0,0 +1,214 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is for Amiga systems using Manx Aztec C ver 5.x. +# Thanks to D.J. James (djjames@cup.portal.com) for this version. + +# Read installation instructions before saying "make" !! + +# The name of your C compiler: +CC= cc + +# You may need to adjust these cc options: +# Uncomment for generic 68000 code (will work on any Amiga) +ARCHFLAGS= -sn + +# Uncomment for 68020/68030 code (faster, but won't run on 68000 CPU) +#ARCHFLAGS= -c2 + +CFLAGS= -MC -MD $(ARCHFLAGS) -spfam -r4 + +# Link-time cc options: +LDFLAGS= -g + +# To link any special libraries, add the necessary -l commands here. +LDLIBS= -lml -lcl + +# Put here the object file name for the correct system-dependent memory +# manager file. For Amiga we recommend jmemname.o. +SYSDEPMEM= jmemname.o + +# miscellaneous OS-dependent stuff +# linker +LN= ln +# file deletion command +RM= delete quiet +# library (.lib) file creation command +AR= lb + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \ + jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \ + jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \ + jfdctint.o +# decompression library object files +DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \ + jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \ + jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \ + jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \ + cdjpeg.o +DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \ + cdjpeg.o +TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o + + +all: libjpeg.lib cjpeg djpeg jpegtran rdjpgcom wrjpgcom + +libjpeg.lib: $(LIBOBJECTS) + -$(RM) libjpeg.lib + $(AR) libjpeg.lib $(LIBOBJECTS) + +cjpeg: $(COBJECTS) libjpeg.lib + $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.lib $(LDLIBS) + +djpeg: $(DOBJECTS) libjpeg.lib + $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.lib $(LDLIBS) + +jpegtran: $(TROBJECTS) libjpeg.lib + $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.lib $(LDLIBS) + +rdjpgcom: rdjpgcom.o + $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS) + +wrjpgcom: wrjpgcom.o + $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS) + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: + -$(RM) *.o cjpeg djpeg jpegtran libjpeg.lib rdjpgcom wrjpgcom + -$(RM) core testout*.* + +test: cjpeg djpeg jpegtran + -$(RM) testout*.* + djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + cjpeg -dct int -outfile testout.jpg testimg.ppm + djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + jpegtran -outfile testoutt.jpg testprog.jpg + cmp testimg.ppm testout.ppm + cmp testimg.bmp testout.bmp + cmp testimg.jpg testout.jpg + cmp testimg.ppm testoutp.ppm + cmp testimgp.jpg testoutp.jpg + cmp testorig.jpg testoutt.jpg + + +jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.mc6 b/src/dep/src/irrlicht/jpeglib/makefile.mc6 new file mode 100644 index 0000000..1185fb4 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.mc6 @@ -0,0 +1,249 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is for Microsoft C for MS-DOS, version 6.00A and up. +# Use NMAKE, not Microsoft's brain-damaged MAKE. +# Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd. + +# Read installation instructions before saying "nmake" !! + +# You may need to adjust these compiler options: +CFLAGS = -AM -Oecigt -Gs -W3 +# -AM medium memory model (or use -AS for small model, if you remove features) +# -Oecigt -Gs maximum safe optimisation (-Ol has bugs in MSC 6.00A) +# -W3 warning level 3 +# You might also want to add -G2 if you have an 80286, etc. +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Jan-Herman Buining suggests the following switches for MS C 8.0 and a 486: +# CFLAGS = /AM /f- /FPi87 /G3 /Gs /Gy /Ob1 /Oc /Oe /Og /Oi /Ol /On /Oo /Ot \ +# /OV4 /W3 +# except for jquant1.c, which must be compiled with /Oo- to avoid a compiler +# crash. + +# Ingar Steinsland suggests the following switches when building +# a 16-bit Windows DLL: +# CFLAGS = -ALw -Gsw -Zpe -W3 -O2 -Zi -Zd + +# Put here the object file name for the correct system-dependent memory +# manager file. For DOS, we recommend jmemdos.c and jmemdosa.asm. +# (But not for Windows; see install.doc if you use this makefile for Windows.) +SYSDEPMEM= jmemdos.obj jmemdosa.obj +# SYSDEPMEMLIB must list the same files with "+" signs for the librarian. +SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \ + jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \ + jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \ + jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj +# decompression library object files +DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \ + jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \ + jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \ + jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \ + jquant1.obj jquant2.obj jdmerge.obj +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \ + rdswitch.obj cdjpeg.obj +DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \ + rdcolmap.obj cdjpeg.obj +TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj + +# need linker response file because file list > 128 chars +RFILE = libjpeg.ans + + +all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + +libjpeg.lib: $(LIBOBJECTS) $(RFILE) + del libjpeg.lib + lib @$(RFILE) + +# linker response file for building libjpeg.lib +$(RFILE) : makefile + del $(RFILE) + echo libjpeg.lib >$(RFILE) +# silly want-to-create-it prompt: + echo y >>$(RFILE) + echo +jcapimin.obj +jcapistd.obj +jctrans.obj +jcparam.obj & >>$(RFILE) + echo +jdatadst.obj +jcinit.obj +jcmaster.obj +jcmarker.obj & >>$(RFILE) + echo +jcmainct.obj +jcprepct.obj +jccoefct.obj & >>$(RFILE) + echo +jccolor.obj +jcsample.obj +jchuff.obj +jcphuff.obj & >>$(RFILE) + echo +jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj & >>$(RFILE) + echo +jfdctint.obj +jdapimin.obj +jdapistd.obj & >>$(RFILE) + echo +jdtrans.obj +jdatasrc.obj +jdmaster.obj +jdinput.obj & >>$(RFILE) + echo +jdmarker.obj +jdhuff.obj +jdphuff.obj +jdmainct.obj & >>$(RFILE) + echo +jdcoefct.obj +jdpostct.obj +jddctmgr.obj & >>$(RFILE) + echo +jidctfst.obj +jidctflt.obj +jidctint.obj & >>$(RFILE) + echo +jidctred.obj +jdsample.obj +jdcolor.obj +jquant1.obj & >>$(RFILE) + echo +jquant2.obj +jdmerge.obj +jcomapi.obj +jutils.obj & >>$(RFILE) + echo +jerror.obj +jmemmgr.obj & >>$(RFILE) + echo $(SYSDEPMEMLIB) ; >>$(RFILE) + +cjpeg.exe: $(COBJECTS) libjpeg.lib + echo $(COBJECTS) >cjpeg.lst + link /STACK:4096 /EXEPACK @cjpeg.lst, cjpeg.exe, , libjpeg.lib, ; + del cjpeg.lst + +djpeg.exe: $(DOBJECTS) libjpeg.lib + echo $(DOBJECTS) >djpeg.lst + link /STACK:4096 /EXEPACK @djpeg.lst, djpeg.exe, , libjpeg.lib, ; + del djpeg.lst + +jpegtran.exe: $(TROBJECTS) libjpeg.lib + link /STACK:4096 /EXEPACK $(TROBJECTS), jpegtran.exe, , libjpeg.lib, ; + +rdjpgcom.exe: rdjpgcom.c + $(CC) -AS -O -W3 rdjpgcom.c + +# wrjpgcom needs large model so it can malloc a 64K chunk +wrjpgcom.exe: wrjpgcom.c + $(CC) -AL -O -W3 wrjpgcom.c + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: + del *.obj + del libjpeg.lib + del cjpeg.exe + del djpeg.exe + del jpegtran.exe + del rdjpgcom.exe + del wrjpgcom.exe + del testout*.* + +test: cjpeg.exe djpeg.exe jpegtran.exe + del testout*.* + djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + cjpeg -dct int -outfile testout.jpg testimg.ppm + djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + jpegtran -outfile testoutt.jpg testprog.jpg + fc /b testimg.ppm testout.ppm + fc /b testimg.bmp testout.bmp + fc /b testimg.jpg testout.jpg + fc /b testimg.ppm testoutp.ppm + fc /b testimgp.jpg testoutp.jpg + fc /b testorig.jpg testoutt.jpg + + +jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +jmemdosa.obj : jmemdosa.asm + masm /mx $*; diff --git a/src/dep/src/irrlicht/jpeglib/makefile.mms b/src/dep/src/irrlicht/jpeglib/makefile.mms new file mode 100644 index 0000000..4ce8b89 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.mms @@ -0,0 +1,218 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is for use with MMS on Digital VMS systems. +# Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu) +# and Tim Bell (tbell@netcom.com) for their help. + +# Read installation instructions before saying "MMS" !! + +# You may need to adjust these cc options: +CFLAGS= $(CFLAGS) /NoDebug /Optimize +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via /Define switches here. +.ifdef ALPHA +OPT= +.else +OPT= ,Sys$Disk:[]MAKVMS.OPT/Option +.endif + +# Put here the object file name for the correct system-dependent memory +# manager file. For Unix this is usually jmemnobs.o, but you may want +# to use jmemansi.o or jmemname.o if you have limited swap space. +SYSDEPMEM= jmemnobs.obj + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \ + jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \ + jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \ + jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj +# decompression library object files +DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \ + jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \ + jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \ + jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \ + jquant1.obj jquant2.obj jdmerge.obj +# These objectfiles are included in libjpeg.olb +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \ + rdswitch.obj cdjpeg.obj +DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \ + rdcolmap.obj cdjpeg.obj +TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj +# objectfile lists with commas --- what a crock +COBJLIST= cjpeg.obj,rdppm.obj,rdgif.obj,rdtarga.obj,rdrle.obj,rdbmp.obj,\ + rdswitch.obj,cdjpeg.obj +DOBJLIST= djpeg.obj,wrppm.obj,wrgif.obj,wrtarga.obj,wrrle.obj,wrbmp.obj,\ + rdcolmap.obj,cdjpeg.obj +TROBJLIST= jpegtran.obj,rdswitch.obj,cdjpeg.obj,transupp.obj +LIBOBJLIST= jcapimin.obj,jcapistd.obj,jctrans.obj,jcparam.obj,jdatadst.obj,\ + jcinit.obj,jcmaster.obj,jcmarker.obj,jcmainct.obj,jcprepct.obj,\ + jccoefct.obj,jccolor.obj,jcsample.obj,jchuff.obj,jcphuff.obj,\ + jcdctmgr.obj,jfdctfst.obj,jfdctflt.obj,jfdctint.obj,jdapimin.obj,\ + jdapistd.obj,jdtrans.obj,jdatasrc.obj,jdmaster.obj,jdinput.obj,\ + jdmarker.obj,jdhuff.obj,jdphuff.obj,jdmainct.obj,jdcoefct.obj,\ + jdpostct.obj,jddctmgr.obj,jidctfst.obj,jidctflt.obj,jidctint.obj,\ + jidctred.obj,jdsample.obj,jdcolor.obj,jquant1.obj,jquant2.obj,\ + jdmerge.obj,jcomapi.obj,jutils.obj,jerror.obj,jmemmgr.obj,$(SYSDEPMEM) + + +.first + @- Define /NoLog Sys Sys$Library + +ALL : libjpeg.olb cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + @ Continue + +libjpeg.olb : $(LIBOBJECTS) + Library /Create libjpeg.olb $(LIBOBJLIST) + +cjpeg.exe : $(COBJECTS) libjpeg.olb + $(LINK) $(LFLAGS) /Executable = cjpeg.exe $(COBJLIST),libjpeg.olb/Library$(OPT) + +djpeg.exe : $(DOBJECTS) libjpeg.olb + $(LINK) $(LFLAGS) /Executable = djpeg.exe $(DOBJLIST),libjpeg.olb/Library$(OPT) + +jpegtran.exe : $(TROBJECTS) libjpeg.olb + $(LINK) $(LFLAGS) /Executable = jpegtran.exe $(TROBJLIST),libjpeg.olb/Library$(OPT) + +rdjpgcom.exe : rdjpgcom.obj + $(LINK) $(LFLAGS) /Executable = rdjpgcom.exe rdjpgcom.obj$(OPT) + +wrjpgcom.exe : wrjpgcom.obj + $(LINK) $(LFLAGS) /Executable = wrjpgcom.exe wrjpgcom.obj$(OPT) + +jconfig.h : jconfig.vms + @- Copy jconfig.vms jconfig.h + +clean : + @- Set Protection = Owner:RWED *.*;-1 + @- Set Protection = Owner:RWED *.OBJ + - Purge /NoLog /NoConfirm *.* + - Delete /NoLog /NoConfirm *.OBJ; + +test : cjpeg.exe djpeg.exe jpegtran.exe + mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + mcr sys$disk:[]cjpeg -dct int -outfile testout.jpg testimg.ppm + mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg + - Backup /Compare/Log testimg.ppm testout.ppm + - Backup /Compare/Log testimg.bmp testout.bmp + - Backup /Compare/Log testimg.jpg testout.jpg + - Backup /Compare/Log testimg.ppm testoutp.ppm + - Backup /Compare/Log testimgp.jpg testoutp.jpg + - Backup /Compare/Log testorig.jpg testoutt.jpg + + +jcapimin.obj : jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.obj : jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.obj : jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.obj : jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.obj : jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.obj : jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.obj : jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.obj : jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.obj : jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.obj : jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.obj : jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.obj : jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.obj : jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.obj : jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.obj : jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.obj : jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.obj : jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.obj : jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.obj : jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.obj : jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.obj : jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.obj : jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.obj : jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.obj : jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.obj : jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.obj : jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.obj : jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.obj : jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.obj : jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.obj : jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.obj : jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.obj : jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.obj : jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.obj : jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.obj : jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.obj : jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.obj : jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.obj : jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.obj : jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.obj : jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.obj : jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.obj : jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.obj : jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.obj : jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.obj : jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.obj : cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.obj : djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.obj : jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.obj : rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.obj : wrjpgcom.c jinclude.h jconfig.h +cdjpeg.obj : cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.obj : rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.obj : rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.obj : transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.obj : rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.obj : wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.obj : rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.obj : wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.obj : rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.obj : wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.obj : rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.obj : wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.obj : rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.obj : wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.sas b/src/dep/src/irrlicht/jpeglib/makefile.sas new file mode 100644 index 0000000..d26793d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.sas @@ -0,0 +1,252 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is for Amiga systems using SAS C 6.0 and up. +# Thanks to Ed Hanway, Mark Rinfret, and Jim Zepeda. + +# Read installation instructions before saying "make" !! + +# The name of your C compiler: +CC= sc + +# You may need to adjust these cc options: +# Uncomment the following lines for generic 680x0 version +ARCHFLAGS= cpu=any +SUFFIX= + +# Uncomment the following lines for 68030-only version +#ARCHFLAGS= cpu=68030 +#SUFFIX=.030 + +CFLAGS= nostackcheck data=near parms=register optimize $(ARCHFLAGS) \ + ignore=104 ignore=304 ignore=306 +# ignore=104 disables warnings for mismatched const qualifiers +# ignore=304 disables warnings for variables being optimized out +# ignore=306 disables warnings for the inlining of functions +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via define switches here. + +# Link-time cc options: +LDFLAGS= SC SD ND BATCH + +# To link any special libraries, add the necessary commands here. +LDLIBS= LIB:scm.lib LIB:sc.lib + +# Put here the object file name for the correct system-dependent memory +# manager file. For Amiga we recommend jmemname.o. +SYSDEPMEM= jmemname.o + +# miscellaneous OS-dependent stuff +# linker +LN= slink +# file deletion command +RM= delete quiet +# library (.lib) file creation command +AR= oml + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \ + jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \ + jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \ + jfdctint.o +# decompression library object files +DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \ + jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \ + jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \ + jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \ + cdjpeg.o +DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \ + cdjpeg.o +TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o + + +all: libjpeg.lib cjpeg$(SUFFIX) djpeg$(SUFFIX) jpegtran$(SUFFIX) rdjpgcom$(SUFFIX) wrjpgcom$(SUFFIX) + +# note: do several AR steps to avoid command line length limitations + +libjpeg.lib: $(LIBOBJECTS) + -$(RM) libjpeg.lib + $(AR) libjpeg.lib r $(CLIBOBJECTS) + $(AR) libjpeg.lib r $(DLIBOBJECTS) + $(AR) libjpeg.lib r $(COMOBJECTS) + +cjpeg$(SUFFIX): $(COBJECTS) libjpeg.lib + $(LN) + +# You may want to adjust these compiler options: +CFLAGS= $(cflags) $(cdebug) $(cvars) -I. +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Link-time options: +LDFLAGS= $(ldebug) $(conlflags) + +# To link any special libraries, add the necessary commands here. +LDLIBS= $(conlibs) + +# Put here the object file name for the correct system-dependent memory +# manager file. For NT we suggest jmemnobs.obj, which expects the OS to +# provide adequate virtual memory. +SYSDEPMEM= jmemnobs.obj + +# miscellaneous OS-dependent stuff +# file deletion command +RM= del + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \ + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \ + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \ + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \ + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \ + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \ + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \ + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \ + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \ + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \ + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \ + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \ + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \ + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \ + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \ + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \ + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \ + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \ + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \ + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \ + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \ + jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \ + jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \ + jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj +# decompression library object files +DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \ + jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \ + jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \ + jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \ + jquant1.obj jquant2.obj jdmerge.obj +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \ + rdswitch.obj cdjpeg.obj +DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \ + rdcolmap.obj cdjpeg.obj +TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj + +# Template command for compiling .c to .obj +.c.obj: + $(cc) $(CFLAGS) $*.c + + +all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + +libjpeg.lib: $(LIBOBJECTS) + $(RM) libjpeg.lib + lib -out:libjpeg.lib $(LIBOBJECTS) + +cjpeg.exe: $(COBJECTS) libjpeg.lib + $(link) $(LDFLAGS) -out:cjpeg.exe $(COBJECTS) libjpeg.lib $(LDLIBS) + +djpeg.exe: $(DOBJECTS) libjpeg.lib + $(link) $(LDFLAGS) -out:djpeg.exe $(DOBJECTS) libjpeg.lib $(LDLIBS) + +jpegtran.exe: $(TROBJECTS) libjpeg.lib + $(link) $(LDFLAGS) -out:jpegtran.exe $(TROBJECTS) libjpeg.lib $(LDLIBS) + +rdjpgcom.exe: rdjpgcom.obj + $(link) $(LDFLAGS) -out:rdjpgcom.exe rdjpgcom.obj $(LDLIBS) + +wrjpgcom.exe: wrjpgcom.obj + $(link) $(LDFLAGS) -out:wrjpgcom.exe wrjpgcom.obj $(LDLIBS) + + +clean: + $(RM) *.obj *.exe libjpeg.lib + $(RM) testout* + +test: cjpeg.exe djpeg.exe jpegtran.exe + $(RM) testout* + .\djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + .\djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + .\cjpeg -dct int -outfile testout.jpg testimg.ppm + .\djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + .\cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + .\jpegtran -outfile testoutt.jpg testprog.jpg + fc /b testimg.ppm testout.ppm + fc /b testimg.bmp testout.bmp + fc /b testimg.jpg testout.jpg + fc /b testimg.ppm testoutp.ppm + fc /b testimgp.jpg testoutp.jpg + fc /b testorig.jpg testoutt.jpg + + +jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makefile.vms b/src/dep/src/irrlicht/jpeglib/makefile.vms new file mode 100644 index 0000000..711f852 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.vms @@ -0,0 +1,142 @@ +$! Makefile for Independent JPEG Group's software +$! +$! This is a command procedure for Digital VMS systems that do not have MMS. +$! It builds the JPEG software by brute force, recompiling everything whether +$! or not it is necessary. It then runs the basic self-test. +$! Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu) +$! and Tim Bell (tbell@netcom.com) for their help. +$! +$! Read installation instructions before running this!! +$! +$ If F$Mode () .eqs. "INTERACTIVE" +$ Then +$ VERIFY = F$Verify (0) +$ Else +$ VERIFY = F$Verify (1) +$ EndIf +$ On Control_Y Then GoTo End +$ On Error Then GoTo End +$ +$ If F$GetSyi ("HW_MODEL") .gt. 1023 +$ Then +$ OPT = "" +$ Else +$ OPT = ",Sys$Disk:[]makvms.opt/Option" +$ EndIf +$ +$ DoCompile := CC /NoDebug /Optimize /NoList +$! +$ DoCompile jcapimin.c +$ DoCompile jcapistd.c +$ DoCompile jctrans.c +$ DoCompile jcparam.c +$ DoCompile jdatadst.c +$ DoCompile jcinit.c +$ DoCompile jcmaster.c +$ DoCompile jcmarker.c +$ DoCompile jcmainct.c +$ DoCompile jcprepct.c +$ DoCompile jccoefct.c +$ DoCompile jccolor.c +$ DoCompile jcsample.c +$ DoCompile jchuff.c +$ DoCompile jcphuff.c +$ DoCompile jcdctmgr.c +$ DoCompile jfdctfst.c +$ DoCompile jfdctflt.c +$ DoCompile jfdctint.c +$ DoCompile jdapimin.c +$ DoCompile jdapistd.c +$ DoCompile jdtrans.c +$ DoCompile jdatasrc.c +$ DoCompile jdmaster.c +$ DoCompile jdinput.c +$ DoCompile jdmarker.c +$ DoCompile jdhuff.c +$ DoCompile jdphuff.c +$ DoCompile jdmainct.c +$ DoCompile jdcoefct.c +$ DoCompile jdpostct.c +$ DoCompile jddctmgr.c +$ DoCompile jidctfst.c +$ DoCompile jidctflt.c +$ DoCompile jidctint.c +$ DoCompile jidctred.c +$ DoCompile jdsample.c +$ DoCompile jdcolor.c +$ DoCompile jquant1.c +$ DoCompile jquant2.c +$ DoCompile jdmerge.c +$ DoCompile jcomapi.c +$ DoCompile jutils.c +$ DoCompile jerror.c +$ DoCompile jmemmgr.c +$ DoCompile jmemnobs.c +$! +$ Library /Create libjpeg.olb jcapimin.obj,jcapistd.obj,jctrans.obj, - + jcparam.obj,jdatadst.obj,jcinit.obj,jcmaster.obj,jcmarker.obj, - + jcmainct.obj,jcprepct.obj,jccoefct.obj,jccolor.obj,jcsample.obj, - + jchuff.obj,jcphuff.obj,jcdctmgr.obj,jfdctfst.obj,jfdctflt.obj, - + jfdctint.obj,jdapimin.obj,jdapistd.obj,jdtrans.obj,jdatasrc.obj, - + jdmaster.obj,jdinput.obj,jdmarker.obj,jdhuff.obj,jdphuff.obj, - + jdmainct.obj,jdcoefct.obj,jdpostct.obj,jddctmgr.obj,jidctfst.obj, - + jidctflt.obj,jidctint.obj,jidctred.obj,jdsample.obj,jdcolor.obj, - + jquant1.obj,jquant2.obj,jdmerge.obj,jcomapi.obj,jutils.obj, - + jerror.obj,jmemmgr.obj,jmemnobs.obj +$! +$ DoCompile cjpeg.c +$ DoCompile rdppm.c +$ DoCompile rdgif.c +$ DoCompile rdtarga.c +$ DoCompile rdrle.c +$ DoCompile rdbmp.c +$ DoCompile rdswitch.c +$ DoCompile cdjpeg.c +$! +$ Link /NoMap /Executable = cjpeg.exe cjpeg.obj,rdppm.obj,rdgif.obj, - + rdtarga.obj,rdrle.obj,rdbmp.obj,rdswitch.obj,cdjpeg.obj,libjpeg.olb/Library'OPT' +$! +$ DoCompile djpeg.c +$ DoCompile wrppm.c +$ DoCompile wrgif.c +$ DoCompile wrtarga.c +$ DoCompile wrrle.c +$ DoCompile wrbmp.c +$ DoCompile rdcolmap.c +$ DoCompile cdjpeg.c +$! +$ Link /NoMap /Executable = djpeg.exe djpeg.obj,wrppm.obj,wrgif.obj, - + wrtarga.obj,wrrle.obj,wrbmp.obj,rdcolmap.obj,cdjpeg.obj,libjpeg.olb/Library'OPT' +$! +$ DoCompile jpegtran.c +$ DoCompile rdswitch.c +$ DoCompile cdjpeg.c +$ DoCompile transupp.c +$! +$ Link /NoMap /Executable = jpegtran.exe jpegtran.obj,rdswitch.obj, - + cdjpeg.obj,transupp.obj,libjpeg.olb/Library'OPT' +$! +$ DoCompile rdjpgcom.c +$ Link /NoMap /Executable = rdjpgcom.exe rdjpgcom.obj'OPT' +$! +$ DoCompile wrjpgcom.c +$ Link /NoMap /Executable = wrjpgcom.exe wrjpgcom.obj'OPT' +$! +$! Run the self-test +$! +$ mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg +$ mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg +$ mcr sys$disk:[]cjpeg -dct int -outfile testout.jpg testimg.ppm +$ mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg +$ mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm +$ mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg +$ Backup /Compare/Log testimg.ppm testout.ppm +$ Backup /Compare/Log testimg.bmp testout.bmp +$ Backup /Compare/Log testimg.jpg testout.jpg +$ Backup /Compare/Log testimg.ppm testoutp.ppm +$ Backup /Compare/Log testimgp.jpg testoutp.jpg +$ Backup /Compare/Log testorig.jpg testoutt.jpg +$! +$End: +$ If Verify Then Set Verify +$ Exit diff --git a/src/dep/src/irrlicht/jpeglib/makefile.wat b/src/dep/src/irrlicht/jpeglib/makefile.wat new file mode 100644 index 0000000..c0570dc --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makefile.wat @@ -0,0 +1,233 @@ +# Makefile for Independent JPEG Group's software + +# This makefile is suitable for Watcom C/C++ 10.0 on MS-DOS (using +# dos4g extender), OS/2, and Windows NT console mode. +# Thanks to Janos Haide, jhaide@btrvtech.com. + +# Read installation instructions before saying "wmake" !! + +# Uncomment line for desired system +SYSTEM=DOS +#SYSTEM=OS2 +#SYSTEM=NT + +# The name of your C compiler: +CC= wcl386 + +# You may need to adjust these cc options: +CFLAGS= -4r -ort -wx -zq -bt=$(SYSTEM) +# Caution: avoid -ol or -ox; these generate bad code with 10.0 or 10.0a. +# Generally, we recommend defining any configuration symbols in jconfig.h, +# NOT via -D switches here. + +# Link-time cc options: +!ifeq SYSTEM DOS +LDFLAGS= -zq -l=dos4g +!else ifeq SYSTEM OS2 +LDFLAGS= -zq -l=os2v2 +!else ifeq SYSTEM NT +LDFLAGS= -zq -l=nt +!endif + +# Put here the object file name for the correct system-dependent memory +# manager file. jmemnobs should work fine for dos4g or OS/2 environment. +SYSDEPMEM= jmemnobs.obj + +# End of configurable options. + + +# source files: JPEG library proper +LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c & + jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c & + jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c & + jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c & + jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c & + jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c & + jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c & + jquant2.c jutils.c jmemmgr.c +# memmgr back ends: compile only one of these into a working library +SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c +# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom +APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c & + rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c & + rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c +SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES) +# files included by source files +INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h & + jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h +# documentation, test, and support files +DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 & + wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc & + coderules.doc filelist.doc change.log +MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc & + makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds & + makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st & + maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms & + makvms.opt +CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat & + jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas & + jconfig.vms +CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh +OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm +TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg & + testimgp.jpg +DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) & + $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES) +# library object files common to compression and decompression +COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM) +# compression library object files +CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj & + jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj & + jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj & + jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj +# decompression library object files +DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj & + jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj & + jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj & + jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj & + jquant1.obj jquant2.obj jdmerge.obj +# These objectfiles are included in libjpeg.lib +LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS) +# object files for sample applications (excluding library files) +COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj & + rdswitch.obj cdjpeg.obj +DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj & + rdcolmap.obj cdjpeg.obj +TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj + + +all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe + +libjpeg.lib: $(LIBOBJECTS) + - del libjpeg.lib + * wlib -n libjpeg.lib $(LIBOBJECTS) + +cjpeg.exe: $(COBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) $(COBJECTS) libjpeg.lib + +djpeg.exe: $(DOBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) $(DOBJECTS) libjpeg.lib + +jpegtran.exe: $(TROBJECTS) libjpeg.lib + $(CC) $(LDFLAGS) $(TROBJECTS) libjpeg.lib + +rdjpgcom.exe: rdjpgcom.c + $(CC) $(CFLAGS) $(LDFLAGS) rdjpgcom.c + +wrjpgcom.exe: wrjpgcom.c + $(CC) $(CFLAGS) $(LDFLAGS) wrjpgcom.c + +.c.obj: + $(CC) $(CFLAGS) -c $< + +jconfig.h: jconfig.doc + echo You must prepare a system-dependent jconfig.h file. + echo Please read the installation directions in install.doc. + exit 1 + +clean: .SYMBOLIC + - del *.obj + - del libjpeg.lib + - del cjpeg.exe + - del djpeg.exe + - del jpegtran.exe + - del rdjpgcom.exe + - del wrjpgcom.exe + - del testout*.* + +test: cjpeg.exe djpeg.exe jpegtran.exe .SYMBOLIC + - del testout*.* + djpeg -dct int -ppm -outfile testout.ppm testorig.jpg + djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg + cjpeg -dct int -outfile testout.jpg testimg.ppm + djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg + cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm + jpegtran -outfile testoutt.jpg testprog.jpg +!ifeq SYSTEM DOS + fc /b testimg.ppm testout.ppm + fc /b testimg.bmp testout.bmp + fc /b testimg.jpg testout.jpg + fc /b testimg.ppm testoutp.ppm + fc /b testimgp.jpg testoutp.jpg + fc /b testorig.jpg testoutt.jpg +!else + echo n > n.tmp + comp testimg.ppm testout.ppm < n.tmp + comp testimg.bmp testout.bmp < n.tmp + comp testimg.jpg testout.jpg < n.tmp + comp testimg.ppm testoutp.ppm < n.tmp + comp testimgp.jpg testoutp.jpg < n.tmp + comp testorig.jpg testoutt.jpg < n.tmp + del n.tmp +!endif + + +jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h +jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h +jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h +jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h +jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h +jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h +jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h +cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h +jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h +rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h +wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h +cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h +rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h +wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h diff --git a/src/dep/src/irrlicht/jpeglib/makelib.ds b/src/dep/src/irrlicht/jpeglib/makelib.ds new file mode 100644 index 0000000..78d0ddf --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makelib.ds @@ -0,0 +1,1046 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +!IF "$(CFG)" == "" +CFG=jpeg - Win32 +!MESSAGE No configuration specified. Defaulting to jpeg - Win32. +!ENDIF + +!IF "$(CFG)" != "jpeg - Win32" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "jpeg.mak" CFG="jpeg - Win32" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "jpeg - Win32" (based on "Win32 (x86) Static Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "jpeg - Win32" +CPP=cl.exe + +!IF "$(CFG)" == "jpeg - Win32" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\jpeg.lib" + +CLEAN : + -@erase "$(INTDIR)\jcapimin.obj" + -@erase "$(INTDIR)\jcapistd.obj" + -@erase "$(INTDIR)\jctrans.obj" + -@erase "$(INTDIR)\jcparam.obj" + -@erase "$(INTDIR)\jdatadst.obj" + -@erase "$(INTDIR)\jcinit.obj" + -@erase "$(INTDIR)\jcmaster.obj" + -@erase "$(INTDIR)\jcmarker.obj" + -@erase "$(INTDIR)\jcmainct.obj" + -@erase "$(INTDIR)\jcprepct.obj" + -@erase "$(INTDIR)\jccoefct.obj" + -@erase "$(INTDIR)\jccolor.obj" + -@erase "$(INTDIR)\jcsample.obj" + -@erase "$(INTDIR)\jchuff.obj" + -@erase "$(INTDIR)\jcphuff.obj" + -@erase "$(INTDIR)\jcdctmgr.obj" + -@erase "$(INTDIR)\jfdctfst.obj" + -@erase "$(INTDIR)\jfdctflt.obj" + -@erase "$(INTDIR)\jfdctint.obj" + -@erase "$(INTDIR)\jdapimin.obj" + -@erase "$(INTDIR)\jdapistd.obj" + -@erase "$(INTDIR)\jdtrans.obj" + -@erase "$(INTDIR)\jdatasrc.obj" + -@erase "$(INTDIR)\jdmaster.obj" + -@erase "$(INTDIR)\jdinput.obj" + -@erase "$(INTDIR)\jdmarker.obj" + -@erase "$(INTDIR)\jdhuff.obj" + -@erase "$(INTDIR)\jdphuff.obj" + -@erase "$(INTDIR)\jdmainct.obj" + -@erase "$(INTDIR)\jdcoefct.obj" + -@erase "$(INTDIR)\jdpostct.obj" + -@erase "$(INTDIR)\jddctmgr.obj" + -@erase "$(INTDIR)\jidctfst.obj" + -@erase "$(INTDIR)\jidctflt.obj" + -@erase "$(INTDIR)\jidctint.obj" + -@erase "$(INTDIR)\jidctred.obj" + -@erase "$(INTDIR)\jdsample.obj" + -@erase "$(INTDIR)\jdcolor.obj" + -@erase "$(INTDIR)\jquant1.obj" + -@erase "$(INTDIR)\jquant2.obj" + -@erase "$(INTDIR)\jdmerge.obj" + -@erase "$(INTDIR)\jcomapi.obj" + -@erase "$(INTDIR)\jutils.obj" + -@erase "$(INTDIR)\jerror.obj" + -@erase "$(INTDIR)\jmemmgr.obj" + -@erase "$(INTDIR)\jmemnobs.obj" + -@erase "$(OUTDIR)\jpeg.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/jpeg.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/jpeg.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +LIB32_FLAGS=/nologo /out:"$(OUTDIR)/jpeg.lib" +LIB32_OBJS= \ + "$(INTDIR)\jcapimin.obj" \ + "$(INTDIR)\jcapistd.obj" \ + "$(INTDIR)\jctrans.obj" \ + "$(INTDIR)\jcparam.obj" \ + "$(INTDIR)\jdatadst.obj" \ + "$(INTDIR)\jcinit.obj" \ + "$(INTDIR)\jcmaster.obj" \ + "$(INTDIR)\jcmarker.obj" \ + "$(INTDIR)\jcmainct.obj" \ + "$(INTDIR)\jcprepct.obj" \ + "$(INTDIR)\jccoefct.obj" \ + "$(INTDIR)\jccolor.obj" \ + "$(INTDIR)\jcsample.obj" \ + "$(INTDIR)\jchuff.obj" \ + "$(INTDIR)\jcphuff.obj" \ + "$(INTDIR)\jcdctmgr.obj" \ + "$(INTDIR)\jfdctfst.obj" \ + "$(INTDIR)\jfdctflt.obj" \ + "$(INTDIR)\jfdctint.obj" \ + "$(INTDIR)\jdapimin.obj" \ + "$(INTDIR)\jdapistd.obj" \ + "$(INTDIR)\jdtrans.obj" \ + "$(INTDIR)\jdatasrc.obj" \ + "$(INTDIR)\jdmaster.obj" \ + "$(INTDIR)\jdinput.obj" \ + "$(INTDIR)\jdmarker.obj" \ + "$(INTDIR)\jdhuff.obj" \ + "$(INTDIR)\jdphuff.obj" \ + "$(INTDIR)\jdmainct.obj" \ + "$(INTDIR)\jdcoefct.obj" \ + "$(INTDIR)\jdpostct.obj" \ + "$(INTDIR)\jddctmgr.obj" \ + "$(INTDIR)\jidctfst.obj" \ + "$(INTDIR)\jidctflt.obj" \ + "$(INTDIR)\jidctint.obj" \ + "$(INTDIR)\jidctred.obj" \ + "$(INTDIR)\jdsample.obj" \ + "$(INTDIR)\jdcolor.obj" \ + "$(INTDIR)\jquant1.obj" \ + "$(INTDIR)\jquant2.obj" \ + "$(INTDIR)\jdmerge.obj" \ + "$(INTDIR)\jcomapi.obj" \ + "$(INTDIR)\jutils.obj" \ + "$(INTDIR)\jerror.obj" \ + "$(INTDIR)\jmemmgr.obj" \ + "$(INTDIR)\jmemnobs.obj" + +"$(OUTDIR)\jpeg.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "jpeg - Win32" + +!IF "$(CFG)" == "jpeg - Win32" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE="jcapimin.c" +DEP_CPP_JCAPI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcapimin.obj" : $(SOURCE) $(DEP_CPP_JCAPI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcapistd.c" +DEP_CPP_JCAPIS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcapistd.obj" : $(SOURCE) $(DEP_CPP_JCAPIS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jccoefct.c" +DEP_CPP_JCCOE=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jccoefct.obj" : $(SOURCE) $(DEP_CPP_JCCOE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jccolor.c" +DEP_CPP_JCCOL=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jccolor.obj" : $(SOURCE) $(DEP_CPP_JCCOL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcdctmgr.c" +DEP_CPP_JCDCT=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jcdctmgr.obj" : $(SOURCE) $(DEP_CPP_JCDCT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jchuff.c" +DEP_CPP_JCHUF=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jchuff.h"\ + + +"$(INTDIR)\jchuff.obj" : $(SOURCE) $(DEP_CPP_JCHUF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcinit.c" +DEP_CPP_JCINI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcinit.obj" : $(SOURCE) $(DEP_CPP_JCINI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcmainct.c" +DEP_CPP_JCMAI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcmainct.obj" : $(SOURCE) $(DEP_CPP_JCMAI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcmarker.c" +DEP_CPP_JCMAR=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcmarker.obj" : $(SOURCE) $(DEP_CPP_JCMAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcmaster.c" +DEP_CPP_JCMAS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcmaster.obj" : $(SOURCE) $(DEP_CPP_JCMAS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcomapi.c" +DEP_CPP_JCOMA=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcomapi.obj" : $(SOURCE) $(DEP_CPP_JCOMA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcparam.c" +DEP_CPP_JCPAR=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcparam.obj" : $(SOURCE) $(DEP_CPP_JCPAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcphuff.c" +DEP_CPP_JCPHU=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jchuff.h"\ + + +"$(INTDIR)\jcphuff.obj" : $(SOURCE) $(DEP_CPP_JCPHU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcprepct.c" +DEP_CPP_JCPRE=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcprepct.obj" : $(SOURCE) $(DEP_CPP_JCPRE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jcsample.c" +DEP_CPP_JCSAM=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jcsample.obj" : $(SOURCE) $(DEP_CPP_JCSAM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jctrans.c" +DEP_CPP_JCTRA=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jctrans.obj" : $(SOURCE) $(DEP_CPP_JCTRA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdapimin.c" +DEP_CPP_JDAPI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdapimin.obj" : $(SOURCE) $(DEP_CPP_JDAPI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdapistd.c" +DEP_CPP_JDAPIS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdapistd.obj" : $(SOURCE) $(DEP_CPP_JDAPIS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdatadst.c" +DEP_CPP_JDATA=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdatadst.obj" : $(SOURCE) $(DEP_CPP_JDATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdatasrc.c" +DEP_CPP_JDATAS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdatasrc.obj" : $(SOURCE) $(DEP_CPP_JDATAS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdcoefct.c" +DEP_CPP_JDCOE=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdcoefct.obj" : $(SOURCE) $(DEP_CPP_JDCOE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdcolor.c" +DEP_CPP_JDCOL=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdcolor.obj" : $(SOURCE) $(DEP_CPP_JDCOL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jddctmgr.c" +DEP_CPP_JDDCT=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jddctmgr.obj" : $(SOURCE) $(DEP_CPP_JDDCT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdhuff.c" +DEP_CPP_JDHUF=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdhuff.h"\ + + +"$(INTDIR)\jdhuff.obj" : $(SOURCE) $(DEP_CPP_JDHUF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdinput.c" +DEP_CPP_JDINP=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdinput.obj" : $(SOURCE) $(DEP_CPP_JDINP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdmainct.c" +DEP_CPP_JDMAI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdmainct.obj" : $(SOURCE) $(DEP_CPP_JDMAI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdmarker.c" +DEP_CPP_JDMAR=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdmarker.obj" : $(SOURCE) $(DEP_CPP_JDMAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdmaster.c" +DEP_CPP_JDMAS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdmaster.obj" : $(SOURCE) $(DEP_CPP_JDMAS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdmerge.c" +DEP_CPP_JDMER=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdmerge.obj" : $(SOURCE) $(DEP_CPP_JDMER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdphuff.c" +DEP_CPP_JDPHU=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdhuff.h"\ + + +"$(INTDIR)\jdphuff.obj" : $(SOURCE) $(DEP_CPP_JDPHU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdpostct.c" +DEP_CPP_JDPOS=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdpostct.obj" : $(SOURCE) $(DEP_CPP_JDPOS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdsample.c" +DEP_CPP_JDSAM=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdsample.obj" : $(SOURCE) $(DEP_CPP_JDSAM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jdtrans.c" +DEP_CPP_JDTRA=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jdtrans.obj" : $(SOURCE) $(DEP_CPP_JDTRA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jerror.c" +DEP_CPP_JERRO=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jversion.h"\ + "jerror.h"\ + + +"$(INTDIR)\jerror.obj" : $(SOURCE) $(DEP_CPP_JERRO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jfdctflt.c" +DEP_CPP_JFDCT=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jfdctflt.obj" : $(SOURCE) $(DEP_CPP_JFDCT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jfdctfst.c" +DEP_CPP_JFDCTF=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jfdctfst.obj" : $(SOURCE) $(DEP_CPP_JFDCTF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jfdctint.c" +DEP_CPP_JFDCTI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jfdctint.obj" : $(SOURCE) $(DEP_CPP_JFDCTI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jidctflt.c" +DEP_CPP_JIDCT=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jidctflt.obj" : $(SOURCE) $(DEP_CPP_JIDCT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jidctfst.c" +DEP_CPP_JIDCTF=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jidctfst.obj" : $(SOURCE) $(DEP_CPP_JIDCTF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jidctint.c" +DEP_CPP_JIDCTI=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jidctint.obj" : $(SOURCE) $(DEP_CPP_JIDCTI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jidctred.c" +DEP_CPP_JIDCTR=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jdct.h"\ + + +"$(INTDIR)\jidctred.obj" : $(SOURCE) $(DEP_CPP_JIDCTR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jquant1.c" +DEP_CPP_JQUAN=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jquant1.obj" : $(SOURCE) $(DEP_CPP_JQUAN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jquant2.c" +DEP_CPP_JQUANT=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jquant2.obj" : $(SOURCE) $(DEP_CPP_JQUANT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jutils.c" +DEP_CPP_JUTIL=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + + +"$(INTDIR)\jutils.obj" : $(SOURCE) $(DEP_CPP_JUTIL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jmemmgr.c" +DEP_CPP_JMEMM=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jmemsys.h"\ + + +"$(INTDIR)\jmemmgr.obj" : $(SOURCE) $(DEP_CPP_JMEMM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="jmemnobs.c" +DEP_CPP_JMEMN=\ + "jinclude.h"\ + "jconfig.h"\ + "jpeglib.h"\ + "jmorecfg.h"\ + "jpegint.h"\ + "jerror.h"\ + "jmemsys.h"\ + + +"$(INTDIR)\jmemnobs.obj" : $(SOURCE) $(DEP_CPP_JMEMN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ + diff --git a/src/dep/src/irrlicht/jpeglib/makeproj.mac b/src/dep/src/irrlicht/jpeglib/makeproj.mac new file mode 100644 index 0000000..cd466da --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makeproj.mac @@ -0,0 +1,213 @@ +-- +-- makeproj.mac +-- +-- This AppleScript builds Code Warrior PRO Release 2 project files for the +-- libjpeg library as well as the test programs 'cjpeg', 'djpeg', 'jpegtran'. +-- (We'd distribute real project files, except they're not text +-- and would create maintenance headaches.) +-- +-- The script then compiles and links the library and the test programs. +-- NOTE: if you haven't already created a 'jconfig.h' file, the script +-- automatically copies 'jconfig.mac' to 'jconfig.h'. +-- +-- To use this script, you must have AppleScript 1.1 or later installed +-- and a suitable AppleScript editor like Script Editor or Script Debugger +-- (http://www.latenightsw.com). Open this file with your AppleScript +-- editor and execute the "run" command to build the projects. +-- +-- Thanks to Dan Sears and Don Agro for this script. +-- Questions about this script can be addressed to dogpark@interlog.com +-- + +on run + + choose folder with prompt ">>> Select IJG source folder <<<" + set ijg_folder to result + + choose folder with prompt ">>> Select MetroWerks folder <<<" + set cw_folder to result + + -- if jconfig.h doesn't already exist, copy jconfig.mac + + tell application "Finder" + if not (exists file "jconfig.h" of ijg_folder) then + duplicate {file "jconfig.mac" of folder ijg_folder} + select file "jconfig.mac copy" of folder ijg_folder + set name of selection to "jconfig.h" + end if + end tell + + tell application "CodeWarrior IDE 2.1" + with timeout of 10000 seconds + + -- create libjpeg project + + activate + Create Project (ijg_folder as string) & "libjpeg.proj" + Set Preferences of panel "Target Settings" to {Target Name:"libjpeg"} + Set Preferences of panel "PPC Project" to {File Name:"libjpeg"} + Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"} + Set Preferences of panel "PPC Project" to {Project Type:library} + Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true} + Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true} + Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC} + Set Preferences of panel "PPC Linker" to {Generate SYM File:false} + + Add Files (ijg_folder as string) & "jcapimin.c" To Segment 1 + Add Files (ijg_folder as string) & "jcapistd.c" To Segment 1 + Add Files (ijg_folder as string) & "jctrans.c" To Segment 1 + Add Files (ijg_folder as string) & "jcparam.c" To Segment 1 + Add Files (ijg_folder as string) & "jdatadst.c" To Segment 1 + Add Files (ijg_folder as string) & "jcinit.c" To Segment 1 + Add Files (ijg_folder as string) & "jcmaster.c" To Segment 1 + Add Files (ijg_folder as string) & "jcmarker.c" To Segment 1 + Add Files (ijg_folder as string) & "jcmainct.c" To Segment 1 + Add Files (ijg_folder as string) & "jcprepct.c" To Segment 1 + Add Files (ijg_folder as string) & "jccoefct.c" To Segment 1 + Add Files (ijg_folder as string) & "jccolor.c" To Segment 1 + Add Files (ijg_folder as string) & "jcsample.c" To Segment 1 + Add Files (ijg_folder as string) & "jchuff.c" To Segment 1 + Add Files (ijg_folder as string) & "jcphuff.c" To Segment 1 + Add Files (ijg_folder as string) & "jcdctmgr.c" To Segment 1 + Add Files (ijg_folder as string) & "jfdctfst.c" To Segment 1 + Add Files (ijg_folder as string) & "jfdctflt.c" To Segment 1 + Add Files (ijg_folder as string) & "jfdctint.c" To Segment 1 + Add Files (ijg_folder as string) & "jdapimin.c" To Segment 1 + Add Files (ijg_folder as string) & "jdapistd.c" To Segment 1 + Add Files (ijg_folder as string) & "jdtrans.c" To Segment 1 + Add Files (ijg_folder as string) & "jdatasrc.c" To Segment 1 + Add Files (ijg_folder as string) & "jdmaster.c" To Segment 1 + Add Files (ijg_folder as string) & "jdinput.c" To Segment 1 + Add Files (ijg_folder as string) & "jdmarker.c" To Segment 1 + Add Files (ijg_folder as string) & "jdhuff.c" To Segment 1 + Add Files (ijg_folder as string) & "jdphuff.c" To Segment 1 + Add Files (ijg_folder as string) & "jdmainct.c" To Segment 1 + Add Files (ijg_folder as string) & "jdcoefct.c" To Segment 1 + Add Files (ijg_folder as string) & "jdpostct.c" To Segment 1 + Add Files (ijg_folder as string) & "jddctmgr.c" To Segment 1 + Add Files (ijg_folder as string) & "jidctfst.c" To Segment 1 + Add Files (ijg_folder as string) & "jidctflt.c" To Segment 1 + Add Files (ijg_folder as string) & "jidctint.c" To Segment 1 + Add Files (ijg_folder as string) & "jidctred.c" To Segment 1 + Add Files (ijg_folder as string) & "jdsample.c" To Segment 1 + Add Files (ijg_folder as string) & "jdcolor.c" To Segment 1 + Add Files (ijg_folder as string) & "jquant1.c" To Segment 1 + Add Files (ijg_folder as string) & "jquant2.c" To Segment 1 + Add Files (ijg_folder as string) & "jdmerge.c" To Segment 1 + Add Files (ijg_folder as string) & "jcomapi.c" To Segment 1 + Add Files (ijg_folder as string) & "jutils.c" To Segment 1 + Add Files (ijg_folder as string) & "jerror.c" To Segment 1 + Add Files (ijg_folder as string) & "jmemmgr.c" To Segment 1 + Add Files (ijg_folder as string) & "jmemmac.c" To Segment 1 + + -- compile and link the library + + Make Project + Close Project + + -- create cjpeg project + + activate + Create Project (ijg_folder as string) & "cjpeg.proj" + Set Preferences of panel "Target Settings" to {Target Name:"cjpeg"} + Set Preferences of panel "PPC Project" to {File Name:"cjpeg"} + Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"} + Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true} + Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true} + Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC} + Set Preferences of panel "PPC Linker" to {Generate SYM File:false} + + Add Files (ijg_folder as string) & "cjpeg.c" To Segment 1 + Add Files (ijg_folder as string) & "rdppm.c" To Segment 1 + Add Files (ijg_folder as string) & "rdgif.c" To Segment 1 + Add Files (ijg_folder as string) & "rdtarga.c" To Segment 1 + Add Files (ijg_folder as string) & "rdrle.c" To Segment 1 + Add Files (ijg_folder as string) & "rdbmp.c" To Segment 1 + Add Files (ijg_folder as string) & "rdswitch.c" To Segment 1 + Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1 + + Add Files (ijg_folder as string) & "libjpeg" To Segment 2 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4 + + -- compile and link cjpeg + + Make Project + Close Project + + -- create djpeg project + + activate + Create Project (ijg_folder as string) & "djpeg.proj" + Set Preferences of panel "Target Settings" to {Target Name:"djpeg"} + Set Preferences of panel "PPC Project" to {File Name:"djpeg"} + Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"} + Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true} + Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true} + Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC} + Set Preferences of panel "PPC Linker" to {Generate SYM File:false} + + Add Files (ijg_folder as string) & "djpeg.c" To Segment 1 + Add Files (ijg_folder as string) & "wrppm.c" To Segment 1 + Add Files (ijg_folder as string) & "wrgif.c" To Segment 1 + Add Files (ijg_folder as string) & "wrtarga.c" To Segment 1 + Add Files (ijg_folder as string) & "wrrle.c" To Segment 1 + Add Files (ijg_folder as string) & "wrbmp.c" To Segment 1 + Add Files (ijg_folder as string) & "rdcolmap.c" To Segment 1 + Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1 + + Add Files (ijg_folder as string) & "libjpeg" To Segment 2 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4 + + -- compile and link djpeg + + Make Project + Close Project + + -- create jpegtran project + + activate + Create Project (ijg_folder as string) & "jpegtran.proj" + Set Preferences of panel "Target Settings" to {Target Name:"jpegtran"} + Set Preferences of panel "PPC Project" to {File Name:"jpegtran"} + Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"} + Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true} + Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true} + Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC} + Set Preferences of panel "PPC Linker" to {Generate SYM File:false} + + Add Files (ijg_folder as string) & "jpegtran.c" To Segment 1 + Add Files (ijg_folder as string) & "rdswitch.c" To Segment 1 + Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1 + Add Files (ijg_folder as string) & "transupp.c" To Segment 1 + + Add Files (ijg_folder as string) & "libjpeg" To Segment 2 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3 + + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4 + Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4 + + -- compile and link jpegtran + + Make Project + Close Project + + quit + + end timeout + end tell +end run diff --git a/src/dep/src/irrlicht/jpeglib/makljpeg.st b/src/dep/src/irrlicht/jpeglib/makljpeg.st new file mode 100644 index 0000000..96bfb65 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makljpeg.st @@ -0,0 +1,70 @@ +; Project file for Independent JPEG Group's software +; +; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C. +; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de), +; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de), +; and Guido Vollbeding (guivol@esc.de). +; +; To use this file, rename it to libjpeg.prj. +; Read installation instructions before trying to make the program! +; +; +; * * * Output file * * * +libjpeg.lib +; +; * * * COMPILER OPTIONS * * * +.C[-P] ; absolute calls +.C[-M] ; and no string merging, folks +.C[-w-cln] ; no "constant is long" warnings +.C[-w-par] ; no "parameter xxxx unused" +.C[-w-rch] ; no "unreachable code" +.C[-wsig] ; warn if significant digits may be lost +.L[-J] ; link new Obj-format (so we get a library) += +; * * * * List of modules * * * * +jcapimin.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcapistd.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jccoefct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jccolor.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcdctmgr.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jchuff.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jchuff.h) +jcinit.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcmainct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcmarker.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcmaster.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcomapi.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcparam.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcphuff.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jchuff.h) +jcprepct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jcsample.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jctrans.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdapimin.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdapistd.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdatadst.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h) +jdatasrc.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h) +jdcoefct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdcolor.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jddctmgr.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jdhuff.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdhuff.h) +jdinput.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdmainct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdmarker.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdmaster.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdmerge.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdphuff.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdhuff.h) +jdpostct.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdsample.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jdtrans.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jerror.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jversion.h,jerror.h) +jfdctflt.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jfdctfst.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jfdctint.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jidctflt.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jidctfst.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jidctint.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jidctred.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jdct.h) +jquant1.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jquant2.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jutils.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h) +jmemmgr.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jmemsys.h) +jmemansi.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,jmemsys.h) diff --git a/src/dep/src/irrlicht/jpeglib/maktjpeg.st b/src/dep/src/irrlicht/jpeglib/maktjpeg.st new file mode 100644 index 0000000..ced1951 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/maktjpeg.st @@ -0,0 +1,32 @@ +; Project file for Independent JPEG Group's software +; +; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C. +; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de), +; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de), +; and Guido Vollbeding (guivol@esc.de). +; +; To use this file, rename it to jpegtran.prj. +; If you are using Turbo C, change filenames beginning with "pc..." to "tc..." +; Read installation instructions before trying to make the program! +; +; +; * * * Output file * * * +jpegtran.ttp +; +; * * * COMPILER OPTIONS * * * +.C[-P] ; absolute calls +.C[-M] ; and no string merging, folks +.C[-w-cln] ; no "constant is long" warnings +.C[-w-par] ; no "parameter xxxx unused" +.C[-w-rch] ; no "unreachable code" +.C[-wsig] ; warn if significant digits may be lost += +; * * * * List of modules * * * * +pcstart.o +jpegtran.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,transupp.h,jversion.h) +cdjpeg.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +rdswitch.c (cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h) +transupp.c (jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,transupp.h) +libjpeg.lib ; built by libjpeg.prj +pcstdlib.lib ; standard library +pcextlib.lib ; extended library diff --git a/src/dep/src/irrlicht/jpeglib/makvms.opt b/src/dep/src/irrlicht/jpeglib/makvms.opt new file mode 100644 index 0000000..26db714 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/makvms.opt @@ -0,0 +1,4 @@ +! A pointer to the VAX/VMS C Run-Time Shareable Library. +! This file is needed by makefile.mms and makefile.vms, +! but only for the older VAX C compiler. DEC C does not need it. +Sys$Library:VAXCRTL.EXE /Share diff --git a/src/dep/src/irrlicht/jpeglib/rdbmp.c b/src/dep/src/irrlicht/jpeglib/rdbmp.c new file mode 100644 index 0000000..4f61bcf --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdbmp.c @@ -0,0 +1,439 @@ +/* + * rdbmp.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Microsoft "BMP" + * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors). + * Currently, only 8-bit and 24-bit images are supported, not 1-bit or + * 4-bit (feeding such low-depth images into JPEG would be silly anyway). + * Also, we don't support RLE-compressed files. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed BMP format). + * + * This code contributed by James Arthur Boucher. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef BMP_SUPPORTED + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* Private version of data source object */ + +typedef struct _bmp_source_struct * bmp_source_ptr; + +typedef struct _bmp_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + j_compress_ptr cinfo; /* back link saves passing separate parm */ + + JSAMPARRAY colormap; /* BMP colormap (converted to my format) */ + + jvirt_sarray_ptr whole_image; /* Needed to reverse row order */ + JDIMENSION source_row; /* Current source row number */ + JDIMENSION row_width; /* Physical width of scanlines in file */ + + int bits_per_pixel; /* remembers 8- or 24-bit format */ +} bmp_source_struct; + + +LOCAL(int) +read_byte (bmp_source_ptr sinfo) +/* Read next byte from BMP file */ +{ + register FILE *infile = sinfo->pub.input_file; + register int c; + + if ((c = getc(infile)) == EOF) + ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); + return c; +} + + +LOCAL(void) +read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize) +/* Read the colormap from a BMP file */ +{ + int i; + + switch (mapentrysize) { + case 3: + /* BGR format (occurs in OS/2 files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + } + break; + case 4: + /* BGR0 format (occurs in MS Windows files) */ + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + (void) read_byte(sinfo); + } + break; + default: + ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP); + break; + } +} + + +/* + * Read one row of pixels. + * The image has been read into the whole_image array, but is otherwise + * unprocessed. We must read it out in top-to-bottom row order, and if + * it is an 8-bit image, we must expand colormapped pixels to 24bit format. + */ + +METHODDEF(JDIMENSION) +get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit colormap indexes */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + register JSAMPARRAY colormap = source->colormap; + JSAMPARRAY image_ptr; + register int t; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Expand the colormap indexes to real data */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + t = GETJSAMPLE(*inptr++); + *outptr++ = colormap[0][t]; /* can omit GETJSAMPLE() safely */ + *outptr++ = colormap[1][t]; + *outptr++ = colormap[2][t]; + } + + return 1; +} + + +METHODDEF(JDIMENSION) +get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 24-bit pixels */ +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + + /* Fetch next row from virtual array */ + source->source_row--; + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source->source_row, (JDIMENSION) 1, FALSE); + + /* Transfer data. Note source values are in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = image_ptr[0]; + outptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + outptr += 3; + } + + return 1; +} + + +/* + * This method loads the image into whole_image during the first call on + * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call + * get_8bit_row or get_24bit_row on subsequent calls. + */ + +METHODDEF(JDIMENSION) +preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + register FILE *infile = source->pub.input_file; + register int c; + register JSAMPROW out_ptr; + JSAMPARRAY image_ptr; + JDIMENSION row, col; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Read the data into a virtual array in input-file row order. */ + for (row = 0; row < cinfo->image_height; row++) { + if (progress != NULL) { + progress->pub.pass_counter = (long) row; + progress->pub.pass_limit = (long) cinfo->image_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + row, (JDIMENSION) 1, TRUE); + out_ptr = image_ptr[0]; + for (col = source->row_width; col > 0; col--) { + /* inline copy of read_byte() for speed */ + if ((c = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_INPUT_EOF); + *out_ptr++ = (JSAMPLE) c; + } + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Set up to read from the virtual array in top-to-bottom order */ + switch (source->bits_per_pixel) { + case 8: + source->pub.get_pixel_rows = get_8bit_row; + break; + case 24: + source->pub.get_pixel_rows = get_24bit_row; + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + } + source->source_row = cinfo->image_height; + + /* And read the first row */ + return (*source->pub.get_pixel_rows) (cinfo, sinfo); +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + bmp_source_ptr source = (bmp_source_ptr) sinfo; + U_CHAR bmpfileheader[14]; + U_CHAR bmpinfoheader[64]; +#define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \ + (((unsigned int) UCH(array[offset+1])) << 8)) +#define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \ + (((INT32) UCH(array[offset+1])) << 8) + \ + (((INT32) UCH(array[offset+2])) << 16) + \ + (((INT32) UCH(array[offset+3])) << 24)) + INT32 bfOffBits; + INT32 headerSize; + INT32 biWidth = 0; /* initialize to avoid compiler warning */ + INT32 biHeight = 0; + unsigned int biPlanes; + INT32 biCompression; + INT32 biXPelsPerMeter,biYPelsPerMeter; + INT32 biClrUsed = 0; + int mapentrysize = 0; /* 0 indicates no colormap */ + INT32 bPad; + JDIMENSION row_width; + + /* Read and verify the bitmap file header */ + if (! ReadOK(source->pub.input_file, bmpfileheader, 14)) + ERREXIT(cinfo, JERR_INPUT_EOF); + if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ + ERREXIT(cinfo, JERR_BMP_NOT); + bfOffBits = (INT32) GET_4B(bmpfileheader,10); + /* We ignore the remaining fileheader fields */ + + /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), + * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. + */ + if (! ReadOK(source->pub.input_file, bmpinfoheader, 4)) + ERREXIT(cinfo, JERR_INPUT_EOF); + headerSize = (INT32) GET_4B(bmpinfoheader,0); + if (headerSize < 12 || headerSize > 64) + ERREXIT(cinfo, JERR_BMP_BADHEADER); + if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4)) + ERREXIT(cinfo, JERR_INPUT_EOF); + + switch ((int) headerSize) { + case 12: + /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */ + biWidth = (INT32) GET_2B(bmpinfoheader,4); + biHeight = (INT32) GET_2B(bmpinfoheader,6); + biPlanes = GET_2B(bmpinfoheader,8); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10); + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */ + TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight); + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + if (biPlanes != 1) + ERREXIT(cinfo, JERR_BMP_BADPLANES); + break; + case 40: + case 64: + /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */ + /* or OS/2 2.x header, which has additional fields that we ignore */ + biWidth = GET_4B(bmpinfoheader,4); + biHeight = GET_4B(bmpinfoheader,8); + biPlanes = GET_2B(bmpinfoheader,12); + source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); + biCompression = GET_4B(bmpinfoheader,16); + biXPelsPerMeter = GET_4B(bmpinfoheader,24); + biYPelsPerMeter = GET_4B(bmpinfoheader,28); + biClrUsed = GET_4B(bmpinfoheader,32); + /* biSizeImage, biClrImportant fields are ignored */ + + switch (source->bits_per_pixel) { + case 8: /* colormapped image */ + mapentrysize = 4; /* Windows uses RGBQUAD colormap */ + TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight); + break; + case 24: /* RGB image */ + TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); + break; + default: + ERREXIT(cinfo, JERR_BMP_BADDEPTH); + break; + } + if (biPlanes != 1) + ERREXIT(cinfo, JERR_BMP_BADPLANES); + if (biCompression != 0) + ERREXIT(cinfo, JERR_BMP_COMPRESSED); + + if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { + /* Set JFIF density parameters from the BMP data */ + cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ + cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); + cinfo->density_unit = 2; /* dots/cm */ + } + break; + default: + ERREXIT(cinfo, JERR_BMP_BADHEADER); + break; + } + + /* Compute distance to bitmap data --- will adjust for colormap below */ + bPad = bfOffBits - (headerSize + 14); + + /* Read the colormap, if any */ + if (mapentrysize > 0) { + if (biClrUsed <= 0) + biClrUsed = 256; /* assume it's 256 */ + else if (biClrUsed > 256) + ERREXIT(cinfo, JERR_BMP_BADCMAP); + /* Allocate space to store the colormap */ + source->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) biClrUsed, (JDIMENSION) 3); + /* and read it from the file */ + read_colormap(source, (int) biClrUsed, mapentrysize); + /* account for size of colormap */ + bPad -= biClrUsed * mapentrysize; + } + + /* Skip any remaining pad bytes */ + if (bPad < 0) /* incorrect bfOffBits value? */ + ERREXIT(cinfo, JERR_BMP_BADHEADER); + while (--bPad >= 0) { + (void) read_byte(source); + } + + /* Compute row width in file, including padding to 4-byte boundary */ + if (source->bits_per_pixel == 24) + row_width = (JDIMENSION) (biWidth * 3); + else + row_width = (JDIMENSION) biWidth; + while ((row_width & 3) != 0) row_width++; + source->row_width = row_width; + + /* Allocate space for inversion array, prepare for preload pass */ + source->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + row_width, (JDIMENSION) biHeight, (JDIMENSION) 1); + source->pub.get_pixel_rows = preload_image; + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + + /* Allocate one-row buffer for returned data */ + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (biWidth * 3), (JDIMENSION) 1); + source->pub.buffer_height = 1; + + cinfo->in_color_space = JCS_RGB; + cinfo->input_components = 3; + cinfo->data_precision = 8; + cinfo->image_width = (JDIMENSION) biWidth; + cinfo->image_height = (JDIMENSION) biHeight; +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for BMP format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_bmp (j_compress_ptr cinfo) +{ + bmp_source_ptr source; + + /* Create module interface object */ + source = (bmp_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(bmp_source_struct)); + source->cinfo = cinfo; /* make back link for subroutines */ + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_bmp; + source->pub.finish_input = finish_input_bmp; + + return (cjpeg_source_ptr) source; +} + +#endif /* BMP_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/rdcolmap.c b/src/dep/src/irrlicht/jpeglib/rdcolmap.c new file mode 100644 index 0000000..eebf834 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdcolmap.c @@ -0,0 +1,253 @@ +/* + * rdcolmap.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file implements djpeg's "-map file" switch. It reads a source image + * and constructs a colormap to be supplied to the JPEG decompressor. + * + * Currently, these file formats are supported for the map file: + * GIF: the contents of the GIF's global colormap are used. + * PPM (either text or raw flavor): the entire file is read and + * each unique pixel value is entered in the map. + * Note that reading a large PPM file will be horrendously slow. + * Typically, a PPM-format map file should contain just one pixel + * of each desired color. Such a file can be extracted from an + * ordinary image PPM file with ppmtomap(1). + * + * Rescaling a PPM that has a maxval unequal to MAXJSAMPLE is not + * currently implemented. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ + +/* Portions of this code are based on the PBMPLUS library, which is: +** +** Copyright (C) 1988 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +/* + * Add a (potentially) new color to the color map. + */ + +LOCAL(void) +add_map_entry (j_decompress_ptr cinfo, int R, int G, int B) +{ + JSAMPROW colormap0 = cinfo->colormap[0]; + JSAMPROW colormap1 = cinfo->colormap[1]; + JSAMPROW colormap2 = cinfo->colormap[2]; + int ncolors = cinfo->actual_number_of_colors; + int index; + + /* Check for duplicate color. */ + for (index = 0; index < ncolors; index++) { + if (GETJSAMPLE(colormap0[index]) == R && + GETJSAMPLE(colormap1[index]) == G && + GETJSAMPLE(colormap2[index]) == B) + return; /* color is already in map */ + } + + /* Check for map overflow. */ + if (ncolors >= (MAXJSAMPLE+1)) + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, (MAXJSAMPLE+1)); + + /* OK, add color to map. */ + colormap0[ncolors] = (JSAMPLE) R; + colormap1[ncolors] = (JSAMPLE) G; + colormap2[ncolors] = (JSAMPLE) B; + cinfo->actual_number_of_colors++; +} + + +/* + * Extract color map from a GIF file. + */ + +LOCAL(void) +read_gif_map (j_decompress_ptr cinfo, FILE * infile) +{ + int header[13]; + int i, colormaplen; + int R, G, B; + + /* Initial 'G' has already been read by read_color_map */ + /* Read the rest of the GIF header and logical screen descriptor */ + for (i = 1; i < 13; i++) { + if ((header[i] = getc(infile)) == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + } + + /* Verify GIF Header */ + if (header[1] != 'I' || header[2] != 'F') + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* There must be a global color map. */ + if ((header[10] & 0x80) == 0) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* OK, fetch it. */ + colormaplen = 2 << (header[10] & 0x07); + + for (i = 0; i < colormaplen; i++) { + R = getc(infile); + G = getc(infile); + B = getc(infile); + if (R == EOF || G == EOF || B == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + add_map_entry(cinfo, + R << (BITS_IN_JSAMPLE-8), + G << (BITS_IN_JSAMPLE-8), + B << (BITS_IN_JSAMPLE-8)); + } +} + + +/* Support routines for reading PPM */ + + +LOCAL(int) +pbm_getc (FILE * infile) +/* Read next char, skipping over any comments */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(infile); + if (ch == '#') { + do { + ch = getc(infile); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(unsigned int) +read_pbm_integer (j_decompress_ptr cinfo, FILE * infile) +/* Read an unsigned decimal integer from the PPM file */ +/* Swallows one trailing character after the integer */ +/* Note that on a 16-bit-int machine, only values up to 64k can be read. */ +/* This should not be a problem in practice. */ +{ + register int ch; + register unsigned int val; + + /* Skip any leading whitespace */ + do { + ch = pbm_getc(infile); + if (ch == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + + if (ch < '0' || ch > '9') + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + val = ch - '0'; + while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { + val *= 10; + val += ch - '0'; + } + return val; +} + + +/* + * Extract color map from a PPM file. + */ + +LOCAL(void) +read_ppm_map (j_decompress_ptr cinfo, FILE * infile) +{ + int c; + unsigned int w, h, maxval, row, col; + int R, G, B; + + /* Initial 'P' has already been read by read_color_map */ + c = getc(infile); /* save format discriminator for a sec */ + + /* while we fetch the remaining header info */ + w = read_pbm_integer(cinfo, infile); + h = read_pbm_integer(cinfo, infile); + maxval = read_pbm_integer(cinfo, infile); + + if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + /* For now, we don't support rescaling from an unusual maxval. */ + if (maxval != (unsigned int) MAXJSAMPLE) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + + switch (c) { + case '3': /* it's a text-format PPM file */ + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + R = read_pbm_integer(cinfo, infile); + G = read_pbm_integer(cinfo, infile); + B = read_pbm_integer(cinfo, infile); + add_map_entry(cinfo, R, G, B); + } + } + break; + + case '6': /* it's a raw-format PPM file */ + for (row = 0; row < h; row++) { + for (col = 0; col < w; col++) { + R = getc(infile); + G = getc(infile); + B = getc(infile); + if (R == EOF || G == EOF || B == EOF) + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + add_map_entry(cinfo, R, G, B); + } + } + break; + + default: + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + break; + } +} + + +/* + * Main entry point from djpeg.c. + * Input: opened input file (from file name argument on command line). + * Output: colormap and actual_number_of_colors fields are set in cinfo. + */ + +GLOBAL(void) +read_color_map (j_decompress_ptr cinfo, FILE * infile) +{ + /* Allocate space for a color map of maximum supported size. */ + cinfo->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (MAXJSAMPLE+1), (JDIMENSION) 3); + cinfo->actual_number_of_colors = 0; /* initialize map to empty */ + + /* Read first byte to determine file format */ + switch (getc(infile)) { + case 'G': + read_gif_map(cinfo, infile); + break; + case 'P': + read_ppm_map(cinfo, infile); + break; + default: + ERREXIT(cinfo, JERR_BAD_CMAP_FILE); + break; + } +} + +#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/rdgif.c b/src/dep/src/irrlicht/jpeglib/rdgif.c new file mode 100644 index 0000000..b0757e7 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdgif.c @@ -0,0 +1,38 @@ +/* + * rdgif.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in GIF format. + * + ***************************************************************************** + * NOTE: to avoid entanglements with Unisys' patent on LZW compression, * + * the ability to read GIF files has been removed from the IJG distribution. * + * Sorry about that. * + ***************************************************************************** + * + * We are required to state that + * "The Graphics Interchange Format(c) is the Copyright property of + * CompuServe Incorporated. GIF(sm) is a Service Mark property of + * CompuServe Incorporated." + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef GIF_SUPPORTED + +/* + * The module selection routine for GIF format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_gif (j_compress_ptr cinfo) +{ + fprintf(stderr, "GIF input is unsupported for legal reasons. Sorry.\n"); + exit(EXIT_FAILURE); + return NULL; /* keep compiler happy */ +} + +#endif /* GIF_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/rdjpgcom.1 b/src/dep/src/irrlicht/jpeglib/rdjpgcom.1 new file mode 100644 index 0000000..dd837a8 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdjpgcom.1 @@ -0,0 +1,54 @@ +.TH RDJPGCOM 1 "11 October 1997" +.SH NAME +rdjpgcom \- display text comments from a JPEG file +.SH SYNOPSIS +.B rdjpgcom +[ +.B \-verbose +] +[ +.I filename +] +.LP +.SH DESCRIPTION +.LP +.B rdjpgcom +reads the named JPEG/JFIF file, or the standard input if no file is named, +and prints any text comments found in the file on the standard output. +.PP +The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file. +Although the standard doesn't actually define what COM blocks are for, they +are widely used to hold user-supplied text strings. This lets you add +annotations, titles, index terms, etc to your JPEG files, and later retrieve +them as text. COM blocks do not interfere with the image stored in the JPEG +file. The maximum size of a COM block is 64K, but you can have as many of +them as you like in one JPEG file. +.SH OPTIONS +.TP +.B \-verbose +Causes +.B rdjpgcom +to also display the JPEG image dimensions. +.PP +Switch names may be abbreviated, and are not case sensitive. +.SH HINTS +.B rdjpgcom +does not depend on the IJG JPEG library. Its source code is intended as an +illustration of the minimum amount of code required to parse a JPEG file +header correctly. +.PP +In +.B \-verbose +mode, +.B rdjpgcom +will also attempt to print the contents of any "APP12" markers as text. +Some digital cameras produce APP12 markers containing useful textual +information. If you like, you can modify the source code to print +other APPn marker types as well. +.SH SEE ALSO +.BR cjpeg (1), +.BR djpeg (1), +.BR jpegtran (1), +.BR wrjpgcom (1) +.SH AUTHOR +Independent JPEG Group diff --git a/src/dep/src/irrlicht/jpeglib/rdjpgcom.c b/src/dep/src/irrlicht/jpeglib/rdjpgcom.c new file mode 100644 index 0000000..c8b94bb --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdjpgcom.c @@ -0,0 +1,496 @@ +/* + * rdjpgcom.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a very simple stand-alone application that displays + * the text in COM (comment) markers in a JFIF file. + * This may be useful as an example of the minimum logic needed to parse + * JPEG markers. + */ + +#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ +#include "jinclude.h" /* get auto-config symbols, */ + +#include /* to declare isupper(), tolower() */ +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif + + +/* + * These macros are used to read the input file. + * To reuse this code in another application, you might need to change these. + */ + +static FILE * infile; /* input JPEG file */ + +/* Return next input byte, or EOF if no more */ +#define NEXTBYTE() getc(infile) + + +/* Error exit handler */ +#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) + + +/* Read one byte, testing for EOF */ +static int +read_1_byte (void) +{ + int c; + + c = NEXTBYTE(); + if (c == EOF) + ERREXIT("Premature EOF in JPEG file"); + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static unsigned int +read_2_bytes (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + if (c1 == EOF) + ERREXIT("Premature EOF in JPEG file"); + c2 = NEXTBYTE(); + if (c2 == EOF) + ERREXIT("Premature EOF in JPEG file"); + return (((unsigned int) c1) << 8) + ((unsigned int) c2); +} + + +/* + * JPEG markers consist of one or more 0xFF bytes, followed by a marker + * code byte (which is not an FF). Here are the marker codes of interest + * in this program. (See jdmarker.c for a more complete list.) + */ + +#define M_SOF0 0xC0 /* Start Of Frame N */ +#define M_SOF1 0xC1 /* N indicates which compression process */ +#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ +#define M_EOI 0xD9 /* End Of Image (end of datastream) */ +#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ +#define M_APP0 0xE0 /* Application-specific marker, type N */ +#define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */ +#define M_COM 0xFE /* COMment */ + + +/* + * Find the next JPEG marker and return its marker code. + * We expect at least one FF byte, possibly more if the compressor used FFs + * to pad the file. + * There could also be non-FF garbage between markers. The treatment of such + * garbage is unspecified; we choose to skip over it but emit a warning msg. + * NB: this routine must not be used after seeing SOS marker, since it will + * not deal correctly with FF/00 sequences in the compressed image data... + */ + +static int +next_marker (void) +{ + int c; + int discarded_bytes = 0; + + /* Find 0xFF byte; count and skip any non-FFs. */ + c = read_1_byte(); + while (c != 0xFF) { + discarded_bytes++; + c = read_1_byte(); + } + /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs + * are legal as pad bytes, so don't count them in discarded_bytes. + */ + do { + c = read_1_byte(); + } while (c == 0xFF); + + if (discarded_bytes != 0) { + fprintf(stderr, "Warning: garbage data found in JPEG file\n"); + } + + return c; +} + + +/* + * Read the initial marker, which should be SOI. + * For a JFIF file, the first two bytes of the file should be literally + * 0xFF M_SOI. To be more general, we could use next_marker, but if the + * input file weren't actually JPEG at all, next_marker might read the whole + * file and then return a misleading error message... + */ + +static int +first_marker (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + c2 = NEXTBYTE(); + if (c1 != 0xFF || c2 != M_SOI) + ERREXIT("Not a JPEG file"); + return c2; +} + + +/* + * Most types of marker are followed by a variable-length parameter segment. + * This routine skips over the parameters for any marker we don't otherwise + * want to process. + * Note that we MUST skip the parameter segment explicitly in order not to + * be fooled by 0xFF bytes that might appear within the parameter segment; + * such bytes do NOT introduce new markers. + */ + +static void +skip_variable (void) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + (void) read_1_byte(); + length--; + } +} + + +/* + * Process a COM marker. + * We want to print out the marker contents as legible text; + * we must guard against non-text junk and varying newline representations. + */ + +static void +process_COM (void) +{ + unsigned int length; + int ch; + int lastch = 0; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + + while (length > 0) { + ch = read_1_byte(); + /* Emit the character in a readable form. + * Nonprintables are converted to \nnn form, + * while \ is converted to \\. + * Newlines in CR, CR/LF, or LF form will be printed as one newline. + */ + if (ch == '\r') { + printf("\n"); + } else if (ch == '\n') { + if (lastch != '\r') + printf("\n"); + } else if (ch == '\\') { + printf("\\\\"); + } else if (isprint(ch)) { + putc(ch, stdout); + } else { + printf("\\%03o", ch); + } + lastch = ch; + length--; + } + printf("\n"); +} + + +/* + * Process a SOFn marker. + * This code is only needed if you want to know the image dimensions... + */ + +static void +process_SOFn (int marker) +{ + unsigned int length; + unsigned int image_height, image_width; + int data_precision, num_components; + const char * process; + int ci; + + length = read_2_bytes(); /* usual parameter length count */ + + data_precision = read_1_byte(); + image_height = read_2_bytes(); + image_width = read_2_bytes(); + num_components = read_1_byte(); + + switch (marker) { + case M_SOF0: process = "Baseline"; break; + case M_SOF1: process = "Extended sequential"; break; + case M_SOF2: process = "Progressive"; break; + case M_SOF3: process = "Lossless"; break; + case M_SOF5: process = "Differential sequential"; break; + case M_SOF6: process = "Differential progressive"; break; + case M_SOF7: process = "Differential lossless"; break; + case M_SOF9: process = "Extended sequential, arithmetic coding"; break; + case M_SOF10: process = "Progressive, arithmetic coding"; break; + case M_SOF11: process = "Lossless, arithmetic coding"; break; + case M_SOF13: process = "Differential sequential, arithmetic coding"; break; + case M_SOF14: process = "Differential progressive, arithmetic coding"; break; + case M_SOF15: process = "Differential lossless, arithmetic coding"; break; + default: process = "Unknown"; break; + } + + printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n", + image_width, image_height, num_components, data_precision); + printf("JPEG process: %s\n", process); + + if (length != (unsigned int) (8 + num_components * 3)) + ERREXIT("Bogus SOF marker length"); + + for (ci = 0; ci < num_components; ci++) { + (void) read_1_byte(); /* Component ID code */ + (void) read_1_byte(); /* H, V sampling factors */ + (void) read_1_byte(); /* Quantization table number */ + } +} + + +/* + * Parse the marker stream until SOS or EOI is seen; + * display any COM markers. + * While the companion program wrjpgcom will always insert COM markers before + * SOFn, other implementations might not, so we scan to SOS before stopping. + * If we were only interested in the image dimensions, we would stop at SOFn. + * (Conversely, if we only cared about COM markers, there would be no need + * for special code to handle SOFn; we could treat it like other markers.) + */ + +static int +scan_JPEG_header (int verbose) +{ + int marker; + + /* Expect SOI at start of file */ + if (first_marker() != M_SOI) + ERREXIT("Expected SOI marker first"); + + /* Scan miscellaneous markers until we reach SOS. */ + for (;;) { + marker = next_marker(); + switch (marker) { + /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, + * treated as SOFn. C4 in particular is actually DHT. + */ + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + case M_SOF2: /* Progressive, Huffman */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_SOF9: /* Extended sequential, arithmetic */ + case M_SOF10: /* Progressive, arithmetic */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + if (verbose) + process_SOFn(marker); + else + skip_variable(); + break; + + case M_SOS: /* stop before hitting compressed data */ + return marker; + + case M_EOI: /* in case it's a tables-only JPEG stream */ + return marker; + + case M_COM: + process_COM(); + break; + + case M_APP12: + /* Some digital camera makers put useful textual information into + * APP12 markers, so we print those out too when in -verbose mode. + */ + if (verbose) { + printf("APP12 contains:\n"); + process_COM(); + } else + skip_variable(); + break; + + default: /* Anything else just gets skipped */ + skip_variable(); /* we assume it has a parameter count... */ + break; + } + } /* end loop */ +} + + +/* Command line parsing code */ + +static const char * progname; /* program name for error messages */ + + +static void +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "rdjpgcom displays any textual comments in a JPEG file.\n"); + + fprintf(stderr, "Usage: %s [switches] [inputfile]\n", progname); + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -verbose Also display dimensions of JPEG image\n"); + + exit(EXIT_FAILURE); +} + + +static int +keymatch (char * arg, const char * keyword, int minchars) +/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ +/* keyword is the constant keyword (must be lower case already), */ +/* minchars is length of minimum legal abbreviation. */ +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return 0; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return 0; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return 0; + return 1; /* A-OK */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + int argn; + char * arg; + int verbose = 0; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "rdjpgcom"; /* in case C library doesn't provide it */ + + /* Parse switches, if any */ + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (arg[0] != '-') + break; /* not switch, must be file name */ + arg++; /* advance over '-' */ + if (keymatch(arg, "verbose", 1)) { + verbose++; + } else + usage(); + } + + /* Open the input file. */ + /* Unix style: expect zero or one file name */ + if (argn < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } + if (argn < argc) { + if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdin\n", progname); + exit(EXIT_FAILURE); + } +#else + infile = stdin; +#endif + } + + /* Scan the JPEG headers. */ + (void) scan_JPEG_header(verbose); + + /* All done. */ + exit(EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/src/dep/src/irrlicht/jpeglib/rdppm.c b/src/dep/src/irrlicht/jpeglib/rdppm.c new file mode 100644 index 0000000..bec0bc0 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdppm.c @@ -0,0 +1,458 @@ +/* + * rdppm.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in PPM/PGM format. + * The extended 2-byte-per-sample raw PPM/PGM formats are supported. + * The PBMPLUS library is NOT required to compile this software + * (but it is highly useful as a set of PPM image manipulation programs). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed PPM format). + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef PPM_SUPPORTED + + +/* Portions of this code are based on the PBMPLUS library, which is: +** +** Copyright (C) 1988 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* + * On most systems, reading individual bytes with getc() is drastically less + * efficient than buffering a row at a time with fread(). On PCs, we must + * allocate the buffer in near data space, because we are assuming small-data + * memory model, wherein fread() can't reach far memory. If you need to + * process very wide images on a PC, you might have to compile in large-memory + * model, or else replace fread() with a getc() loop --- which will be much + * slower. + */ + + +/* Private version of data source object */ + +typedef struct { + struct cjpeg_source_struct pub; /* public fields */ + + U_CHAR *iobuffer; /* non-FAR pointer to I/O buffer */ + JSAMPROW pixrow; /* FAR pointer to same */ + size_t buffer_width; /* width of I/O buffer */ + JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ +} ppm_source_struct; + +typedef ppm_source_struct * ppm_source_ptr; + + +LOCAL(int) +pbm_getc (FILE * infile) +/* Read next char, skipping over any comments */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(infile); + if (ch == '#') { + do { + ch = getc(infile); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(unsigned int) +read_pbm_integer (j_compress_ptr cinfo, FILE * infile) +/* Read an unsigned decimal integer from the PPM file */ +/* Swallows one trailing character after the integer */ +/* Note that on a 16-bit-int machine, only values up to 64k can be read. */ +/* This should not be a problem in practice. */ +{ + register int ch; + register unsigned int val; + + /* Skip any leading whitespace */ + do { + ch = pbm_getc(infile); + if (ch == EOF) + ERREXIT(cinfo, JERR_INPUT_EOF); + } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + + if (ch < '0' || ch > '9') + ERREXIT(cinfo, JERR_PPM_NONNUMERIC); + + val = ch - '0'; + while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { + val *= 10; + val += ch - '0'; + } + return val; +} + + +/* + * Read one row of pixels. + * + * We provide several different versions depending on input file format. + * In all cases, input is scaled to the size of JSAMPLE. + * + * A really fast path is provided for reading byte/sample raw files with + * maxval = MAXJSAMPLE, which is the normal case for 8-bit data. + */ + + +METHODDEF(JDIMENSION) +get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading text-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + FILE * infile = source->pub.input_file; + register JSAMPROW ptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading text-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + FILE * infile = source->pub.input_file; + register JSAMPROW ptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[UCH(*bufferptr++)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + *ptr++ = rescale[UCH(*bufferptr++)]; + *ptr++ = rescale[UCH(*bufferptr++)]; + *ptr++ = rescale[UCH(*bufferptr++)]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-byte-format files with maxval = MAXJSAMPLE. + * In this case we just read right into the JSAMPLE buffer! + * Note that same code works for PPM and PGM files. + */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + return 1; +} + + +METHODDEF(JDIMENSION) +get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-word-format PGM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + register int temp; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + } + return 1; +} + + +METHODDEF(JDIMENSION) +get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading raw-word-format PPM files with any maxval */ +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + register JSAMPROW ptr; + register U_CHAR * bufferptr; + register JSAMPLE *rescale = source->rescale; + JDIMENSION col; + + if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) + ERREXIT(cinfo, JERR_INPUT_EOF); + ptr = source->pub.buffer[0]; + bufferptr = source->iobuffer; + for (col = cinfo->image_width; col > 0; col--) { + register int temp; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + temp = UCH(*bufferptr++); + temp |= UCH(*bufferptr++) << 8; + *ptr++ = rescale[temp]; + } + return 1; +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + ppm_source_ptr source = (ppm_source_ptr) sinfo; + int c; + unsigned int w, h, maxval; + boolean need_iobuffer, use_raw_buffer, need_rescale; + + if (getc(source->pub.input_file) != 'P') + ERREXIT(cinfo, JERR_PPM_NOT); + + c = getc(source->pub.input_file); /* subformat discriminator character */ + + /* detect unsupported variants (ie, PBM) before trying to read header */ + switch (c) { + case '2': /* it's a text-format PGM file */ + case '3': /* it's a text-format PPM file */ + case '5': /* it's a raw-format PGM file */ + case '6': /* it's a raw-format PPM file */ + break; + default: + ERREXIT(cinfo, JERR_PPM_NOT); + break; + } + + /* fetch the remaining header info */ + w = read_pbm_integer(cinfo, source->pub.input_file); + h = read_pbm_integer(cinfo, source->pub.input_file); + maxval = read_pbm_integer(cinfo, source->pub.input_file); + + if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ + ERREXIT(cinfo, JERR_PPM_NOT); + + cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ + cinfo->image_width = (JDIMENSION) w; + cinfo->image_height = (JDIMENSION) h; + + /* initialize flags to most common settings */ + need_iobuffer = TRUE; /* do we need an I/O buffer? */ + use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ + need_rescale = TRUE; /* do we need a rescale array? */ + + switch (c) { + case '2': /* it's a text-format PGM file */ + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); + source->pub.get_pixel_rows = get_text_gray_row; + need_iobuffer = FALSE; + break; + + case '3': /* it's a text-format PPM file */ + cinfo->input_components = 3; + cinfo->in_color_space = JCS_RGB; + TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); + source->pub.get_pixel_rows = get_text_rgb_row; + need_iobuffer = FALSE; + break; + + case '5': /* it's a raw-format PGM file */ + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_PGM, w, h); + if (maxval > 255) { + source->pub.get_pixel_rows = get_word_gray_row; + } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { + source->pub.get_pixel_rows = get_raw_row; + use_raw_buffer = TRUE; + need_rescale = FALSE; + } else { + source->pub.get_pixel_rows = get_scaled_gray_row; + } + break; + + case '6': /* it's a raw-format PPM file */ + cinfo->input_components = 3; + cinfo->in_color_space = JCS_RGB; + TRACEMS2(cinfo, 1, JTRC_PPM, w, h); + if (maxval > 255) { + source->pub.get_pixel_rows = get_word_rgb_row; + } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { + source->pub.get_pixel_rows = get_raw_row; + use_raw_buffer = TRUE; + need_rescale = FALSE; + } else { + source->pub.get_pixel_rows = get_scaled_rgb_row; + } + break; + } + + /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ + if (need_iobuffer) { + source->buffer_width = (size_t) w * cinfo->input_components * + ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR))); + source->iobuffer = (U_CHAR *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + source->buffer_width); + } + + /* Create compressor input buffer. */ + if (use_raw_buffer) { + /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ + /* Synthesize a JSAMPARRAY pointer structure */ + /* Cast here implies near->far pointer conversion on PCs */ + source->pixrow = (JSAMPROW) source->iobuffer; + source->pub.buffer = & source->pixrow; + source->pub.buffer_height = 1; + } else { + /* Need to translate anyway, so make a separate sample buffer. */ + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); + source->pub.buffer_height = 1; + } + + /* Compute the rescaling array if required. */ + if (need_rescale) { + INT32 val, half_maxval; + + /* On 16-bit-int machines we have to be careful of maxval = 65535 */ + source->rescale = (JSAMPLE *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE))); + half_maxval = maxval / 2; + for (val = 0; val <= (INT32) maxval; val++) { + /* The multiplication here must be done in 32 bits to avoid overflow */ + source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); + } + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for PPM format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_ppm (j_compress_ptr cinfo) +{ + ppm_source_ptr source; + + /* Create module interface object */ + source = (ppm_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ppm_source_struct)); + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_ppm; + source->pub.finish_input = finish_input_ppm; + + return (cjpeg_source_ptr) source; +} + +#endif /* PPM_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/rdrle.c b/src/dep/src/irrlicht/jpeglib/rdrle.c new file mode 100644 index 0000000..df871e0 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdrle.c @@ -0,0 +1,387 @@ +/* + * rdrle.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Utah RLE format. + * The Utah Raster Toolkit library is required (version 3.1 or later). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed RLE format). + * + * Based on code contributed by Mike Lijewski, + * with updates from Robert Hutchinson. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef RLE_SUPPORTED + +/* rle.h is provided by the Utah Raster Toolkit. */ + +#include + +/* + * We assume that JSAMPLE has the same representation as rle_pixel, + * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * We support the following types of RLE files: + * + * GRAYSCALE - 8 bits, no colormap + * MAPPEDGRAY - 8 bits, 1 channel colomap + * PSEUDOCOLOR - 8 bits, 3 channel colormap + * TRUECOLOR - 24 bits, 3 channel colormap + * DIRECTCOLOR - 24 bits, no colormap + * + * For now, we ignore any alpha channel in the image. + */ + +typedef enum + { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; + + +/* + * Since RLE stores scanlines bottom-to-top, we have to invert the image + * to conform to JPEG's top-to-bottom order. To do this, we read the + * incoming image into a virtual array on the first get_pixel_rows call, + * then fetch the required row from the virtual array on subsequent calls. + */ + +typedef struct _rle_source_struct * rle_source_ptr; + +typedef struct _rle_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + rle_kind visual; /* actual type of input file */ + jvirt_sarray_ptr image; /* virtual array to hold the image */ + JDIMENSION row; /* current row # in the virtual array */ + rle_hdr header; /* Input file information */ + rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ + +} rle_source_struct; + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JDIMENSION width, height; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* Use RLE library routine to get the header info */ + source->header = *rle_hdr_init(NULL); + source->header.rle_file = source->pub.input_file; + switch (rle_get_setup(&(source->header))) { + case RLE_SUCCESS: + /* A-OK */ + break; + case RLE_NOT_RLE: + ERREXIT(cinfo, JERR_RLE_NOT); + break; + case RLE_NO_SPACE: + ERREXIT(cinfo, JERR_RLE_MEM); + break; + case RLE_EMPTY: + ERREXIT(cinfo, JERR_RLE_EMPTY); + break; + case RLE_EOF: + ERREXIT(cinfo, JERR_RLE_EOF); + break; + default: + ERREXIT(cinfo, JERR_RLE_BADERROR); + break; + } + + /* Figure out what we have, set private vars and return values accordingly */ + + width = source->header.xmax - source->header.xmin + 1; + height = source->header.ymax - source->header.ymin + 1; + source->header.xmin = 0; /* realign horizontally */ + source->header.xmax = width-1; + + cinfo->image_width = width; + cinfo->image_height = height; + cinfo->data_precision = 8; /* we can only handle 8 bit data */ + + if (source->header.ncolors == 1 && source->header.ncmap == 0) { + source->visual = GRAYSCALE; + TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); + } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { + source->visual = MAPPEDGRAY; + TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { + source->visual = PSEUDOCOLOR; + TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { + source->visual = TRUECOLOR; + TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, + 1 << source->header.cmaplen); + } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { + source->visual = DIRECTCOLOR; + TRACEMS2(cinfo, 1, JTRC_RLE, width, height); + } else + ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); + + if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { + cinfo->in_color_space = JCS_GRAYSCALE; + cinfo->input_components = 1; + } else { + cinfo->in_color_space = JCS_RGB; + cinfo->input_components = 3; + } + + /* + * A place to hold each scanline while it's converted. + * (GRAYSCALE scanlines don't need converting) + */ + if (source->visual != GRAYSCALE) { + source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) width, (JDIMENSION) cinfo->input_components); + } + + /* request a virtual array to hold the image */ + source->image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) (width * source->header.ncolors), + (JDIMENSION) height, (JDIMENSION) 1); + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + /* count file input as separate pass */ + progress->total_extra_passes++; + } +#endif + + source->pub.buffer_height = 1; +} + + +/* + * Read one row of pixels. + * Called only after load_image has read the image into the virtual array. + * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images. + */ + +METHODDEF(JDIMENSION) +get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + + source->row--; + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); + + return 1; +} + +/* + * Read one row of pixels. + * Called only after load_image has read the image into the virtual array. + * Used for PSEUDOCOLOR images. + */ + +METHODDEF(JDIMENSION) +get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JSAMPROW src_row, dest_row; + JDIMENSION col; + rle_map *colormap; + int val; + + colormap = source->header.cmap; + dest_row = source->pub.buffer[0]; + source->row--; + src_row = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); + + for (col = cinfo->image_width; col > 0; col--) { + val = GETJSAMPLE(*src_row++); + *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); + *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); + *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); + } + + return 1; +} + + +/* + * Load the image into a virtual array. We have to do this because RLE + * files start at the lower left while the JPEG standard has them starting + * in the upper left. This is called the first time we want to get a row + * of input. What we do is load the RLE data into the array and then call + * the appropriate routine to read one row from the array. Before returning, + * we set source->pub.get_pixel_rows so that subsequent calls go straight to + * the appropriate row-reading routine. + */ + +METHODDEF(JDIMENSION) +load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + rle_source_ptr source = (rle_source_ptr) sinfo; + JDIMENSION row, col; + JSAMPROW scanline, red_ptr, green_ptr, blue_ptr; + rle_pixel **rle_row; + rle_map *colormap; + char channel; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + colormap = source->header.cmap; + rle_row = source->rle_row; + + /* Read the RLE data into our virtual array. + * We assume here that (a) rle_pixel is represented the same as JSAMPLE, + * and (b) we are not on a machine where FAR pointers differ from regular. + */ + RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_limit = cinfo->image_height; + progress->pub.pass_counter = 0; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + + switch (source->visual) { + + case GRAYSCALE: + case PSEUDOCOLOR: + for (row = 0; row < cinfo->image_height; row++) { + rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_getrow(&source->header, rle_row); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + break; + + case MAPPEDGRAY: + case TRUECOLOR: + for (row = 0; row < cinfo->image_height; row++) { + scanline = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_row = source->rle_row; + rle_getrow(&source->header, rle_row); + + for (col = 0; col < cinfo->image_width; col++) { + for (channel = 0; channel < source->header.ncolors; channel++) { + *scanline++ = (JSAMPLE) + (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + break; + + case DIRECTCOLOR: + for (row = 0; row < cinfo->image_height; row++) { + scanline = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); + rle_getrow(&source->header, rle_row); + + red_ptr = rle_row[0]; + green_ptr = rle_row[1]; + blue_ptr = rle_row[2]; + + for (col = cinfo->image_width; col > 0; col--) { + *scanline++ = *red_ptr++; + *scanline++ = *green_ptr++; + *scanline++ = *blue_ptr++; + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) + progress->completed_extra_passes++; +#endif + + /* Set up to call proper row-extraction routine in future */ + if (source->visual == PSEUDOCOLOR) { + source->pub.buffer = source->rle_row; + source->pub.get_pixel_rows = get_pseudocolor_row; + } else { + source->pub.get_pixel_rows = get_rle_row; + } + source->row = cinfo->image_height; + + /* And fetch the topmost (bottommost) row */ + return (*source->pub.get_pixel_rows) (cinfo, sinfo); +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for RLE format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_rle (j_compress_ptr cinfo) +{ + rle_source_ptr source; + + /* Create module interface object */ + source = (rle_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(rle_source_struct)); + /* Fill in method ptrs */ + source->pub.start_input = start_input_rle; + source->pub.finish_input = finish_input_rle; + source->pub.get_pixel_rows = load_image; + + return (cjpeg_source_ptr) source; +} + +#endif /* RLE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/rdswitch.c b/src/dep/src/irrlicht/jpeglib/rdswitch.c new file mode 100644 index 0000000..b915ad9 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdswitch.c @@ -0,0 +1,332 @@ +/* + * rdswitch.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to process some of cjpeg's more complicated + * command-line switches. Switches processed here are: + * -qtables file Read quantization tables from text file + * -scans file Read scan script from text file + * -qslots N[,N,...] Set component quantization table selectors + * -sample HxV[,HxV,...] Set component sampling factors + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ +#include /* to declare isdigit(), isspace() */ + + +LOCAL(int) +text_getc (FILE * file) +/* Read next char, skipping over any comments (# to end of line) */ +/* A comment/newline sequence is returned as a newline */ +{ + register int ch; + + ch = getc(file); + if (ch == '#') { + do { + ch = getc(file); + } while (ch != '\n' && ch != EOF); + } + return ch; +} + + +LOCAL(boolean) +read_text_integer (FILE * file, long * result, int * termchar) +/* Read an unsigned decimal integer from a file, store it in result */ +/* Reads one trailing character after the integer; returns it in termchar */ +{ + register int ch; + register long val; + + /* Skip any leading whitespace, detect EOF */ + do { + ch = text_getc(file); + if (ch == EOF) { + *termchar = ch; + return FALSE; + } + } while (isspace(ch)); + + if (! isdigit(ch)) { + *termchar = ch; + return FALSE; + } + + val = ch - '0'; + while ((ch = text_getc(file)) != EOF) { + if (! isdigit(ch)) + break; + val *= 10; + val += ch - '0'; + } + *result = val; + *termchar = ch; + return TRUE; +} + + +GLOBAL(boolean) +read_quant_tables (j_compress_ptr cinfo, char * filename, + int scale_factor, boolean force_baseline) +/* Read a set of quantization tables from the specified file. + * The file is plain ASCII text: decimal numbers with whitespace between. + * Comments preceded by '#' may be included in the file. + * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values. + * The tables are implicitly numbered 0,1,etc. + * NOTE: does not affect the qslots mapping, which will default to selecting + * table 0 for luminance (or primary) components, 1 for chrominance components. + * You must use -qslots if you want a different component->table mapping. + */ +{ + FILE * fp; + int tblno, i, termchar; + long val; + unsigned int table[DCTSIZE2]; + + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Can't open table file %s\n", filename); + return FALSE; + } + tblno = 0; + + while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */ + if (tblno >= NUM_QUANT_TBLS) { + fprintf(stderr, "Too many tables in file %s\n", filename); + fclose(fp); + return FALSE; + } + table[0] = (unsigned int) val; + for (i = 1; i < DCTSIZE2; i++) { + if (! read_text_integer(fp, &val, &termchar)) { + fprintf(stderr, "Invalid table data in file %s\n", filename); + fclose(fp); + return FALSE; + } + table[i] = (unsigned int) val; + } + jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline); + tblno++; + } + + if (termchar != EOF) { + fprintf(stderr, "Non-numeric data in file %s\n", filename); + fclose(fp); + return FALSE; + } + + fclose(fp); + return TRUE; +} + + +#ifdef C_MULTISCAN_FILES_SUPPORTED + +LOCAL(boolean) +read_scan_integer (FILE * file, long * result, int * termchar) +/* Variant of read_text_integer that always looks for a non-space termchar; + * this simplifies parsing of punctuation in scan scripts. + */ +{ + register int ch; + + if (! read_text_integer(file, result, termchar)) + return FALSE; + ch = *termchar; + while (ch != EOF && isspace(ch)) + ch = text_getc(file); + if (isdigit(ch)) { /* oops, put it back */ + if (ungetc(ch, file) == EOF) + return FALSE; + ch = ' '; + } else { + /* Any separators other than ';' and ':' are ignored; + * this allows user to insert commas, etc, if desired. + */ + if (ch != EOF && ch != ';' && ch != ':') + ch = ' '; + } + *termchar = ch; + return TRUE; +} + + +GLOBAL(boolean) +read_scan_script (j_compress_ptr cinfo, char * filename) +/* Read a scan script from the specified text file. + * Each entry in the file defines one scan to be emitted. + * Entries are separated by semicolons ';'. + * An entry contains one to four component indexes, + * optionally followed by a colon ':' and four progressive-JPEG parameters. + * The component indexes denote which component(s) are to be transmitted + * in the current scan. The first component has index 0. + * Sequential JPEG is used if the progressive-JPEG parameters are omitted. + * The file is free format text: any whitespace may appear between numbers + * and the ':' and ';' punctuation marks. Also, other punctuation (such + * as commas or dashes) can be placed between numbers if desired. + * Comments preceded by '#' may be included in the file. + * Note: we do very little validity checking here; + * jcmaster.c will validate the script parameters. + */ +{ + FILE * fp; + int scanno, ncomps, termchar; + long val; + jpeg_scan_info * scanptr; +#define MAX_SCANS 100 /* quite arbitrary limit */ + jpeg_scan_info scans[MAX_SCANS]; + + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Can't open scan definition file %s\n", filename); + return FALSE; + } + scanptr = scans; + scanno = 0; + + while (read_scan_integer(fp, &val, &termchar)) { + if (scanno >= MAX_SCANS) { + fprintf(stderr, "Too many scans defined in file %s\n", filename); + fclose(fp); + return FALSE; + } + scanptr->component_index[0] = (int) val; + ncomps = 1; + while (termchar == ' ') { + if (ncomps >= MAX_COMPS_IN_SCAN) { + fprintf(stderr, "Too many components in one scan in file %s\n", + filename); + fclose(fp); + return FALSE; + } + if (! read_scan_integer(fp, &val, &termchar)) + goto bogus; + scanptr->component_index[ncomps] = (int) val; + ncomps++; + } + scanptr->comps_in_scan = ncomps; + if (termchar == ':') { + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Ss = (int) val; + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Se = (int) val; + if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + goto bogus; + scanptr->Ah = (int) val; + if (! read_scan_integer(fp, &val, &termchar)) + goto bogus; + scanptr->Al = (int) val; + } else { + /* set non-progressive parameters */ + scanptr->Ss = 0; + scanptr->Se = DCTSIZE2-1; + scanptr->Ah = 0; + scanptr->Al = 0; + } + if (termchar != ';' && termchar != EOF) { +bogus: + fprintf(stderr, "Invalid scan entry format in file %s\n", filename); + fclose(fp); + return FALSE; + } + scanptr++, scanno++; + } + + if (termchar != EOF) { + fprintf(stderr, "Non-numeric data in file %s\n", filename); + fclose(fp); + return FALSE; + } + + if (scanno > 0) { + /* Stash completed scan list in cinfo structure. + * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data, + * but if you want to compress multiple images you'd want JPOOL_PERMANENT. + */ + scanptr = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + scanno * SIZEOF(jpeg_scan_info)); + MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info)); + cinfo->scan_info = scanptr; + cinfo->num_scans = scanno; + } + + fclose(fp); + return TRUE; +} + +#endif /* C_MULTISCAN_FILES_SUPPORTED */ + + +GLOBAL(boolean) +set_quant_slots (j_compress_ptr cinfo, char *arg) +/* Process a quantization-table-selectors parameter string, of the form + * N[,N,...] + * If there are more components than parameters, the last value is replicated. + */ +{ + int val = 0; /* default table # */ + int ci; + char ch; + + for (ci = 0; ci < MAX_COMPONENTS; ci++) { + if (*arg) { + ch = ','; /* if not set by sscanf, will be ',' */ + if (sscanf(arg, "%d%c", &val, &ch) < 1) + return FALSE; + if (ch != ',') /* syntax check */ + return FALSE; + if (val < 0 || val >= NUM_QUANT_TBLS) { + fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n", + NUM_QUANT_TBLS-1); + return FALSE; + } + cinfo->comp_info[ci].quant_tbl_no = val; + while (*arg && *arg++ != ',') /* advance to next segment of arg string */ + ; + } else { + /* reached end of parameter, set remaining components to last table */ + cinfo->comp_info[ci].quant_tbl_no = val; + } + } + return TRUE; +} + + +GLOBAL(boolean) +set_sample_factors (j_compress_ptr cinfo, char *arg) +/* Process a sample-factors parameter string, of the form + * HxV[,HxV,...] + * If there are more components than parameters, "1x1" is assumed for the rest. + */ +{ + int ci, val1, val2; + char ch1, ch2; + + for (ci = 0; ci < MAX_COMPONENTS; ci++) { + if (*arg) { + ch2 = ','; /* if not set by sscanf, will be ',' */ + if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3) + return FALSE; + if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */ + return FALSE; + if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) { + fprintf(stderr, "JPEG sampling factors must be 1..4\n"); + return FALSE; + } + cinfo->comp_info[ci].h_samp_factor = val1; + cinfo->comp_info[ci].v_samp_factor = val2; + while (*arg && *arg++ != ',') /* advance to next segment of arg string */ + ; + } else { + /* reached end of parameter, set remaining components to 1x1 sampling */ + cinfo->comp_info[ci].h_samp_factor = 1; + cinfo->comp_info[ci].v_samp_factor = 1; + } + } + return TRUE; +} diff --git a/src/dep/src/irrlicht/jpeglib/rdtarga.c b/src/dep/src/irrlicht/jpeglib/rdtarga.c new file mode 100644 index 0000000..d7ffc33 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/rdtarga.c @@ -0,0 +1,500 @@ +/* + * rdtarga.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to read input images in Targa format. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume input from + * an ordinary stdio stream. They further assume that reading begins + * at the start of the file; start_input may need work if the + * user interface has already read some data (e.g., to determine that + * the file is indeed Targa format). + * + * Based on code contributed by Lee Daniel Crocker. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef TARGA_SUPPORTED + + +/* Macros to deal with unsigned chars as efficiently as compiler allows */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char U_CHAR; +#define UCH(x) ((int) (x)) +#else /* !HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char U_CHAR; +#define UCH(x) ((int) (x)) +#else +typedef char U_CHAR; +#define UCH(x) ((int) (x) & 0xFF) +#endif +#endif /* HAVE_UNSIGNED_CHAR */ + + +#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) + + +/* Private version of data source object */ + +typedef struct _tga_source_struct * tga_source_ptr; + +typedef struct _tga_source_struct { + struct cjpeg_source_struct pub; /* public fields */ + + j_compress_ptr cinfo; /* back link saves passing separate parm */ + + JSAMPARRAY colormap; /* Targa colormap (converted to my format) */ + + jvirt_sarray_ptr whole_image; /* Needed if funny input row order */ + JDIMENSION current_row; /* Current logical row number to read */ + + /* Pointer to routine to extract next Targa pixel from input file */ + JMETHOD(void, read_pixel, (tga_source_ptr sinfo)); + + /* Result of read_pixel is delivered here: */ + U_CHAR tga_pixel[4]; + + int pixel_size; /* Bytes per Targa pixel (1 to 4) */ + + /* State info for reading RLE-coded pixels; both counts must be init to 0 */ + int block_count; /* # of pixels remaining in RLE block */ + int dup_pixel_count; /* # of times to duplicate previous pixel */ + + /* This saves the correct pixel-row-expansion method for preload_image */ + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); +} tga_source_struct; + + +/* For expanding 5-bit pixel values to 8-bit with best rounding */ + +static const UINT8 c5to8bits[32] = { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 +}; + + + +LOCAL(int) +read_byte (tga_source_ptr sinfo) +/* Read next byte from Targa file */ +{ + register FILE *infile = sinfo->pub.input_file; + register int c; + + if ((c = getc(infile)) == EOF) + ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); + return c; +} + + +LOCAL(void) +read_colormap (tga_source_ptr sinfo, int cmaplen, int mapentrysize) +/* Read the colormap from a Targa file */ +{ + int i; + + /* Presently only handles 24-bit BGR format */ + if (mapentrysize != 24) + ERREXIT(sinfo->cinfo, JERR_TGA_BADCMAP); + + for (i = 0; i < cmaplen; i++) { + sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); + sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); + } +} + + +/* + * read_pixel methods: get a single pixel from Targa file into tga_pixel[] + */ + +METHODDEF(void) +read_non_rle_pixel (tga_source_ptr sinfo) +/* Read one Targa pixel from the input file; no RLE expansion */ +{ + register FILE *infile = sinfo->pub.input_file; + register int i; + + for (i = 0; i < sinfo->pixel_size; i++) { + sinfo->tga_pixel[i] = (U_CHAR) getc(infile); + } +} + + +METHODDEF(void) +read_rle_pixel (tga_source_ptr sinfo) +/* Read one Targa pixel from the input file, expanding RLE data as needed */ +{ + register FILE *infile = sinfo->pub.input_file; + register int i; + + /* Duplicate previously read pixel? */ + if (sinfo->dup_pixel_count > 0) { + sinfo->dup_pixel_count--; + return; + } + + /* Time to read RLE block header? */ + if (--sinfo->block_count < 0) { /* decrement pixels remaining in block */ + i = read_byte(sinfo); + if (i & 0x80) { /* Start of duplicate-pixel block? */ + sinfo->dup_pixel_count = i & 0x7F; /* number of dups after this one */ + sinfo->block_count = 0; /* then read new block header */ + } else { + sinfo->block_count = i & 0x7F; /* number of pixels after this one */ + } + } + + /* Read next pixel */ + for (i = 0; i < sinfo->pixel_size; i++) { + sinfo->tga_pixel[i] = (U_CHAR) getc(infile); + } +} + + +/* + * Read one row of pixels. + * + * We provide several different versions depending on input file format. + */ + + +METHODDEF(JDIMENSION) +get_8bit_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit grayscale pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]); + } + return 1; +} + +METHODDEF(JDIMENSION) +get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 8-bit colormap indexes */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register int t; + register JSAMPROW ptr; + register JDIMENSION col; + register JSAMPARRAY colormap = source->colormap; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + t = UCH(source->tga_pixel[0]); + *ptr++ = colormap[0][t]; + *ptr++ = colormap[1][t]; + *ptr++ = colormap[2][t]; + } + return 1; +} + +METHODDEF(JDIMENSION) +get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 16-bit pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register int t; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + t = UCH(source->tga_pixel[0]); + t += UCH(source->tga_pixel[1]) << 8; + /* We expand 5 bit data to 8 bit sample width. + * The format of the 16-bit (LSB first) input word is + * xRRRRRGGGGGBBBBB + */ + ptr[2] = (JSAMPLE) c5to8bits[t & 0x1F]; + t >>= 5; + ptr[1] = (JSAMPLE) c5to8bits[t & 0x1F]; + t >>= 5; + ptr[0] = (JSAMPLE) c5to8bits[t & 0x1F]; + ptr += 3; + } + return 1; +} + +METHODDEF(JDIMENSION) +get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +/* This version is for reading 24-bit pixels */ +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = source->pub.buffer[0]; + for (col = cinfo->image_width; col > 0; col--) { + (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[2]); /* change BGR to RGB order */ + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[1]); + *ptr++ = (JSAMPLE) UCH(source->tga_pixel[0]); + } + return 1; +} + +/* + * Targa also defines a 32-bit pixel format with order B,G,R,A. + * We presently ignore the attribute byte, so the code for reading + * these pixels is identical to the 24-bit routine above. + * This works because the actual pixel length is only known to read_pixel. + */ + +#define get_32bit_row get_24bit_row + + +/* + * This method is for re-reading the input data in standard top-down + * row order. The entire image has already been read into whole_image + * with proper conversion of pixel format, but it's in a funny row order. + */ + +METHODDEF(JDIMENSION) +get_memory_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + JDIMENSION source_row; + + /* Compute row of source that maps to current_row of normal order */ + /* For now, assume image is bottom-up and not interlaced. */ + /* NEEDS WORK to support interlaced images! */ + source_row = cinfo->image_height - source->current_row - 1; + + /* Fetch that row from virtual array */ + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, + source_row, (JDIMENSION) 1, FALSE); + + source->current_row++; + return 1; +} + + +/* + * This method loads the image into whole_image during the first call on + * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call + * get_memory_row on subsequent calls. + */ + +METHODDEF(JDIMENSION) +preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + JDIMENSION row; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Read the data into a virtual array in input-file row order. */ + for (row = 0; row < cinfo->image_height; row++) { + if (progress != NULL) { + progress->pub.pass_counter = (long) row; + progress->pub.pass_limit = (long) cinfo->image_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + source->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, source->whole_image, row, (JDIMENSION) 1, TRUE); + (*source->get_pixel_rows) (cinfo, sinfo); + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Set up to read from the virtual array in unscrambled order */ + source->pub.get_pixel_rows = get_memory_row; + source->current_row = 0; + /* And read the first row */ + return get_memory_row(cinfo, sinfo); +} + + +/* + * Read the file header; return image size and component count. + */ + +METHODDEF(void) +start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + tga_source_ptr source = (tga_source_ptr) sinfo; + U_CHAR targaheader[18]; + int idlen, cmaptype, subtype, flags, interlace_type, components; + unsigned int width, height, maplen; + boolean is_bottom_up; + +#define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \ + (((unsigned int) UCH(targaheader[offset+1])) << 8)) + + if (! ReadOK(source->pub.input_file, targaheader, 18)) + ERREXIT(cinfo, JERR_INPUT_EOF); + + /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */ + if (targaheader[16] == 15) + targaheader[16] = 16; + + idlen = UCH(targaheader[0]); + cmaptype = UCH(targaheader[1]); + subtype = UCH(targaheader[2]); + maplen = GET_2B(5); + width = GET_2B(12); + height = GET_2B(14); + source->pixel_size = UCH(targaheader[16]) >> 3; + flags = UCH(targaheader[17]); /* Image Descriptor byte */ + + is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */ + interlace_type = flags >> 6; /* bits 6/7 are interlace code */ + + if (cmaptype > 1 || /* cmaptype must be 0 or 1 */ + source->pixel_size < 1 || source->pixel_size > 4 || + (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */ + interlace_type != 0) /* currently don't allow interlaced image */ + ERREXIT(cinfo, JERR_TGA_BADPARMS); + + if (subtype > 8) { + /* It's an RLE-coded file */ + source->read_pixel = read_rle_pixel; + source->block_count = source->dup_pixel_count = 0; + subtype -= 8; + } else { + /* Non-RLE file */ + source->read_pixel = read_non_rle_pixel; + } + + /* Now should have subtype 1, 2, or 3 */ + components = 3; /* until proven different */ + cinfo->in_color_space = JCS_RGB; + + switch (subtype) { + case 1: /* Colormapped image */ + if (source->pixel_size == 1 && cmaptype == 1) + source->get_pixel_rows = get_8bit_row; + else + ERREXIT(cinfo, JERR_TGA_BADPARMS); + TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height); + break; + case 2: /* RGB image */ + switch (source->pixel_size) { + case 2: + source->get_pixel_rows = get_16bit_row; + break; + case 3: + source->get_pixel_rows = get_24bit_row; + break; + case 4: + source->get_pixel_rows = get_32bit_row; + break; + default: + ERREXIT(cinfo, JERR_TGA_BADPARMS); + break; + } + TRACEMS2(cinfo, 1, JTRC_TGA, width, height); + break; + case 3: /* Grayscale image */ + components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + if (source->pixel_size == 1) + source->get_pixel_rows = get_8bit_gray_row; + else + ERREXIT(cinfo, JERR_TGA_BADPARMS); + TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height); + break; + default: + ERREXIT(cinfo, JERR_TGA_BADPARMS); + break; + } + + if (is_bottom_up) { + /* Create a virtual array to buffer the upside-down image. */ + source->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) width * components, (JDIMENSION) height, (JDIMENSION) 1); + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + /* source->pub.buffer will point to the virtual array. */ + source->pub.buffer_height = 1; /* in case anyone looks at it */ + source->pub.get_pixel_rows = preload_image; + } else { + /* Don't need a virtual array, but do need a one-row input buffer. */ + source->whole_image = NULL; + source->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) width * components, (JDIMENSION) 1); + source->pub.buffer_height = 1; + source->pub.get_pixel_rows = source->get_pixel_rows; + } + + while (idlen--) /* Throw away ID field */ + (void) read_byte(source); + + if (maplen > 0) { + if (maplen > 256 || GET_2B(3) != 0) + ERREXIT(cinfo, JERR_TGA_BADCMAP); + /* Allocate space to store the colormap */ + source->colormap = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3); + /* and read it from the file */ + read_colormap(source, (int) maplen, UCH(targaheader[7])); + } else { + if (cmaptype) /* but you promised a cmap! */ + ERREXIT(cinfo, JERR_TGA_BADPARMS); + source->colormap = NULL; + } + + cinfo->input_components = components; + cinfo->data_precision = 8; + cinfo->image_width = width; + cinfo->image_height = height; +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) +{ + /* no work */ +} + + +/* + * The module selection routine for Targa format input. + */ + +GLOBAL(cjpeg_source_ptr) +jinit_read_targa (j_compress_ptr cinfo) +{ + tga_source_ptr source; + + /* Create module interface object */ + source = (tga_source_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(tga_source_struct)); + source->cinfo = cinfo; /* make back link for subroutines */ + /* Fill in method ptrs, except get_pixel_rows which start_input sets */ + source->pub.start_input = start_input_tga; + source->pub.finish_input = finish_input_tga; + + return (cjpeg_source_ptr) source; +} + +#endif /* TARGA_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/structure.doc b/src/dep/src/irrlicht/jpeglib/structure.doc new file mode 100644 index 0000000..4179e48 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/structure.doc @@ -0,0 +1,948 @@ +IJG JPEG LIBRARY: SYSTEM ARCHITECTURE + +Copyright (C) 1991-1995, Thomas G. Lane. +This file is part of the Independent JPEG Group's software. +For conditions of distribution and use, see the accompanying README file. + + +This file provides an overview of the architecture of the IJG JPEG software; +that is, the functions of the various modules in the system and the interfaces +between modules. For more precise details about any data structure or calling +convention, see the include files and comments in the source code. + +We assume that the reader is already somewhat familiar with the JPEG standard. +The README file includes references for learning about JPEG. The file +libjpeg.doc describes the library from the viewpoint of an application +programmer using the library; it's best to read that file before this one. +Also, the file coderules.doc describes the coding style conventions we use. + +In this document, JPEG-specific terminology follows the JPEG standard: + A "component" means a color channel, e.g., Red or Luminance. + A "sample" is a single component value (i.e., one number in the image data). + A "coefficient" is a frequency coefficient (a DCT transform output number). + A "block" is an 8x8 group of samples or coefficients. + An "MCU" (minimum coded unit) is an interleaved set of blocks of size + determined by the sampling factors, or a single block in a + noninterleaved scan. +We do not use the terms "pixel" and "sample" interchangeably. When we say +pixel, we mean an element of the full-size image, while a sample is an element +of the downsampled image. Thus the number of samples may vary across +components while the number of pixels does not. (This terminology is not used +rigorously throughout the code, but it is used in places where confusion would +otherwise result.) + + +*** System features *** + +The IJG distribution contains two parts: + * A subroutine library for JPEG compression and decompression. + * cjpeg/djpeg, two sample applications that use the library to transform + JFIF JPEG files to and from several other image formats. +cjpeg/djpeg are of no great intellectual complexity: they merely add a simple +command-line user interface and I/O routines for several uncompressed image +formats. This document concentrates on the library itself. + +We desire the library to be capable of supporting all JPEG baseline, extended +sequential, and progressive DCT processes. Hierarchical processes are not +supported. + +The library does not support the lossless (spatial) JPEG process. Lossless +JPEG shares little or no code with lossy JPEG, and would normally be used +without the extensive pre- and post-processing provided by this library. +We feel that lossless JPEG is better handled by a separate library. + +Within these limits, any set of compression parameters allowed by the JPEG +spec should be readable for decompression. (We can be more restrictive about +what formats we can generate.) Although the system design allows for all +parameter values, some uncommon settings are not yet implemented and may +never be; nonintegral sampling ratios are the prime example. Furthermore, +we treat 8-bit vs. 12-bit data precision as a compile-time switch, not a +run-time option, because most machines can store 8-bit pixels much more +compactly than 12-bit. + +For legal reasons, JPEG arithmetic coding is not currently supported, but +extending the library to include it would be straightforward. + +By itself, the library handles only interchange JPEG datastreams --- in +particular the widely used JFIF file format. The library can be used by +surrounding code to process interchange or abbreviated JPEG datastreams that +are embedded in more complex file formats. (For example, libtiff uses this +library to implement JPEG compression within the TIFF file format.) + +The library includes a substantial amount of code that is not covered by the +JPEG standard but is necessary for typical applications of JPEG. These +functions preprocess the image before JPEG compression or postprocess it after +decompression. They include colorspace conversion, downsampling/upsampling, +and color quantization. This code can be omitted if not needed. + +A wide range of quality vs. speed tradeoffs are possible in JPEG processing, +and even more so in decompression postprocessing. The decompression library +provides multiple implementations that cover most of the useful tradeoffs, +ranging from very-high-quality down to fast-preview operation. On the +compression side we have generally not provided low-quality choices, since +compression is normally less time-critical. It should be understood that the +low-quality modes may not meet the JPEG standard's accuracy requirements; +nonetheless, they are useful for viewers. + + +*** Portability issues *** + +Portability is an essential requirement for the library. The key portability +issues that show up at the level of system architecture are: + +1. Memory usage. We want the code to be able to run on PC-class machines +with limited memory. Images should therefore be processed sequentially (in +strips), to avoid holding the whole image in memory at once. Where a +full-image buffer is necessary, we should be able to use either virtual memory +or temporary files. + +2. Near/far pointer distinction. To run efficiently on 80x86 machines, the +code should distinguish "small" objects (kept in near data space) from +"large" ones (kept in far data space). This is an annoying restriction, but +fortunately it does not impact code quality for less brain-damaged machines, +and the source code clutter turns out to be minimal with sufficient use of +pointer typedefs. + +3. Data precision. We assume that "char" is at least 8 bits, "short" and +"int" at least 16, "long" at least 32. The code will work fine with larger +data sizes, although memory may be used inefficiently in some cases. However, +the JPEG compressed datastream must ultimately appear on external storage as a +sequence of 8-bit bytes if it is to conform to the standard. This may pose a +problem on machines where char is wider than 8 bits. The library represents +compressed data as an array of values of typedef JOCTET. If no data type +exactly 8 bits wide is available, custom data source and data destination +modules must be written to unpack and pack the chosen JOCTET datatype into +8-bit external representation. + + +*** System overview *** + +The compressor and decompressor are each divided into two main sections: +the JPEG compressor or decompressor proper, and the preprocessing or +postprocessing functions. The interface between these two sections is the +image data that the official JPEG spec regards as its input or output: this +data is in the colorspace to be used for compression, and it is downsampled +to the sampling factors to be used. The preprocessing and postprocessing +steps are responsible for converting a normal image representation to or from +this form. (Those few applications that want to deal with YCbCr downsampled +data can skip the preprocessing or postprocessing step.) + +Looking more closely, the compressor library contains the following main +elements: + + Preprocessing: + * Color space conversion (e.g., RGB to YCbCr). + * Edge expansion and downsampling. Optionally, this step can do simple + smoothing --- this is often helpful for low-quality source data. + JPEG proper: + * MCU assembly, DCT, quantization. + * Entropy coding (sequential or progressive, Huffman or arithmetic). + +In addition to these modules we need overall control, marker generation, +and support code (memory management & error handling). There is also a +module responsible for physically writing the output data --- typically +this is just an interface to fwrite(), but some applications may need to +do something else with the data. + +The decompressor library contains the following main elements: + + JPEG proper: + * Entropy decoding (sequential or progressive, Huffman or arithmetic). + * Dequantization, inverse DCT, MCU disassembly. + Postprocessing: + * Upsampling. Optionally, this step may be able to do more general + rescaling of the image. + * Color space conversion (e.g., YCbCr to RGB). This step may also + provide gamma adjustment [ currently it does not ]. + * Optional color quantization (e.g., reduction to 256 colors). + * Optional color precision reduction (e.g., 24-bit to 15-bit color). + [This feature is not currently implemented.] + +We also need overall control, marker parsing, and a data source module. +The support code (memory management & error handling) can be shared with +the compression half of the library. + +There may be several implementations of each of these elements, particularly +in the decompressor, where a wide range of speed/quality tradeoffs is very +useful. It must be understood that some of the best speedups involve +merging adjacent steps in the pipeline. For example, upsampling, color space +conversion, and color quantization might all be done at once when using a +low-quality ordered-dither technique. The system architecture is designed to +allow such merging where appropriate. + + +Note: it is convenient to regard edge expansion (padding to block boundaries) +as a preprocessing/postprocessing function, even though the JPEG spec includes +it in compression/decompression. We do this because downsampling/upsampling +can be simplified a little if they work on padded data: it's not necessary to +have special cases at the right and bottom edges. Therefore the interface +buffer is always an integral number of blocks wide and high, and we expect +compression preprocessing to pad the source data properly. Padding will occur +only to the next block (8-sample) boundary. In an interleaved-scan situation, +additional dummy blocks may be used to fill out MCUs, but the MCU assembly and +disassembly logic will create or discard these blocks internally. (This is +advantageous for speed reasons, since we avoid DCTing the dummy blocks. +It also permits a small reduction in file size, because the compressor can +choose dummy block contents so as to minimize their size in compressed form. +Finally, it makes the interface buffer specification independent of whether +the file is actually interleaved or not.) Applications that wish to deal +directly with the downsampled data must provide similar buffering and padding +for odd-sized images. + + +*** Poor man's object-oriented programming *** + +It should be clear by now that we have a lot of quasi-independent processing +steps, many of which have several possible behaviors. To avoid cluttering the +code with lots of switch statements, we use a simple form of object-style +programming to separate out the different possibilities. + +For example, two different color quantization algorithms could be implemented +as two separate modules that present the same external interface; at runtime, +the calling code will access the proper module indirectly through an "object". + +We can get the limited features we need while staying within portable C. +The basic tool is a function pointer. An "object" is just a struct +containing one or more function pointer fields, each of which corresponds to +a method name in real object-oriented languages. During initialization we +fill in the function pointers with references to whichever module we have +determined we need to use in this run. Then invocation of the module is done +by indirecting through a function pointer; on most machines this is no more +expensive than a switch statement, which would be the only other way of +making the required run-time choice. The really significant benefit, of +course, is keeping the source code clean and well structured. + +We can also arrange to have private storage that varies between different +implementations of the same kind of object. We do this by making all the +module-specific object structs be separately allocated entities, which will +be accessed via pointers in the master compression or decompression struct. +The "public" fields or methods for a given kind of object are specified by +a commonly known struct. But a module's initialization code can allocate +a larger struct that contains the common struct as its first member, plus +additional private fields. With appropriate pointer casting, the module's +internal functions can access these private fields. (For a simple example, +see jdatadst.c, which implements the external interface specified by struct +jpeg_destination_mgr, but adds extra fields.) + +(Of course this would all be a lot easier if we were using C++, but we are +not yet prepared to assume that everyone has a C++ compiler.) + +An important benefit of this scheme is that it is easy to provide multiple +versions of any method, each tuned to a particular case. While a lot of +precalculation might be done to select an optimal implementation of a method, +the cost per invocation is constant. For example, the upsampling step might +have a "generic" method, plus one or more "hardwired" methods for the most +popular sampling factors; the hardwired methods would be faster because they'd +use straight-line code instead of for-loops. The cost to determine which +method to use is paid only once, at startup, and the selection criteria are +hidden from the callers of the method. + +This plan differs a little bit from usual object-oriented structures, in that +only one instance of each object class will exist during execution. The +reason for having the class structure is that on different runs we may create +different instances (choose to execute different modules). You can think of +the term "method" as denoting the common interface presented by a particular +set of interchangeable functions, and "object" as denoting a group of related +methods, or the total shared interface behavior of a group of modules. + + +*** Overall control structure *** + +We previously mentioned the need for overall control logic in the compression +and decompression libraries. In IJG implementations prior to v5, overall +control was mostly provided by "pipeline control" modules, which proved to be +large, unwieldy, and hard to understand. To improve the situation, the +control logic has been subdivided into multiple modules. The control modules +consist of: + +1. Master control for module selection and initialization. This has two +responsibilities: + + 1A. Startup initialization at the beginning of image processing. + The individual processing modules to be used in this run are selected + and given initialization calls. + + 1B. Per-pass control. This determines how many passes will be performed + and calls each active processing module to configure itself + appropriately at the beginning of each pass. End-of-pass processing, + where necessary, is also invoked from the master control module. + + Method selection is partially distributed, in that a particular processing + module may contain several possible implementations of a particular method, + which it will select among when given its initialization call. The master + control code need only be concerned with decisions that affect more than + one module. + +2. Data buffering control. A separate control module exists for each + inter-processing-step data buffer. This module is responsible for + invoking the processing steps that write or read that data buffer. + +Each buffer controller sees the world as follows: + +input data => processing step A => buffer => processing step B => output data + | | | + ------------------ controller ------------------ + +The controller knows the dataflow requirements of steps A and B: how much data +they want to accept in one chunk and how much they output in one chunk. Its +function is to manage its buffer and call A and B at the proper times. + +A data buffer control module may itself be viewed as a processing step by a +higher-level control module; thus the control modules form a binary tree with +elementary processing steps at the leaves of the tree. + +The control modules are objects. A considerable amount of flexibility can +be had by replacing implementations of a control module. For example: +* Merging of adjacent steps in the pipeline is done by replacing a control + module and its pair of processing-step modules with a single processing- + step module. (Hence the possible merges are determined by the tree of + control modules.) +* In some processing modes, a given interstep buffer need only be a "strip" + buffer large enough to accommodate the desired data chunk sizes. In other + modes, a full-image buffer is needed and several passes are required. + The control module determines which kind of buffer is used and manipulates + virtual array buffers as needed. One or both processing steps may be + unaware of the multi-pass behavior. + +In theory, we might be able to make all of the data buffer controllers +interchangeable and provide just one set of implementations for all. In +practice, each one contains considerable special-case processing for its +particular job. The buffer controller concept should be regarded as an +overall system structuring principle, not as a complete description of the +task performed by any one controller. + + +*** Compression object structure *** + +Here is a sketch of the logical structure of the JPEG compression library: + + |-- Colorspace conversion + |-- Preprocessing controller --| + | |-- Downsampling +Main controller --| + | |-- Forward DCT, quantize + |-- Coefficient controller --| + |-- Entropy encoding + +This sketch also describes the flow of control (subroutine calls) during +typical image data processing. Each of the components shown in the diagram is +an "object" which may have several different implementations available. One +or more source code files contain the actual implementation(s) of each object. + +The objects shown above are: + +* Main controller: buffer controller for the subsampled-data buffer, which + holds the preprocessed input data. This controller invokes preprocessing to + fill the subsampled-data buffer, and JPEG compression to empty it. There is + usually no need for a full-image buffer here; a strip buffer is adequate. + +* Preprocessing controller: buffer controller for the downsampling input data + buffer, which lies between colorspace conversion and downsampling. Note + that a unified conversion/downsampling module would probably replace this + controller entirely. + +* Colorspace conversion: converts application image data into the desired + JPEG color space; also changes the data from pixel-interleaved layout to + separate component planes. Processes one pixel row at a time. + +* Downsampling: performs reduction of chroma components as required. + Optionally may perform pixel-level smoothing as well. Processes a "row + group" at a time, where a row group is defined as Vmax pixel rows of each + component before downsampling, and Vk sample rows afterwards (remember Vk + differs across components). Some downsampling or smoothing algorithms may + require context rows above and below the current row group; the + preprocessing controller is responsible for supplying these rows via proper + buffering. The downsampler is responsible for edge expansion at the right + edge (i.e., extending each sample row to a multiple of 8 samples); but the + preprocessing controller is responsible for vertical edge expansion (i.e., + duplicating the bottom sample row as needed to make a multiple of 8 rows). + +* Coefficient controller: buffer controller for the DCT-coefficient data. + This controller handles MCU assembly, including insertion of dummy DCT + blocks when needed at the right or bottom edge. When performing + Huffman-code optimization or emitting a multiscan JPEG file, this + controller is responsible for buffering the full image. The equivalent of + one fully interleaved MCU row of subsampled data is processed per call, + even when the JPEG file is noninterleaved. + +* Forward DCT and quantization: Perform DCT, quantize, and emit coefficients. + Works on one or more DCT blocks at a time. (Note: the coefficients are now + emitted in normal array order, which the entropy encoder is expected to + convert to zigzag order as necessary. Prior versions of the IJG code did + the conversion to zigzag order within the quantization step.) + +* Entropy encoding: Perform Huffman or arithmetic entropy coding and emit the + coded data to the data destination module. Works on one MCU per call. + For progressive JPEG, the same DCT blocks are fed to the entropy coder + during each pass, and the coder must emit the appropriate subset of + coefficients. + +In addition to the above objects, the compression library includes these +objects: + +* Master control: determines the number of passes required, controls overall + and per-pass initialization of the other modules. + +* Marker writing: generates JPEG markers (except for RSTn, which is emitted + by the entropy encoder when needed). + +* Data destination manager: writes the output JPEG datastream to its final + destination (e.g., a file). The destination manager supplied with the + library knows how to write to a stdio stream; for other behaviors, the + surrounding application may provide its own destination manager. + +* Memory manager: allocates and releases memory, controls virtual arrays + (with backing store management, where required). + +* Error handler: performs formatting and output of error and trace messages; + determines handling of nonfatal errors. The surrounding application may + override some or all of this object's methods to change error handling. + +* Progress monitor: supports output of "percent-done" progress reports. + This object represents an optional callback to the surrounding application: + if wanted, it must be supplied by the application. + +The error handler, destination manager, and progress monitor objects are +defined as separate objects in order to simplify application-specific +customization of the JPEG library. A surrounding application may override +individual methods or supply its own all-new implementation of one of these +objects. The object interfaces for these objects are therefore treated as +part of the application interface of the library, whereas the other objects +are internal to the library. + +The error handler and memory manager are shared by JPEG compression and +decompression; the progress monitor, if used, may be shared as well. + + +*** Decompression object structure *** + +Here is a sketch of the logical structure of the JPEG decompression library: + + |-- Entropy decoding + |-- Coefficient controller --| + | |-- Dequantize, Inverse DCT +Main controller --| + | |-- Upsampling + |-- Postprocessing controller --| |-- Colorspace conversion + |-- Color quantization + |-- Color precision reduction + +As before, this diagram also represents typical control flow. The objects +shown are: + +* Main controller: buffer controller for the subsampled-data buffer, which + holds the output of JPEG decompression proper. This controller's primary + task is to feed the postprocessing procedure. Some upsampling algorithms + may require context rows above and below the current row group; when this + is true, the main controller is responsible for managing its buffer so as + to make context rows available. In the current design, the main buffer is + always a strip buffer; a full-image buffer is never required. + +* Coefficient controller: buffer controller for the DCT-coefficient data. + This controller handles MCU disassembly, including deletion of any dummy + DCT blocks at the right or bottom edge. When reading a multiscan JPEG + file, this controller is responsible for buffering the full image. + (Buffering DCT coefficients, rather than samples, is necessary to support + progressive JPEG.) The equivalent of one fully interleaved MCU row of + subsampled data is processed per call, even when the source JPEG file is + noninterleaved. + +* Entropy decoding: Read coded data from the data source module and perform + Huffman or arithmetic entropy decoding. Works on one MCU per call. + For progressive JPEG decoding, the coefficient controller supplies the prior + coefficients of each MCU (initially all zeroes), which the entropy decoder + modifies in each scan. + +* Dequantization and inverse DCT: like it says. Note that the coefficients + buffered by the coefficient controller have NOT been dequantized; we + merge dequantization and inverse DCT into a single step for speed reasons. + When scaled-down output is asked for, simplified DCT algorithms may be used + that emit only 1x1, 2x2, or 4x4 samples per DCT block, not the full 8x8. + Works on one DCT block at a time. + +* Postprocessing controller: buffer controller for the color quantization + input buffer, when quantization is in use. (Without quantization, this + controller just calls the upsampler.) For two-pass quantization, this + controller is responsible for buffering the full-image data. + +* Upsampling: restores chroma components to full size. (May support more + general output rescaling, too. Note that if undersized DCT outputs have + been emitted by the DCT module, this module must adjust so that properly + sized outputs are created.) Works on one row group at a time. This module + also calls the color conversion module, so its top level is effectively a + buffer controller for the upsampling->color conversion buffer. However, in + all but the highest-quality operating modes, upsampling and color + conversion are likely to be merged into a single step. + +* Colorspace conversion: convert from JPEG color space to output color space, + and change data layout from separate component planes to pixel-interleaved. + Works on one pixel row at a time. + +* Color quantization: reduce the data to colormapped form, using either an + externally specified colormap or an internally generated one. This module + is not used for full-color output. Works on one pixel row at a time; may + require two passes to generate a color map. Note that the output will + always be a single component representing colormap indexes. In the current + design, the output values are JSAMPLEs, so an 8-bit compilation cannot + quantize to more than 256 colors. This is unlikely to be a problem in + practice. + +* Color reduction: this module handles color precision reduction, e.g., + generating 15-bit color (5 bits/primary) from JPEG's 24-bit output. + Not quite clear yet how this should be handled... should we merge it with + colorspace conversion??? + +Note that some high-speed operating modes might condense the entire +postprocessing sequence to a single module (upsample, color convert, and +quantize in one step). + +In addition to the above objects, the decompression library includes these +objects: + +* Master control: determines the number of passes required, controls overall + and per-pass initialization of the other modules. This is subdivided into + input and output control: jdinput.c controls only input-side processing, + while jdmaster.c handles overall initialization and output-side control. + +* Marker reading: decodes JPEG markers (except for RSTn). + +* Data source manager: supplies the input JPEG datastream. The source + manager supplied with the library knows how to read from a stdio stream; + for other behaviors, the surrounding application may provide its own source + manager. + +* Memory manager: same as for compression library. + +* Error handler: same as for compression library. + +* Progress monitor: same as for compression library. + +As with compression, the data source manager, error handler, and progress +monitor are candidates for replacement by a surrounding application. + + +*** Decompression input and output separation *** + +To support efficient incremental display of progressive JPEG files, the +decompressor is divided into two sections that can run independently: + +1. Data input includes marker parsing, entropy decoding, and input into the + coefficient controller's DCT coefficient buffer. Note that this + processing is relatively cheap and fast. + +2. Data output reads from the DCT coefficient buffer and performs the IDCT + and all postprocessing steps. + +For a progressive JPEG file, the data input processing is allowed to get +arbitrarily far ahead of the data output processing. (This occurs only +if the application calls jpeg_consume_input(); otherwise input and output +run in lockstep, since the input section is called only when the output +section needs more data.) In this way the application can avoid making +extra display passes when data is arriving faster than the display pass +can run. Furthermore, it is possible to abort an output pass without +losing anything, since the coefficient buffer is read-only as far as the +output section is concerned. See libjpeg.doc for more detail. + +A full-image coefficient array is only created if the JPEG file has multiple +scans (or if the application specifies buffered-image mode anyway). When +reading a single-scan file, the coefficient controller normally creates only +a one-MCU buffer, so input and output processing must run in lockstep in this +case. jpeg_consume_input() is effectively a no-op in this situation. + +The main impact of dividing the decompressor in this fashion is that we must +be very careful with shared variables in the cinfo data structure. Each +variable that can change during the course of decompression must be +classified as belonging to data input or data output, and each section must +look only at its own variables. For example, the data output section may not +depend on any of the variables that describe the current scan in the JPEG +file, because these may change as the data input section advances into a new +scan. + +The progress monitor is (somewhat arbitrarily) defined to treat input of the +file as one pass when buffered-image mode is not used, and to ignore data +input work completely when buffered-image mode is used. Note that the +library has no reliable way to predict the number of passes when dealing +with a progressive JPEG file, nor can it predict the number of output passes +in buffered-image mode. So the work estimate is inherently bogus anyway. + +No comparable division is currently made in the compression library, because +there isn't any real need for it. + + +*** Data formats *** + +Arrays of pixel sample values use the following data structure: + + typedef something JSAMPLE; a pixel component value, 0..MAXJSAMPLE + typedef JSAMPLE *JSAMPROW; ptr to a row of samples + typedef JSAMPROW *JSAMPARRAY; ptr to a list of rows + typedef JSAMPARRAY *JSAMPIMAGE; ptr to a list of color-component arrays + +The basic element type JSAMPLE will typically be one of unsigned char, +(signed) char, or short. Short will be used if samples wider than 8 bits are +to be supported (this is a compile-time option). Otherwise, unsigned char is +used if possible. If the compiler only supports signed chars, then it is +necessary to mask off the value when reading. Thus, all reads of JSAMPLE +values must be coded as "GETJSAMPLE(value)", where the macro will be defined +as "((value) & 0xFF)" on signed-char machines and "((int) (value))" elsewhere. + +With these conventions, JSAMPLE values can be assumed to be >= 0. This helps +simplify correct rounding during downsampling, etc. The JPEG standard's +specification that sample values run from -128..127 is accommodated by +subtracting 128 just as the sample value is copied into the source array for +the DCT step (this will be an array of signed ints). Similarly, during +decompression the output of the IDCT step will be immediately shifted back to +0..255. (NB: different values are required when 12-bit samples are in use. +The code is written in terms of MAXJSAMPLE and CENTERJSAMPLE, which will be +defined as 255 and 128 respectively in an 8-bit implementation, and as 4095 +and 2048 in a 12-bit implementation.) + +We use a pointer per row, rather than a two-dimensional JSAMPLE array. This +choice costs only a small amount of memory and has several benefits: +* Code using the data structure doesn't need to know the allocated width of + the rows. This simplifies edge expansion/compression, since we can work + in an array that's wider than the logical picture width. +* Indexing doesn't require multiplication; this is a performance win on many + machines. +* Arrays with more than 64K total elements can be supported even on machines + where malloc() cannot allocate chunks larger than 64K. +* The rows forming a component array may be allocated at different times + without extra copying. This trick allows some speedups in smoothing steps + that need access to the previous and next rows. + +Note that each color component is stored in a separate array; we don't use the +traditional layout in which the components of a pixel are stored together. +This simplifies coding of modules that work on each component independently, +because they don't need to know how many components there are. Furthermore, +we can read or write each component to a temporary file independently, which +is helpful when dealing with noninterleaved JPEG files. + +In general, a specific sample value is accessed by code such as + GETJSAMPLE(image[colorcomponent][row][col]) +where col is measured from the image left edge, but row is measured from the +first sample row currently in memory. Either of the first two indexings can +be precomputed by copying the relevant pointer. + + +Since most image-processing applications prefer to work on images in which +the components of a pixel are stored together, the data passed to or from the +surrounding application uses the traditional convention: a single pixel is +represented by N consecutive JSAMPLE values, and an image row is an array of +(# of color components)*(image width) JSAMPLEs. One or more rows of data can +be represented by a pointer of type JSAMPARRAY in this scheme. This scheme is +converted to component-wise storage inside the JPEG library. (Applications +that want to skip JPEG preprocessing or postprocessing will have to contend +with component-wise storage.) + + +Arrays of DCT-coefficient values use the following data structure: + + typedef short JCOEF; a 16-bit signed integer + typedef JCOEF JBLOCK[DCTSIZE2]; an 8x8 block of coefficients + typedef JBLOCK *JBLOCKROW; ptr to one horizontal row of 8x8 blocks + typedef JBLOCKROW *JBLOCKARRAY; ptr to a list of such rows + typedef JBLOCKARRAY *JBLOCKIMAGE; ptr to a list of color component arrays + +The underlying type is at least a 16-bit signed integer; while "short" is big +enough on all machines of interest, on some machines it is preferable to use +"int" for speed reasons, despite the storage cost. Coefficients are grouped +into 8x8 blocks (but we always use #defines DCTSIZE and DCTSIZE2 rather than +"8" and "64"). + +The contents of a coefficient block may be in either "natural" or zigzagged +order, and may be true values or divided by the quantization coefficients, +depending on where the block is in the processing pipeline. In the current +library, coefficient blocks are kept in natural order everywhere; the entropy +codecs zigzag or dezigzag the data as it is written or read. The blocks +contain quantized coefficients everywhere outside the DCT/IDCT subsystems. +(This latter decision may need to be revisited to support variable +quantization a la JPEG Part 3.) + +Notice that the allocation unit is now a row of 8x8 blocks, corresponding to +eight rows of samples. Otherwise the structure is much the same as for +samples, and for the same reasons. + +On machines where malloc() can't handle a request bigger than 64Kb, this data +structure limits us to rows of less than 512 JBLOCKs, or a picture width of +4000+ pixels. This seems an acceptable restriction. + + +On 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW) +must be declared as "far" pointers, but the upper levels can be "near" +(implying that the pointer lists are allocated in the DS segment). +We use a #define symbol FAR, which expands to the "far" keyword when +compiling on 80x86 machines and to nothing elsewhere. + + +*** Suspendable processing *** + +In some applications it is desirable to use the JPEG library as an +incremental, memory-to-memory filter. In this situation the data source or +destination may be a limited-size buffer, and we can't rely on being able to +empty or refill the buffer at arbitrary times. Instead the application would +like to have control return from the library at buffer overflow/underrun, and +then resume compression or decompression at a later time. + +This scenario is supported for simple cases. (For anything more complex, we +recommend that the application "bite the bullet" and develop real multitasking +capability.) The libjpeg.doc file goes into more detail about the usage and +limitations of this capability; here we address the implications for library +structure. + +The essence of the problem is that the entropy codec (coder or decoder) must +be prepared to stop at arbitrary times. In turn, the controllers that call +the entropy codec must be able to stop before having produced or consumed all +the data that they normally would handle in one call. That part is reasonably +straightforward: we make the controller call interfaces include "progress +counters" which indicate the number of data chunks successfully processed, and +we require callers to test the counter rather than just assume all of the data +was processed. + +Rather than trying to restart at an arbitrary point, the current Huffman +codecs are designed to restart at the beginning of the current MCU after a +suspension due to buffer overflow/underrun. At the start of each call, the +codec's internal state is loaded from permanent storage (in the JPEG object +structures) into local variables. On successful completion of the MCU, the +permanent state is updated. (This copying is not very expensive, and may even +lead to *improved* performance if the local variables can be registerized.) +If a suspension occurs, the codec simply returns without updating the state, +thus effectively reverting to the start of the MCU. Note that this implies +leaving some data unprocessed in the source/destination buffer (ie, the +compressed partial MCU). The data source/destination module interfaces are +specified so as to make this possible. This also implies that the data buffer +must be large enough to hold a worst-case compressed MCU; a couple thousand +bytes should be enough. + +In a successive-approximation AC refinement scan, the progressive Huffman +decoder has to be able to undo assignments of newly nonzero coefficients if it +suspends before the MCU is complete, since decoding requires distinguishing +previously-zero and previously-nonzero coefficients. This is a bit tedious +but probably won't have much effect on performance. Other variants of Huffman +decoding need not worry about this, since they will just store the same values +again if forced to repeat the MCU. + +This approach would probably not work for an arithmetic codec, since its +modifiable state is quite large and couldn't be copied cheaply. Instead it +would have to suspend and resume exactly at the point of the buffer end. + +The JPEG marker reader is designed to cope with suspension at an arbitrary +point. It does so by backing up to the start of the marker parameter segment, +so the data buffer must be big enough to hold the largest marker of interest. +Again, a couple KB should be adequate. (A special "skip" convention is used +to bypass COM and APPn markers, so these can be larger than the buffer size +without causing problems; otherwise a 64K buffer would be needed in the worst +case.) + +The JPEG marker writer currently does *not* cope with suspension. I feel that +this is not necessary; it is much easier simply to require the application to +ensure there is enough buffer space before starting. (An empty 2K buffer is +more than sufficient for the header markers; and ensuring there are a dozen or +two bytes available before calling jpeg_finish_compress() will suffice for the +trailer.) This would not work for writing multi-scan JPEG files, but +we simply do not intend to support that capability with suspension. + + +*** Memory manager services *** + +The JPEG library's memory manager controls allocation and deallocation of +memory, and it manages large "virtual" data arrays on machines where the +operating system does not provide virtual memory. Note that the same +memory manager serves both compression and decompression operations. + +In all cases, allocated objects are tied to a particular compression or +decompression master record, and they will be released when that master +record is destroyed. + +The memory manager does not provide explicit deallocation of objects. +Instead, objects are created in "pools" of free storage, and a whole pool +can be freed at once. This approach helps prevent storage-leak bugs, and +it speeds up operations whenever malloc/free are slow (as they often are). +The pools can be regarded as lifetime identifiers for objects. Two +pools/lifetimes are defined: + * JPOOL_PERMANENT lasts until master record is destroyed + * JPOOL_IMAGE lasts until done with image (JPEG datastream) +Permanent lifetime is used for parameters and tables that should be carried +across from one datastream to another; this includes all application-visible +parameters. Image lifetime is used for everything else. (A third lifetime, +JPOOL_PASS = one processing pass, was originally planned. However it was +dropped as not being worthwhile. The actual usage patterns are such that the +peak memory usage would be about the same anyway; and having per-pass storage +substantially complicates the virtual memory allocation rules --- see below.) + +The memory manager deals with three kinds of object: +1. "Small" objects. Typically these require no more than 10K-20K total. +2. "Large" objects. These may require tens to hundreds of K depending on + image size. Semantically they behave the same as small objects, but we + distinguish them for two reasons: + * On MS-DOS machines, large objects are referenced by FAR pointers, + small objects by NEAR pointers. + * Pool allocation heuristics may differ for large and small objects. + Note that individual "large" objects cannot exceed the size allowed by + type size_t, which may be 64K or less on some machines. +3. "Virtual" objects. These are large 2-D arrays of JSAMPLEs or JBLOCKs + (typically large enough for the entire image being processed). The + memory manager provides stripwise access to these arrays. On machines + without virtual memory, the rest of the array may be swapped out to a + temporary file. + +(Note: JSAMPARRAY and JBLOCKARRAY data structures are a combination of large +objects for the data proper and small objects for the row pointers. For +convenience and speed, the memory manager provides single routines to create +these structures. Similarly, virtual arrays include a small control block +and a JSAMPARRAY or JBLOCKARRAY working buffer, all created with one call.) + +In the present implementation, virtual arrays are only permitted to have image +lifespan. (Permanent lifespan would not be reasonable, and pass lifespan is +not very useful since a virtual array's raison d'etre is to store data for +multiple passes through the image.) We also expect that only "small" objects +will be given permanent lifespan, though this restriction is not required by +the memory manager. + +In a non-virtual-memory machine, some performance benefit can be gained by +making the in-memory buffers for virtual arrays be as large as possible. +(For small images, the buffers might fit entirely in memory, so blind +swapping would be very wasteful.) The memory manager will adjust the height +of the buffers to fit within a prespecified maximum memory usage. In order +to do this in a reasonably optimal fashion, the manager needs to allocate all +of the virtual arrays at once. Therefore, there isn't a one-step allocation +routine for virtual arrays; instead, there is a "request" routine that simply +allocates the control block, and a "realize" routine (called just once) that +determines space allocation and creates all of the actual buffers. The +realize routine must allow for space occupied by non-virtual large objects. +(We don't bother to factor in the space needed for small objects, on the +grounds that it isn't worth the trouble.) + +To support all this, we establish the following protocol for doing business +with the memory manager: + 1. Modules must request virtual arrays (which may have only image lifespan) + during the initial setup phase, i.e., in their jinit_xxx routines. + 2. All "large" objects (including JSAMPARRAYs and JBLOCKARRAYs) must also be + allocated during initial setup. + 3. realize_virt_arrays will be called at the completion of initial setup. + The above conventions ensure that sufficient information is available + for it to choose a good size for virtual array buffers. +Small objects of any lifespan may be allocated at any time. We expect that +the total space used for small objects will be small enough to be negligible +in the realize_virt_arrays computation. + +In a virtual-memory machine, we simply pretend that the available space is +infinite, thus causing realize_virt_arrays to decide that it can allocate all +the virtual arrays as full-size in-memory buffers. The overhead of the +virtual-array access protocol is very small when no swapping occurs. + +A virtual array can be specified to be "pre-zeroed"; when this flag is set, +never-yet-written sections of the array are set to zero before being made +available to the caller. If this flag is not set, never-written sections +of the array contain garbage. (This feature exists primarily because the +equivalent logic would otherwise be needed in jdcoefct.c for progressive +JPEG mode; we may as well make it available for possible other uses.) + +The first write pass on a virtual array is required to occur in top-to-bottom +order; read passes, as well as any write passes after the first one, may +access the array in any order. This restriction exists partly to simplify +the virtual array control logic, and partly because some file systems may not +support seeking beyond the current end-of-file in a temporary file. The main +implication of this restriction is that rearrangement of rows (such as +converting top-to-bottom data order to bottom-to-top) must be handled while +reading data out of the virtual array, not while putting it in. + + +*** Memory manager internal structure *** + +To isolate system dependencies as much as possible, we have broken the +memory manager into two parts. There is a reasonably system-independent +"front end" (jmemmgr.c) and a "back end" that contains only the code +likely to change across systems. All of the memory management methods +outlined above are implemented by the front end. The back end provides +the following routines for use by the front end (none of these routines +are known to the rest of the JPEG code): + +jpeg_mem_init, jpeg_mem_term system-dependent initialization/shutdown + +jpeg_get_small, jpeg_free_small interface to malloc and free library routines + (or their equivalents) + +jpeg_get_large, jpeg_free_large interface to FAR malloc/free in MSDOS machines; + else usually the same as + jpeg_get_small/jpeg_free_small + +jpeg_mem_available estimate available memory + +jpeg_open_backing_store create a backing-store object + +read_backing_store, manipulate a backing-store object +write_backing_store, +close_backing_store + +On some systems there will be more than one type of backing-store object +(specifically, in MS-DOS a backing store file might be an area of extended +memory as well as a disk file). jpeg_open_backing_store is responsible for +choosing how to implement a given object. The read/write/close routines +are method pointers in the structure that describes a given object; this +lets them be different for different object types. + +It may be necessary to ensure that backing store objects are explicitly +released upon abnormal program termination. For example, MS-DOS won't free +extended memory by itself. To support this, we will expect the main program +or surrounding application to arrange to call self_destruct (typically via +jpeg_destroy) upon abnormal termination. This may require a SIGINT signal +handler or equivalent. We don't want to have the back end module install its +own signal handler, because that would pre-empt the surrounding application's +ability to control signal handling. + +The IJG distribution includes several memory manager back end implementations. +Usually the same back end should be suitable for all applications on a given +system, but it is possible for an application to supply its own back end at +need. + + +*** Implications of DNL marker *** + +Some JPEG files may use a DNL marker to postpone definition of the image +height (this would be useful for a fax-like scanner's output, for instance). +In these files the SOF marker claims the image height is 0, and you only +find out the true image height at the end of the first scan. + +We could read these files as follows: +1. Upon seeing zero image height, replace it by 65535 (the maximum allowed). +2. When the DNL is found, update the image height in the global image + descriptor. +This implies that control modules must avoid making copies of the image +height, and must re-test for termination after each MCU row. This would +be easy enough to do. + +In cases where image-size data structures are allocated, this approach will +result in very inefficient use of virtual memory or much-larger-than-necessary +temporary files. This seems acceptable for something that probably won't be a +mainstream usage. People might have to forgo use of memory-hogging options +(such as two-pass color quantization or noninterleaved JPEG files) if they +want efficient conversion of such files. (One could improve efficiency by +demanding a user-supplied upper bound for the height, less than 65536; in most +cases it could be much less.) + +The standard also permits the SOF marker to overestimate the image height, +with a DNL to give the true, smaller height at the end of the first scan. +This would solve the space problems if the overestimate wasn't too great. +However, it implies that you don't even know whether DNL will be used. + +This leads to a couple of very serious objections: +1. Testing for a DNL marker must occur in the inner loop of the decompressor's + Huffman decoder; this implies a speed penalty whether the feature is used + or not. +2. There is no way to hide the last-minute change in image height from an + application using the decoder. Thus *every* application using the IJG + library would suffer a complexity penalty whether it cared about DNL or + not. +We currently do not support DNL because of these problems. + +A different approach is to insist that DNL-using files be preprocessed by a +separate program that reads ahead to the DNL, then goes back and fixes the SOF +marker. This is a much simpler solution and is probably far more efficient. +Even if one wants piped input, buffering the first scan of the JPEG file needs +a lot smaller temp file than is implied by the maximum-height method. For +this approach we'd simply treat DNL as a no-op in the decompressor (at most, +check that it matches the SOF image height). + +We will not worry about making the compressor capable of outputting DNL. +Something similar to the first scheme above could be applied if anyone ever +wants to make that work. diff --git a/src/dep/src/irrlicht/jpeglib/testimg.bmp b/src/dep/src/irrlicht/jpeglib/testimg.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8603d15484d47f0b90eb4246a2309c566f8adaa7 GIT binary patch literal 35050 zcma)_3tX1<-TyC>J>f74nTlu{hZGOkAIYFla+;t5CY2?gP!NJV4nbH*Qq9cO(pDM; z!M&9_Ivv~Qt&darbb%w{>;N(93 zxHBv7XHI7B(@w~}KJe$ADSu}5{^WsOJ zI*aaj&q=#&u9K8K$JtiC&KVZ*ptI}npPaa{e{tsJr8}`x=Q!~HsR(Vsi< z6VE!Oi}IYG&-{b)>)&p5?#y26JhZRG$({Pp-* zCw1O_CwWqxb9CK0XX?y{oy_bsXH@hjPSN_U&Mi~dI4|D+3nw(>O(%BzBqu+k&AETU zpPdmABb=wQ?{OwQFwa@{>=RD&H|L!P?{9O~{_2Et>+PR7lZUrCQMc@K?!9N3^Ug2U zIFoPR=1iHL>OA~zgh97 zQ}*1a&dy)`!O57K?Cjou%vo0awDVT&Kb+b>z3seK^OCdexy{b8O`DvjH`h6TI(F8{ zfBl!v@!ve@{BGyF&KqxTaT@mTck=Fk!`c17Q%?8|Y0g7g`tAhI9RdZO+J1QG8yYZ8p|f+xHfQhdKRENIzv;|R|J2ENuE=>{#eV08am$>Wr!IAVwQrmA zhpKO!@bFKa`!cpU^X{MTjJ)Z7Cw|gC=jFd_cLqni;N&d-)LF3nMdzOBpE(o9e(J1P z@R{?=+)tcU3miq2f7o6*&mpTt`_=9u%{Kd|&TcVv=GydTmdh$0;>X>hx2O zPFmI*PP|&Ef4qNaUZ|(VpHB--3yn`pjJamg)oWjUX56@?7b5!{e`U&)n+FZL@4f?b z<}6)0?muafk&!?A#mI5vc5aDE>byi*>mC)=J*s1(tTC@{_a%^7cLZIT6|)f zf11A$0-81!U0lyT^FGWRF2@wVl9#1`lg;o8l3{!6i z3&y^ys;XN3QmR%BT(zouYpb7Mr;Z&W>M?CXJdpm0yLVmv#H-i2id~4@+2{Cyt59-~ zC_njM4*rMIE}b*@F?9Q3yJbsMpb&NN*5Cm%C53yV+~V&c4CiCeZv_Pz6Cxs{V034c zu8F{gRaYJ3)6#&#K#kDuc$JvA8&kdDp@|$9*{9EOlpHkZ z(0%_A@kV!}wm7<%gC>D!)7%sOW(FU2NO2{f1E7uMk^@xtr zm*yuSSM^1`s;U$i_pj=nlH##d%o42l^XJcpVx(#~WN2c%f8M^UfBEWl_@lMR$ekDZ z95?{v$^Ve?hYGr{<&OY%5fTpgQd*^EcsRELD8s`Gpu`n}bo|!3*s4*wD*A!F&~Kri zA5I9RT@122to&f1QxJbX91KJcVN?hV5vxDv{p$PBuF15jS4a={61BeSAMjvd^{H-kUS{#=%>zk!C{&PDmh)m zcmgdBx$A0+tDT2>!BWV77IHfO$o-HaAG_u8`~UHi^FBU-8-oIa0%=KHO-Yk7bS1GS zD5bU4OxK_Ekrm~}Q$hJ*lHYF<(66-%p*@w1LNvxIe(p!^kdP4C&8*giBx5Ef#_am_ z6R&pB@fnQul>-M3Y?|{giLaB$^Q7ai+`zi?;m7a)iBApf$dSM!HAiY{#OSu7z@jKc z+Vdk|6k=;DI{Nbp5nVEHp!B>jU=y(Lhk!UG>Y<;So|wpvOcnL8R+{UQ6ULla{X zCtdyOtK>(w5m_(vx#jpP$BzT44B5fa@eBXvF*5Sue?m8;CZp!aMs7!HHg4Q_BruTc z#tzV+q@eK70_;>mwqmOO{{986eu|@FvU~R_f=aS_budx|Jj#xW)?g-B^ z&K)_jk&BB8X;M&NcvNXnP-{vMGRB7%0GT32S3$#)c(jGa_dUXeik}M?dJxGXtsnwv z?@C8kNpng?SDp}b{6o_y0(xA%R&`Eii@dON=gvNT1|J_h7<2s(bc~GrpAY7b_44w{ zh#it4xFJXCTvqp9oPp;|&7>nirKNtP4=k0ufszF&3(-+{U7Ga!zJ#VGG{7Sxm5rQn z|NgZ7MIJ_JXby>-1RVM01hj-P(ceEth0Z0$$Y(BG7Kzj6F8Oq@<#44qmng>tfm_ULvHhW3- z#83-~rGBkZ-S-#7#}70{$K#KRr;=0212a|fK*+S1CHHp8j~61Z>w}PeBKyoae&E1h zx#a(?WaQ5O`2fKD{NQctyRh?4Xpg%AZu@)U7E+`}b3Xuc}(;;EoPdQcq$^LrF@GR3m$gU-Iis9c7MsAAL4m z=tJRpVJAA0B(M8-(e)Xsc-q4sWaJ0u*4I~5Y}+N1M*h)WrjRO1s~ zlLTZaLi*v4lF=pPLDKz8bITmy&|R*W(w#ysJ`o*BEex-SOJ$CS5KaMGo#P*~`;jNQ zgq)=puIsa@k8G8?l~Q2sflb%_A4*34N+Raw*5^(=yA8-8IAlkY#VY6oo;!D1*Ns5p znhLc?lrm{BZrRO2nuenETz*JszA1L$$rT|KVtisE-3}p=A3G#WLqk2sAFa^A9k+bX z9hEvTRD$bHw>Cey_SM1H{X28rdH+~EG1nTV3L|DJ9Xr~&K&fZ83ZtY%NhOmb6bDI3 zHRnUOY}x;>gf43*spxpC)el3(5$SJ0xQcq5DlL9L-A5QLabU1AQf{u@nyq53;~zP> z_PWlXIu1w$9Ug9(^5Px6dM$bJS%@D~MaK`sd>??;9qm|^Ct1Q%2 z6j;-dV#K^XmxgPB8u?b#?#y&mAEQ}0+W1vVBC_`DWvo>b9Em(Xfai41NAG5=n!M4 ztLRd#;vxP-VqdBNL3Wy|M@Wh3G1kz~yxltv(o612Da3J+$6p!LE3qJc_x7t#{x8-V z`Da9|_pV1pZow55u_Q+$1QJXSpjhRKfF>AIE{Z-PKoC-XyW!k-m zm>*)Lt*!WA_p0tyAku-P8;OpIeY>Zat$OssFXftPQb;_13`lci&w0*;I3A>1fE zjWVz%@ci@%3oA`cG(;a4n5xdIQ@@mW4c{OjEqv9g_`c|fkfx&*<=jCh zyXBdhThir)rsc(CUcL7Bm+AmRjC|~>LA^#442+N2eeh-y<+v{4HS*yny@)mS_2T1_ zN?7gJZ(F}hI(A42qNEfg7HaOOJJ(!Ma-+{!pQOS{qon-4WU8VQtWd49tREF6CcbA1 z3Q{_r=zHSCs_t|<+qZrkuPe_Z|g}GjE6P^t98A|iWTkd;&fj=V=@oC!+ z9hmb;mpr-iH{X%-kuj{EOKw6KT83=f)~~J($Rl+_&bhW)r^q8h52Tr@BCAp2k_4fR z>YxNwf*}D-LGc1+8O5H-P^oMx7y5NiT=^c5o@Rva_3hieQ2y8T2DiQ$u}+Q3zi`sxcwGZF6^Fo%{A{am}4V4 z+@0vV_yn(UXyr#FG`l5k7x=_$&Z%|10*r9qO)6|&Ofpt4l!2vh7~$(5}sC#KDw-A&`G zp0>E}dt68#mLJ_(M^Q(n%GLUj(viw1X33#0bvcYX``q%!J9@>3rvx!5m=#py6Z6%e z1Dhh3M!xV}ZhcOpH&D%C%?V*mJiyruV=g)>tRkdqr!rS5O0w*%bOfiMO7qAF=8+7a z`94WOL71yXJJdJs=!d92RWBG7k&(E%^5W>Di(Nn-7-;3%ch&yZOFDw)amG#^C1+aR zmPbx@Ngj+kU3K#vTX4o8T4_*a|Dw3OuO5H+;s5#h+=<>T5T&++B_uSbCp3vQtU28` zw;o%Sjz*@t$*#p>yrOiujLm%tEB=UzJ$oL>$k?3Wlf>ASjFR9|C?WAk$~XE_E@GuV zf$lIK9^FllA_P!3qEHnzxgx3n?atM*Q%7~RVzwVTiA#x0%m*h7!svBi8bg+6Ui zVOC{n&C`GTf6rYxH`u$mCAp;~A)%?I8A=ht$bCqMj&e#5p-YL364DZ-@tr1Pnx(?o z6Uw>_uM8ib%>{S`6}K?4OEFTL+PICW$os7+@ry5xzG#ddM30auPJDszXkB!?^oCV+ zQgZF9%yDSo`{9QMEr?-kDJ!Kl3n42D3rkBkW_)+o+_~P~IW5Ue&CM+dEeXxE4o2TF z3f9Rc2{)6aC|&f=;E(nWOdJ-O1XRTgVjdz#`$AqS_#V25PHdd;6d z-^b^CcoBnk($Czlu#hPYlr>(-n-bpF7$u|`s*A|0?v6*sG|!`Y$ZCdY4=P{twrq!T z?R_Ut4*F_KC?d9|5VQ;VWV0%R0*Bevm85zMj(e2{s!=n{iT?xC{1CiA^U%57TaC#n)o^k|Zg@=)AqQI(37}rc5v=goG{g!E~48Yq`4wOm~2uaX;?zYHc9|@7+}a` zt6Mwu(-RZ4!-Qefm1bg|JC^~X2?^v_pQ7;YE9o#{vE5a!`n6_RWv6ifLe53yj?q_K zG1~Nl@sf@n0fpiTIFgW;ddC2D=To4GQO4?n0_UHpXh@wpH6(Xvb&j{8g@vg!H3w{R zO|_}HxH-KT(6CcyLn`_Wq0H$w`Fq~zi86|{lR=zJ>NI19dNP;Orsa_%LY$AmqNEQ= ziw2H}jIVYwOa}1K$ilLg2Jn7q4F^48gbpg4z9*8-ihZ)9#f&ylj zP%))7@JN3B*;7-erdCHsSLbw63fAL?InB*E#mU9V&FSfQYRK8MjOTbl>ZL5{0Rpa$ zN{{BMD_ny_&(mlOVhz5COL~o+?xTt3_!B4mQIhbQrI`XumZ#lUE$(*FY*k^$Ak80@ zF0EcQOrav%1bfuDx!ZV@%@&x9#B1hUNQm{9h2(mJ*cOqKV{l4`Il8oPrxrer*m zuv)>0l?JU;%DHHlP$#>9m^077G+7POZ1zY7krg40ajZ{40YSApohG^jN+N!K^ezE~ z97dB7W5p#+Nj$O}{bV=hxMB*bj6C7OUDEJ;C@LlusUy{@%oucT?4Gli!B`z2AhXjj z0ot`K2W`1|G)<+-K}L66j*f@hhDg3TQPJyau!~W8eq1-%&6cOnO@@$Wj9&AnPah!( zG0c^$XK1BR_e7jlWk=~~p;eHwRyB;(>YPhDx|D#bNkaW7lo^NutRyRi^#_!xDI06X z?uqrTZfgrjZua#J;X-p!B`QO4VHB@9$;MePTaArnT+Y&mN*&Wny7lXK_H0AQSzQ_$ z`dub1O=u9Uk|p+JXiU$;ICkvxHNASRj893~eC$9Xv z%xu@(1!8hKo!}p~kX$P8%YbZvvKgUU!a_ozJd06Uxx+)O0O4~1=|x*Pgx*k+X8P3; zg{>sOFYEew#VW9xLwe00tJOOsjw&WJ!lPP);G@XF9~UonQ%4t{G;^i2GaVuEP<6sl zuv*QEv5HZaiZ^DZ6ylaCNr4&PRTEu=Snfimcd!BkBLpF5OMHEs=}%f@ZP>=!Knkv3 zzlzujjFgWd#5cXUnX6%jG++VSzMo+xpB~~BJD#*+`c;*M7s05R z4#gbTAKl2RB#Dx)M|%8Ggmx98OVugi`2rtH{#j5~RYg@r6|t=5h!_3gbhtv!cCd9k zdKl04!~A%!xwyEgB|#P(aw;UG!9Xi2q~Y0+a(Ve$`Ep46-N~0R~dvu%2pZa@DO&y9r}{00%WVEl+^OrrezJ2 zQDKMo>A7hci3;JWqN1cEpZQ+-jV(%Xsdq6Q=ccBT zQwa&Yg}fF05K*xP6QE8=@7)BZqOfmR!c_H9tXW{9JUEAtQE!0H{(8%i4trvS-tY7xDgf+U|k-v#G{HGy_E z_iTs=)9qrg1P|Hj*<6AN5b3>p7pE6DHSvjXODIQ4Fby#zEWIhcsknD>@7~S5ky7^R zo50_lZ7{d=P@b#H$d@zD#~EoOR;~de= zRq8NIm(^+kjJ2;52Vz`75_d^FN>c>&DJvknmYKrJ{!vMos0a(_JHxoA9@oL21#&4^Ula=NQqMhsaj>k#dO3UAq3C8ssm!R0Ci4y61E7VA%N;4p7$wJmMkks ziqjB7QBo00^uR~q(DU>61XnQa7IIcW14JCN)(}N0#s&~_6>+J4^fNRPN-d_@45a;> z5R>j2GAind${=#1tJVRDkdzEeE(BNPix7YGpEmNHcSc=|rw6GnWMv@*c~BubE~d=! zTnyEME5tA|^RD%W?ixgZeYnChA@rlrya^M^$_n-u6mgL~hf8C^kh=a%D#{u`GaX$q zC8gY{LEfl{VkI3321}G$I9@v0GNb|hbA9pXbTd@s6dn)49W$bnTR^m)oF{otWw3Sc(WK zZzz|Mhc#iLy7UIHxK?g!FPj*A4#{n>_=;N&nS5FB`yWmWuFv<%7b9K8Zlm70bKT*^ zRs~SBB4tW^UqYw|yV3pV=z$pI=x$C{5H%WOiLeq_WU=98WqAX}kH0=MbNp?K@)j*x zl$Vzm3LTK56sY<-6(GXKk?HV6hhW&M#S;{6ZX@MU>{!iil=?L2Ql>Wt1o)QU4J6ho zKWsu{U0h<`@l|O=qmr=h$YtKkavCS5zMVgI`gHPRQ22?%cdi3+#I%(K*ejlyLY3}8 zgm9YFw1!7sG1{>?3!<>4zapj-37vVjjn7=MVg-!W#t(2QJxYRl9-qu7u8{vMW(v_N z^K|lKgJPzyZ*p66E>>x=M|MlLPsU>9dC3tG5n(C;q_0`25{yCCg4opLi_U^PD@clh z;144LT3S-ioS8m7rAnjoeY>suX5__by+*ENY6(PoB5qY1-FYX8gw-7Jo&7}vq%Uc~ zM{#E~>&ckDTL@-hR#s8b>eU0w-nwo43K-|jTQO|KFxl*m9UJh?@p++0i6s+W8PN5q znV&zmEjhWw4pMPdt=715feL9Ob#SCKWswpt{AMy7z0;T1rZ=@kL`Tqb(Z{1EB}Gc< zm)@IBsXiST4YYxeEh1oMds9o}#4|O4%m=oX`jtk7_8K*6-8w?-N_x#5I;uc*DLrBW zX^f)8T&q?W4IFrR*`h^~QMS5b*vl`k=pj8TxZN}q~5=LxU*-Z=pQ3L0tv z$~ApUM5WZBUWwwX2?=Gogv95_AY!R)%9%kQ8#XoSJP<{wpYpHqSDr?>c(%MeAYx|w z@Z^~-6YF3stgI{@6XY}Pn>+8klRR?x1fw|}I*PHwTHVMaMqyThh^Y=N8(4PvTQI&X z$Q3VhaodI!8^&kilvD*~s|5KHIt>ZIt!>iRj{Ex#0-Q4a>lkJOnR0w)#8`Z_u`%J{PCSpqYkfx(Hu|)Dq0UG&pH^1Iv{2h4NQA$ z;9Hkpe)$)&QOW4JnyqeFk-24j-UK|6)vxhBHDiP4dN<}oL`O%5HJ6uTmlWW#NE9T}FOIvAULRpFQ++u=!(i@Pyq-f6R@BZQjTFDjy@dF%4BmtF!= zl=C_))qND?ZFxQ!ap&X1<0;I8a~i87-d`3S%@~~IGRa({_Baow*J{Ds) z=8*}gl2k$pRdbTqDt`bWA(_m$DDAD6XfoHAO-lw9-eEp|GK3!vC6u*-Y*ZX#F#M$oMt z?lPMH$_dm|EBPj4t;5@w4GkkcWgtK&*o(X(4Ohl$xj z5IM)9D6WipX3<+Fq?9zWc`J4ZQB4^{jH=Up813*zM%uDv%c7xD(*e1MWl!z+Ov`d= zI#*HRPVZUEX}aSkO!`(3Dpi^Rn~rjEUEF_>$L5HL8N(HKW=`BTX3W=Gy5iRw7`~Ej z$Vka3^_2ESg^nwEM>k3y$787KcNCPRP~Unaz5(bCJMOg9Cn^2}=Wwq4OeLZU}4jI(ClG;2B6<;!p4ioMD@(UA-( zN@YzKvBQXYRgxTyM*`X2I1wSW=pl&H2!Oof@X8Y&@9Q9xJ3_cpT6S}&l&J~<5(S4V(cN}Q3#+bZ!KGt?}WHlt&~1iDnW4OsMrbd*P;;-j}d`mwIx-umsg zJFd;7+9@bQ#tbh8JgyYt^Gxitm6wnoJjN>Xvg6aE#AW3iuv5dlng4+}Jze%GJ9QZq zf6Q1dMb1J=k(rR7p(~9iCBALhGiJ^tgS5{~ts8?wijdLXcqS#gKw8X^tnit&E>^!I z3PhP|LDGcKnA@ns2Ym6C7>B{Q{?SK2yZ6!09{r4V>$lftX6EIUkv^yZ@`LAMs?Tfg zs=1B9MTUmzty_L#SR z{k`|zdxP4&pZ)H$M>bp^b3U!iXM)ezjQqJ*Mq{RJZFHiVa~MF)4I_?{9uz`Ve%G3g zIaUyy3TbJ{$!ToN38QQ!ee|v^Ca@~5k{_uE#K^3(x{_wE2q{zG7uD?NC1E8I$7Tcw za`?=tv16=r9~4EuDxB4SvP}@J@q(9R%oB_K7qc`FM%Nc>G^RtfP2X|+fPDjoeL+LW z_3J;o_l75)cw+6^Cr%zZ^t;ctlRiT8KAJvu>~|niR<|WHfYDryWW-LAqVl4vLUOt! zY$y-&4kkdBBCud!PmD*6&xP{MGc5z0J@fc zpLq4a;K7`3ru&`>i_XR+VI;I>97$rL zi8-ed{kP_z2Q%AX+(OkQ9ukvX5nF6Ls2$w=|wP zlEf@b6zg(KM$-?-qaE2pj9OLBN>=s>@iYy{>1iAzRs+WG+c#{O#hrQcKEL6K1AT7c ze7T*sTs3778x*Yh$=E$tJ|ErIlFV!djA0B6Hw0H#d&>b!0_YVI`9Z|sd>K#;VKTWT z0O{JYquZKD9J78rtGKN=IT`9?V2YVmcgu3gh)?QOiR@j!YckG4X!22c1dN28_Tf#9 zZzH7U?(xQz-86usHrgHI(9^|zPk5GHuhQ5fW2-d;)o|025!JXngWQL?s@l2r-a~7T zyNrTdu;w2hc+Gu3nobqRR!g59jEdaq>gq7&H`HNj<^d10G2`a)l9o2S7Ncf>Bf1S2 zRIxgICWMUY1PGEqBllC*XCQ>0q->Xui6@;hGLp`CUiC5<6ghDDnxujnIVE*#-hcu7ULJZt(jA*CegqmG_OR`-GvE2mw&c$88c5id<8Q@VCre1Zve zF6da}@`$aXNPW{f;X!D>d8GAw-N(6bv1jXZ+5(!3n?SKbCbxdBi%7(g*=dGG zmTDp-x3xvLv^33#ZaNknkWi99fGHkc+s?oofP&6x;m;VnV)1|~IN7owRl`|WwJsQl zjMbhcAs@^B5FvqVJkv8O3vXOJ?Hbk}k3LGYp&xZv(;T`SzT)uV!xyK$cOpLiUl>)? zC56Woqzynw)ja$5z1)Ms_10@Y`yJ=LkB!x7Vgbq6X%n+)N*QMx>OlL(b+lG_c?bL@T#BN>t=%b$FO0zKFCUEGcPg zYC3iI-ONQQtCZy6o?KJ)?-8Za>1pGVwO0GgDh}w-(UnpD$Sg|q^Dd;-0TU}W2C^(i zraJquOL=%S;vLrDIEb{7dv{&4QjE3_L8rZXUKPc~O<>kz^CCr`eJajx-SGE!e|y)J z(b0;A)*E7i2}YK~c@Om#qD2ip@nntsbBxFsK$JnXWa3X#t#5WyNy*&_%tC5f**7%@ ze~g$~Uu^@*6oBfo$ih|qz(|b74|%Q&1GnWN_4EL6NYw%D!)LbKej3J=w$|bBY^i97 zSgG5-`R4G*i`OKk4g6npB=96L-N-~vnNQgSNC%j)UVH7EfBHF@p9q;e(}vR$$o;uY zHRgKPQ<8IlGB4n$a|j{HjK3A5c<&!`h^YGG+S=mewgAnW^Luh+P901QX(;z@LCH1- zM{M%P#vjv@1C%|4s0)8j>S#FY4dXIJ9oHcn>&_*u(prbn=qNro4wp}!ckea31mAZnDoq2X>@q~+03QsR!LV{|8@#;=<084}3)z>B!u;crYr-R%`5 zGJdme)R*tPbMop*yXkirRA3U1rlJ;$Z-1=jJJEfpn6hlE9=g?-0|~k?NI(SArP#*7)(Szy9XW-#C^%vweASdvQ|&okT6h zC9b;0$~qK2_HmtW|R8=v{pbOXWhvWW`QEJwpH|rcLWL4amcXzuEf@dVaH2Ix6Cf zx|yARo;diigKX-07@;KfAc{~8Q-zVr?)5+X?XQ3Ru(5r4dvY=nFszw8o!rcF8rFoN zq%Ss1xM_>dks1V9LJ%Ln@`r{|Z8Vi4Zg@NCgab@&YA1!*{7-ofYhaljk*UfZWft!A zGld;dM~GCjj5Fj^OGE;zJTic&6ATpcts_SbVso)4 z4nBg8*r*l*n9&-p!MS&YRuZKcH@x{bAR7~Awg+h07kv&fx{(8`lXK zX9YwA6c_W787wNEbOufXuuMQuUt^WXZ#?B==T)WeJAIA+>&i%t+yED#}>N;Rq=|l~1_=7D!dxjOJ*JRS}bcob>2q zW`e+^<6)C>^2}3DUeN2}#c3CNjb!n|Q5ptIP+hl=8i)t3D<(_|z z9C;DMJ6Y6_CrDI6L=^)!Q=RjZPSA2Lx+{X#(1 zxRwn&-`$(xaQ(0xf22gD0cRdB89k8M*+_|w!&~0Jf63m%(?-7d&Xk|t@(L4?Uw*lD z-BuWX^v)mu^2+hY<~%IO$1l~Z2p6a=!nheOJ&&{r4AEs~vL;|fj~**t9x!at7jJF$ zI+NNoe0h5@HCsz^aXUelRq+%lIyRQe>$ud=5)ZZ5Z}~&EO={KTDtXkJMpWG#Yr;1t zqdUfGZb?m3D$QI7Cn%cm&6%=<0xbh(v(&{_Rk-$Re!5FdT1jSOca?Ke+ zEsQ{TT}zs4q2!aY$iu(n;!zT?G_S&&L9yy;SHcK6WE(>P%f6a+bY-_*H{as!i}K9x zH~sW4fBDg0{_>Yse&1(jWaOMV$LBou*l|a-43tt3k7OAq4aelE23mXU5aD`;%h#`; zx1&domszRv?mZJ*hBq~_P#nZ!qE0G7k50S`=~}9U6eGGQu=d6S`GJaU%XaFCDTUHV z{k+m|6MAfbjtmq)=8#2Hgs>`4tPDOdpBpX8W7*Xa*~^Yax6N#Cd}9HpU-@qt)W>tS z^fS-={`Wtn_36`RC%aKR_Sj={*qYE|tEdN}=IEH>k&Z;zvb6D;Jw6uTywBHv{`uAG z*MEE~t35Vsc;KFishq9K`C|khDol2YAF} zo~PvldX23|DC@UT_A{!J2{~7g|hY7%gW&7s!xo5U1f-%|mWnw6DjG_497M^>f;%+}3~o=&iS| zU;phd{_yO?saihGjkRrBIULf)7#3wqf^TX_xm-y}MD<)TmS>P|axcHTS&`FvQN&kk zns%d==b&VA8yb4-SA-QNqGV)3m*Ls!=$y9f4qPe=f3{$_ zw7E?uqbnx&*lJWDv#dJTzpyl@RO@umk++J9^7egfjGwwqVjAN5kH7uu&3A8{nA##O z35`k_tg7ZTIfg+kxGGtyVzotoJSy#>Af0EW6pex~WPRd_Kzw652HO``)qO&Aw~vrvXSqN zW$&Y9_J_~E@XrOI?0@;@L!WdpRu81>i+bTeDCvagS6W!gY9x@k1QrdHjw19lx#gn- z)|ZD37?AhY=FJ&r-e!XiSuDG(Fo!Bbg_eet>MLjshue6fQuJ=s*Fse3BQRo;B~N_- z0nsg-#L|W{;)}9&*{JR~2andsn6ns#NmOOR_QPX8`}qey@sEld@zp~Qf8rtQd|=ZJ zSIDIo91?~Hu~b5q_Qxp$v*>)RM#mju{BJHdn35t~G3>Ut-nxAC>eqDI{F&P)HqufV zxFBC*s0ucyC`ju@V4@yM^FvS=R!p{zFS$@1E0uF}fi;AnWrXyW-Eae)ePCfA=A?SJ zkQB4C17^&0DR~a$``_*P$>yknHTOUCulxG4C#9=of8$9>kwYPx_|%vrJ@}B?o$su`_w(Rr%nYjpT zdIAhXSuP@8SX+xV*MhAsM{_!k*sMjALR3c^6ZLj&g7qLRscmf=v-_|sEw*H5I}@nmdCiQiGF!G@hOE<&QD6fe<`h^Is+timls zn&NJ{Z$O*+Q#4gRVPOo_<<>WQH&gX6%-kjg4N@k{gcnmK+0{eGX8h!zf9`6kM$6Xd zgAcemE`?Eq+OS27A1g~i2C*m*9VZN!XNaQ2R3Ckms$3$Ly@ZU4OmP*o{#R+)_or!&K2q0|#iYduL5LaI8Jw)i#}BX_uA z4m;E_US|_5Ohb1zbISmYM$ed$Gk5Hh4?aBSlMWe0sBO|7d+dOR@tI9xEOZH79SN&a zkrKe;j(8*O-bX*)k;yu<)rk0-LQ^4UCKnd=uNs*4MdARK(QWp+(JNo$r7EDgXnmFR zp)BBzs*Wp51#Hw+Nl`-pL>+#|Z3JMt#SDSDkQ5d$hS2wJPG+n!06*+7R3a<5*+|La zi5cI$``rI@$&MbzPv#6hFxcJm=YklKkoDvyBc91l6)*-Cy;hc&`SI1lQ#if#%oV+?&xc~G%sEH$(%Wx z9y3T73k}Z*<&MgZ6y#vW|Rl|HS85Vd|- z>0ARdRO%&nt4!Abh$|-918njK_tdE*SE~YrNmS({N^Qb-y6)9ioXUk?bK$@_e$JUxnWL^%U{qY%fJ}OiJ2Hu-WpS^) zrq%dr!t8)F#-LLDZ6W(1ontFmAxcJLRCsiC;jrm-VZF5qL{Mr_u9k30j>Mv=8C2Tm zXuOtYPN^K596-UqM3+J0kmi$Sv#i^C;Wsa2oPPJYhpooxl00l{#-)*)4y>KB_La3$ ze(kW>)!ea=qc04q0#T4rMOj5Hqc)J~#9L zo$%oc&uy&v$FFclSGh}dx$V3)cr9PVaq#5L2OWvXc1Z$cC97mKMlc!c$Xk?$gjxNA z`j^^f1InY^_}xmCe?o+jQl7Wj&ada`x>%jz$(gJ|v=cq0s9J7AZoO7^(iCS+NOTmi zI+Rk;>{2JqS(?pd%0pxE?M!z9h_Q-}CxjZJ&deDtsn0$cIO4w^SB-;dav^J|>E+T- zt~+q@;3JPLIk@Bz$5j#g>y)voLrMnbRNH}o}DR7M}`g6Dwu9oXWk}bMG2(!H}sU(8kY8^0KpROO zz_#3eSJIk09zW3Mlj}ZlTL)yMLeAQQk8IzyYkRL=_#?;6g=8mZ3rh(TGEK>7s*epgS}Vb%>Wxh12coSeMPo(od_4z1Tvg0#sR zMOEf&=vq`)Q|4(%lL6bQXT8ac8p#9DL)T%iGiNl;oROW~KI6mNf4+Img8TXE8#SXe zNtb>?<`}&8&?DP-?~a+q_i8QF#$HBgmI|4S)$Enwoh+T*q=s}RBPTi$fjxA5dqdDh z@k2};l4owLn>$g%z6}i(aACRq&Jt^L*6@lfj7 z31#IWEgGq8PcELR2d4C_nZYvC0U}+i_y4qKzR#Mk2AyQ(sT%u-euAWtAbv7HtRI6(by|{gMVq#y;w{esg z$&7Bmk+Hg%>Qs6VIdJe`;8MxCBM8}K)G%2ayDaJU_ATXckDctk$)vh+DM-_^XWolE|0NXnuS*PiNa1} z#9!};J%cZc zE@B6v4&4Y!{ai>k9T2RrJVLt0T1Y9NQG}q4lg~6ZHYME6o)rCZa}#`(N!a@;*iD)t zAydf>2~CXjr+U-D=KL%M^H^{#sY(FYbk|OBZEU>f z?IAsTQjrBkY5VIXONcJqwlBG3(9I{OoMejpphw32`wJY`6$?3qiECC+f5Q|nv?dXd zlE_phQwCXhb83Vmlas5>yc+0rk>)G`u5wL z72mIZBE1p@m&1bhc=?1*_n$ufgDV4=OlePs3`8J{WvbY!`0UlxXY--h@D}RYyu=S_lh(+c#{kh zm8q%|rgNQ2O-nOWqqJW&YYi+tz3t4z+lOw8^@a8F1ZwjpXoY+c>y z$&)XeNuCr*6o%xP5Q z$O@yPe6;EQG}=mTyRO-_cM0vwNlSL^VyRr;RYe6!)Z~R+E0NI;9jRA?TuB-92Bt}Of0@qwfDfg#C;O+dA30kz#d_rriH)sb>l}7{W}lLZiuyD4 z_T2$>M`|)SD_)QZxkK}ZWSr+q5NKn+8=BK1#^uW?a&j6OI=<3vf4cI@yPldmcW&?* z_8U4qrso)CEJoMDeL_!cVUqRew4>LsbnfUi*Ua9vchcUyyN<5JANMo1>WEN{B+r4W zq*3pK<1RF9h?x9aWJWVn-RTn%bVu8mB`_{x=aQ9Gnzd2;B(i@hU(LZ@OU!@tf-~mV=+xNr)2DO3K~6Jg?z9IqM!)gK8$WxJ z_FoGYELgK<&GfMue5(SRd5#$~#_EnSUymsb3}?#%W|QArc@)6eqpz7g`{?Z1vvp-&lf}m^(-yr9G$Pf=D@y&bxcrr0bd*E4`sKbqpxAb zoDlcUzJ@mKJ!T3R9CyeYE@2_cDKOg6(#_Jl#^s^2=iHe~%66rlwNky{&vesM%v?Xi zlmJCckhIafwyENwrsJu*J@RE|hrY1~yRP9Ig*X9d`UxOE`0lQ|o?P(Nk|kSr?G+!< zQNHyB%W&iaV;tVUlP9^jyR>hEJQihdcHdXD2-N`eA>nA$7JnnHbqO z#*mM&M<70n`|5k4GPJ3qKagvBebsBp-mQCSySD67$i(jAQPIx`^_?909stMT&?7o2uzsQFnNIbC;zw;4qMax>OSE&y=r z)~$PI?>&0-8ZPfi#VWaun&EZcea+?;X`DQFao0sGmF17D z-aQ`~Zmw`<_xuM7?N?1W-RUOjcpzlS^fA|->?JH3xY$^ZT_1U3d*m6UM@aT3=ev>= zcC5vEjs0lNmXUjfIEfr^lq5%GO}LTw0A>w7J?E8<#E)}XS)em=>)v&D{^-tiG6CFq z@2+VI#VJ7?xdwCu>9NF)f2I?y>l1znNWG)~1FyAK>JkD8B7s4H+BH-P9^0~0Z2CGD z+XGSND!>k>L`}W}qSGbW?r6;#B@RW^-S52zVNptyLYF>hZj|~^112bmvCG? zAFo_TjFnOGD|anfGHKG*tAF%M+K+y;_3Cw7zudZY*ENZJZLKld@xu6j1L~)q|3}uU zD?Uk}v5Sj|rIPnOh{y;_tXqsT0zg06gcKjm0xZ8_#eig#S%a9N(ss`Wy}nv9atV=2iI?6Eg54#_T`+sncZK}DT+^c@;kWmM2p{7DxwRwjHcS3sfG_ULkJqC%8u@(6h zK>lOF$nATPaeq-!RTf`hQHf|As^Wq1nO|`LiV0EiyL-UcqsOGHxlGzSY1iyYFiygq z2XdAi+UV+D%*{F=yIQUN^P%EkcD{cqvKH}o%>u8s(C6M z0*w{vP`c#}G7@TxP)p;aBj4u*C6BJTVzSz8RfJ-MQaa`a=YRLXnl)?;Oy7up0*v-m zBnpn!TxRaYSQ!)-llkqA^*uOa^NY)0VlSt(#NGQS<#+G)k7rYg4o0&8)ikc=wfB%|3WfQ*~6`n&=e*_qVcZp`D8_JtSP+glM= zjP>kXUynTQx*z^pV)dA~n_Y z$W7(B`x#hwgHKN)n(YWtBI?TG9^wtr#+HRpr6LN)TM-N*8+6);B1>Mi{>`JMJW`PE zMM5Gayc7#K@YLLj{EQm9r|Qxc+J9spZxf4*A-CzGmzFzR?aY6Wd##oY^d*ekc#!WGE|KkYuHrh z^~hFPF~GQTKh8vQD;{BbSXD7Fb)XUT{2@mIOJTInkpEupVdCk|jz@?+gD7`vHh*;6 zcvnV2GO@k7EG;dqU|{$_wyMO>#T-u*@UWqG1*5MCO;vXH~K zSJR0gZ(x=zbmPlQIN!xJR_&Ic^#an8$q;zNrmN|wr@Xh#j5WBzYe*oUT%qZxBk>3+ zSF}Tr9M}$DM4U19qw#EMu*hU&#lq^cn3$N|G5+xb(J@Z(6sE4tm^`E&J`>lT%XInu z4onJgnP*4S3Q;C{K;+;VAE&iosLc#|Bcp^gMC{e{RNU==v`1)TSy7Ca)V{J?Lz2FaP|zF{o$*F`2v zuIxngn5&r4(S)qPSh0T#s_p?v3lF6TX{DuF(&lyJ2iLRB=*t7dSo9i`!zYWgk76_)4V~y38X6_^CLi7Obwz}OhJY#3Nft3ox5-yk`wN1-K|Th zG62(bja78^l6xVB@a>-&($QLnrC~vy1F&PlR54U9uXlg@+YOm3dJK4LH7c%N%~x_g Sa`hccw(kxNXLrXq=l=ug74q5u literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/jpeglib/testimg.jpg b/src/dep/src/irrlicht/jpeglib/testimg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b34ca5d3151840576b6cdf33c3d52d0368172d4c GIT binary patch literal 5756 zcmbW&XHXMPn*i|8tMo_<9YqKNhS0l6fFLE5&=KhbX+c60rK9u!p@Y&}04brP^eVkd zQ96QxpdeC&^Z&j#cQg0t?w+09FZ;~S^P6qg3)iav1~^O`1|T8=0EqrJ!1WS99Y9G= zPC-saNkKtDMMX(X%W{L3hK81%iJ6{-i-U)oivtAW6%-TVpOR857?!O_Xt#TDiA)EDFD9}pNG5g8Tz@>NW7N-8cbJtH%#ps=X8q_nKOqOQJy z(Ad=6(%RkA+t)uZI5a#pJu^EuzwmK!ZGB^NYkTL*?%vUlpT{S^PJf@B|KlP8ko=qV zcle$eGj-6py```5~c{EcdbbwOv#Kl7@#s zJM<*=O+o0|t)qWv|C0UhU}66+*?+&X z!_{KtrmR!-Go3zbLI(HAIP$g8bmuxKcq#Y3c5~p2PqWz&{UTHNgz8e=95eq7E@AHhT zgr`HYx%umHH4{H8@4|IxLPei#l$})R{Bb;y#aZ0u-ZV85k2tHq=(nH=?UiFlw7$MKc&ZsYHCmZwIus7|gL2hpKMvTOla z%$yU6BZA&~FQM*OYqBa_aYw-rI?rKDMubU~guoz5shzwc?}eF@tODlm^@vxx3^mmJ zK^ceUJy7c?FvW{j~jmI8j)fVwn)LF z;ynwa|7~Pf7sb!DG^&(Z4LCoa+KKk@EHia?E!;Df5AI&pYr&?4}TE2Ern$8lbPRQ=vj@p!!auOKz`wcbHNDQOe`kd~(>KdbCKPZpTE7E1A{gbR$HX_u56 zPYc<|$A8sj9ZBL$BNc!Asr`cnkHepx{MqPY!}b$|=8EWbsOf$X!2eQqAmA0~Loj-ruOx?r{Clf#d?j$){^>5{FRNQ~GA9p+?R zZ4Pn+%2H9a=NGHNH{iuAkI92a1NQUwIb{4CxDke!<8o<+Ho&R<9}(L=qGguXrSJzW zI5r$wa)vH?A>lYDewI=b!D4H$8QP~4k?N5czM_9zmJ4d6#tmTD%Ickc5XOH#6&lBP z=26NGR#yK|2mGXT+>4XvC^IoeYoD9Esc})D`12QEXdakQZh~TpE^>C8b+XIL*~BsrZs;>bjo5EjFf2zUhRM&h zBr<}lA$m8S8sZX~=M5)p$&8zxc?In(7Bok2Nn@B^H+mX@9JrcEnNz--3cSkX3^O6u zlg~mnq?v8HO#8qfYKkF2a|wFqpyqNToSbln{KD}g$_Caf!3P!JNhr7plY&${hl#`O z^=pkaqUp?w^$y^a-%cI2==YJn)1GMqy-2sL!;eX$AV+kkU5lSE1Id(KSpTU)qQ1KBf*#E)|HGi+|*-Z0AT*$(=%1Qkt`!-!gxb2^01lH?nK0 zXBM6kYMIW!*WjuuSa*C}W9L8EPi^=(x@)XMPwPP48$aYrB4X>YiZyRj+LMY<3ybUJ z4%pYncK2&3&X1bb$WL!$Ph}t8RlF`$NXz4+Rt&%P0Fh7gZq183NP0 zVXakw`=Ajb-sus-Jsa+5lv-3YX;LJLFY?mUB*@=Fgas66*-%*sv(lEb{O+F}gY1+N zoR*;ZG{fuP?5LFf_>Vr|d-6k-YfKX;%(j*DLY_%nh7$B_fMCqKwDA2YAK1s5agbHO zw)1?dLVD(y~Z(s`<1Ua0IM9>SH!i1f(7mPSCqmCXZPAF1{Y zbYcHzgU@TmTgX?#Z{^Mn1=5qmk@hi7UZnF7g@oqL((MoK`%go4d0g3dt$pj;Cj`pL zUQsBunu<+mCZ@WpSbTXV#hZLP;>7C6lsudNX{q)iEW%qNm7Pw@DkaYOu#9P4Tc|Cb z{=*UQ(cgD>tLI5vN|)5wvJI#8&vMTC(BE@kHGLEx8owoQejBS?n=Qh~=ZvF=Y0%1q zT^ae=_==pd$PS_!=K8b)$8l|GxOm85NR>+I#({>m6-Y7>qa&62KltvvNO_uDnv zW#lGUHuvu~?kr2HfVsSM=#RF(?Z--ABK4e|ScGc83Xk@`IevO$70E4?s_`r9ySw%{ z^p#8!VDq?Cx3muvuar%$KK5z7-6D01YrL*&V=X2cJeh$>VsGy?B6N~6Ph1#4sF0)* zvb-}>YNDcWuDCZTc{x71Stc!xI8%FU6#MFHR6o+?OG&Zbvzo`fXIQaybnc%H;fXqE zi1v?sHbKk=OETWZ*v2yV_t`wxjr)GWSIql4#(SAdR4^H=otsSjpj9hR^TNf7>>t;d zcz5tX`ri7cNW%-s7t{$?sqYuaU3#pvCf~`@%mlk)Nz*g}oH^BohUBE&edTVn30ui% zKyNoaHVn&6o+)WOv=Fp&cFvUNC85aME=*Gdx=MV|RCNh1O&jtVbLm=18CAy(83#Ox zjAFZ7?E)NFDwT)EYMGrtcU1VcGi3Qo9)5v~=-|w}t5j&3IT|MOzGz(oRN|eo+6suX zQkzI3wO$G>A6-cqUkQMo1SHqilrKLU0R5^qLT0ePX&i(2y+6JpH2KJ4N0=i)$-&@+ zjwCBos<#IjwnVHX?*@1^>HhfG{--pBX_eqSeNP{U+*{vy0$(W%7h+R$|OG}owZylVUXUg*e|Jc7irXxB+s#f)0RRn?tJU4`DE))@}}l> zl^FgMow|kSUsUN_nlEZ}lO`o=c>-W<9=`@yv=ozqV)C>(G{tsA1GC~xX^Szzkm3=C zg~;YX74=;`U-ycE!l(TC$RUU0N>&m37*TXKjPmsB`J`RILG~Ao*Xgcj(fQ?<^9-qm zn2nNvGU9rWyWF|)-z#nQLmuF|f}<3se2F3M;ju83ywp4dDtZTu>1e$yOmmhcPSbXe zGMqIZ2zc~FZg?aiY3b>q5o@-C24%$&j&gWh-?On~*qSVXitRlxg zo%k`-Nvfa)J$8;@%i~mwxJ2jfAAeIBud+AeYkj9Ru(EdzI7lE=d5bwZDK*#OpjEL3SvPyhAks^jr)njc5x2h7_r^TbsVBeMSD7hBymqGJIY zD!G^|p4wZx=3X)lw%x!++ipckvsF1I9e@(Yg9smX}$zvtPR_eDS( z_3p-lj{2WmSVtR>^GUVE@OSmyx~LWL0LywwNvyUZn{+K_KZTd@I+@Cki7S(l;c?Hr zZMVjekRWc6We5Xi71Cq}5z(ApOA2#%Mz2byhaI3iV|{HjRO!-2Ru^docm;!bwR$?_Jg9T7 z0U}(|K8XIZ;ctt5QZLnph|BI?*t7G*tBLOOjeus#6!tL21KsnlQ0w0q3G_3w?1E*B zdMJn=14ZDh>JK+NM;VNpE4m$_HSFb};Ikal8a@BB!k~ItTmupF)+vGI=Pe-@0okt> zeISBJP-_RnMIysTmtXO8SP$i?jnfnvd#l;ela=*MAzVgYsgfHqC@83|j#7D?_~+1w zlH(^U!J;DgP3S6-iLS;If^x9Mru66)mS@H^*dt`AbgKPodEG&%p8A**M(+_3i1g2k zFuBFJ6#^8TiZvcEr&ohJmbylnLUf{OXdir~gboLapQIp^v9#6y@B zb@<6okqAHJGSvvOHq^B zeh9_H0yhUa4CRCfPc5ziA^QZNq#3ZWWnkrsLiy@-qz0VJF33#rBN*27DFEiJE0jej z-#ra9nYR3-Itf?cjtC52HUS-tq8ozVRYXL}@KCmChKbJq}S$RreJ5KsQa$5)CF( zVA}K)0}NH9bHqt(0!;^01Gej{Poz_XZ<@$Ex8Q%A?V;T?=yu5Y->bB7#eT1Vjy?OZ zI_qrR;`jyC!aIW<1T3zIv=}aIEZM@?*V{(v^ra`Y6^X1!^5dJtSE@&}n{})ycAah|8ThJhaVDOkd6FvP4>PC;fDMJP=I0VRU=# z=&Q!li<_nb@>zF4Q?t1tV50|N?1Vdpo^5%!46qSw$0)>J4pnxkmDwh+e4I_=rf}yn zV}hwgkh<1aE|v(Ut63~;N!i7={@VY3zol1Y**Ew?agc&iVc9Cy%CR&oYsWZf9_`1| z-D-BAJnOwB=~wle*UW$nzs7m-p$&|Jj7_?`&q>Hr*J}XFZ)2(o&AuX|KAi)xDiPNJ zrq>2Rrpdq4yJQxb8zwwk>y!jZw)Ia#u7bgfiFyqYH*`niyXiBYqiSD0 zgUP~)^7v9y>&%@Zr;Oo1WMh3kN}hC=uF!L{Eq++0(&0IIy+nVdx{!$T#6@?k-d(laezRBR+Fvesf&p104Dc4rWBo9xMy$2LAA5;nm-t4bvd;?}UTY@u~2 zJP=2Xi3|sfYO|C`k9)%PWPtI5)oBJ2UZ}BB6k!3U~vl; zK+?ftnAVf9l{XXTKgxnoiA-)%)ZYMH17e~+I49Qs{lkCOcW=jlu?Mabo;D&{?sM8O zeWRE=CBGzta;3II$*R+LGz9`OhMxHTsgrQj2F@4IA4JB5KC6KC6MD5MD5OC3NB2OC3OC3PD4RE5R?1Y?2b@4nB5}E6‹H8™G9£F7¯G:¸G9¾E:ÅG;ÇG>ÊG?ËH@ÐE@çFLíCLëDKëEIîCIïBDñ>Bô=Aø;A÷:@ô:?ð×?<ËA7»=/µ@.µ@.´?-´?-³@-²?-¯@-­@,ªA,¦A-¢B,Ÿ@*›A)˜@*–A,”>-’?/’?/‘>.‘>,=+’<+’<+”?+”?+”=*”=*”=*•>+–?,–@/–?6•>5—=2Ÿ?1©B3³D3¼D4¿D4¹?0µA2¬F8žH;‡H9oA2T8*C3&=5295495473271160050-50-72/72/72/61.61-50,50,41,//-.0-//-//-0/-0/-2.-2.-5,-4+,4*+3)*7(+=.1E69P:0U?1^A3jC4xD6„E4’E5œC3§C4¯A4µA4¼B7ÀD:ÄE<ÅF=ÍC@áEIçBIèCIêDHíDGïBDó@Cö?Cø;A÷:@ô:?ðÕ@<Ê@6¹>/µ@.´?-´?-´?-²?,°?-¯@-­@,©@+¦A-¡A+Ÿ@*›A)˜@*–A,”>-’?/‘>.‘>.‘>,=+’<+’<+”?+“>*”=*”=*”=*•>+–?,–@/”@5•>5˜>3 >1«A3µD4½C4¿D5»A2·C6¬F8œI;…G:l@3S9*B4)>63:6595484382271161.61.72/72/72/61.61-50,50,41,//-.0-//-//-0/-0/-2.-2.-3--5,-4*+3)*5)+<-0C47N8:d>=vEA†JINLšTV¤aj¥l}rŽ‘{¢†€®…¹{„»ou©[[QHuOCiOFeOG_PH_RN_[Yfnotƒ‡ˆ”™•™ž—š ”™‘ƒ~ojkY][LVSJXSZVRaXQa/.,/.,0/-10.40-40-51.51.72.72.72.72.92,92,92,92,91.80.7/-7/-7/-7/-80.91/80.80.80.80.80.80.80.80.6.,5-+5-+5-+4,*4,*4,*4,*5-+5-+5-+5-+5-+5-+5-+3.*2-'1.'2/(30)30)41*41*52+63,63,63,74-85.96/96/:7.?8.@:.B<0D>2G?4H@5H@3H@3I@1I@1K?1K?1K?/L@0MA1NB2MA1QA1YB2dC2qC3|C2‡B2’A0˜<- :+§;.¯=2µ@6ºD:¿F=ÅD>ÙCEá@FãBGçBFêDFðCEôADø?Dú;@ù:?õ;@ð=@è@@ÜA=Ñ@;Æ@5·=.³@-³@-²?,²?-°?-¯>,­@,ª?-§@-¥@,¡A+A,š?*˜@*•@+”>-‘>.‘>.‘>.=+=+=+=+‘>,‘>,’<+’<+“=,“=,”?+•?.•A6–?5š>3£>2¯A4¹C5¿D5ÁC5ÀD8¸F;®I=™J=G;h@4Q:,B5,?74=77<66:4494183072/72/62/62/62/51.52-41,41,21,.0-,1-.0-.0-//-//-0/-2.-5//4..5,-4*+4*+9-/>24I56[97l?9|E@†IDOM˜[`›fv”mˆŒwžƒ}­}‚¹u~·fm¤TV‰MEvLAkMAeOFcQHcMH^NK\[[eqty…‰ˆ‡Œ†Šˆ…†Š|xzlfiXZ[MVSLZU[ZT`[S`.-+/.,/.,0/-3/,40-40-40-61-61-61-61-81+81+81+81+7/-7/-6.,6.,6.,6.,7/-7/-80.80.80.80.80.80.80.80.5-+5-+5-+4,*4,*4,*3+)3+)6.,6.,6.,6.,6.,6.,6.,4/,30+30)30)41*41*52+52+52+52+52+63,74-85.85.96/96->7-?9-@:.B<0E=2E=2F>1F>1G=1G>/H<.I=/I=/J>.L@0JA0KD2NE4UD4^D3iD2sB1~A/†?-Œ9)”9'9*£<-¬@3³E8¸H<ÁF>ÒDCÚACÞBCâDCçCDìBCó@C÷?Aú;@ù:?õ;@î>@åA@ÚB=Í@9Â@3µ=-°@,°@,°@,¯>,®?,®?,¬?+©@-¦?,£@+ @*œ@+˜@*–@)”?*‘>,‘>.‘>.=-=+=+<*<*=+=+<*<*’<+‘>,”>-’?-•A6–?5œ>2¦@4²B6¼C8ÁC7ÂB7ÂF<ºJ?¬L@—K>|F:b@4L:.A7-@85>96=77<74:5294183083062/62/62/32.52-21,21,12--2.-2./1./1.00.00.10.10.5106005//5,-4+,6,-:01D22T71c;3qA7{E;‚HD‰RU_l‹i‚ƒs˜}y«x}µowµ`f¢QR‹LEyL@pL@hPEgQFfLC^GBVMLZ^^fjnquyxx}wz€vwzokoa`bTWYLTTL]WY]V]]V^------.-+/.,0/-10.3/,40-3/,3/,4/+4/+4/+4/+6/)6/)4/,4/,3.+3.+3.+3.+4/,4/,50-50-50-50-50-50-50-50-3.+3.+2-*2-*2-*1,)1,)1,)4/,4/,4/,4/,4/,4/,4/,4/,41,41,41,41,41,52-52-52-52-52-63.63.74/85096196/<5-=6,?8.@9/B:/C;0C;0C;.D:.D:.F:.G;-H<.I=/J>0I@1JG6MH5RG5YF5bE3jD1uB/}>,‚;)‹:)“:*š=,£B2¬F8²J=»I?ÌGBÔDCØDBÝEBâBBéAAð=@ô<>ù:?ø:<ô<>í?>áB>ÓC:ÅA5¹?0²?-®?,®?,®?,­>-¬>-¬>-ª?-¨>.¤?- ?,ž?+š?,—?+•>*“>*‘>,?.>->->-Ž=,Ž=,Ž=,Ž=,Ž=,Ž=,Ž=,<,>-‘>.?.”B4—A4@1¨@3¶A7¿C9ÅB8ÄA7¾C;·H?¦LCJ@tE;Z>2E9-<5+@93@85?75>63=52<4194083/62/43/43/23.32.12-12-02--2.,2.-2.-2./1./1.00.10.3205105104..2,,4+,7./=/.N5.Y9.e=1n@3sB;yKK€Zeƒg€p—zxªu{·ks´_d¦TT”OGƒLBwNAmNBhMAeJA`GBYGFXKKWMPU]cc`fbbia`f\Z`TW[MUXMXXP^YV`WX`WZ,,,,,,.-+.-+/.,0/-3/,3/,2.+2.+3.*3.*3.*3.*5.(5-*3.+3.+2-*1,)1,)2-*3.+3.+3.+3.+3.+3.+3.+3.+3.+3.+2-*2-*2-*2-*1,)1,)1,)0+(3.+3.+3.+3.+3.+3.+3.+3.+41,41,41,41,41,41,41,41,41,52-52-63.74/85085085.;4,<5+=6,>7-@7.A9.A9.A9.C9/C9-E9-F:.G;/H<.J>0HA1JG6IH6NG5VF6\E3dC2n@0v>-{<+‚;)Œ;*”=,œ@1£F5ªJ:´J=ÄH@ÌEAÑFAÖE@ÞCAä@>ì>?ñ:<÷;<ô:;ð<=é@=ÜC=ÍC8¾@2±>,®?,«@,ª?+ª?+ª?-©>,©>,¨?,¥>-¢?, ?,›>,—?+•>*“>)‘?*>+>->->-Ž=,Ž=,Ž=,<+Ž=,‹<+<+‹<+‹<-Œ=,>/Ž?.”B4—A2 @2¬B5¹C9ÂC:ÅB:ÂA;ºA9±I@£NGNEoG=S?4A;/96-@93A75?74>63<4194083/74/43/43/34/23.23.02-02-.3--3/-3/.3/.3/02/02/11/11/21/32032040/2.-1-,4..8.,G4-O4)X8+`<0e?6mGFyYd‚k…€uŸ||²w|¼nu»dh¯[[¡RMLB~OArL@hI=cH>`HB^ECX@BO;@FBGJDMJJQJJQIIQFKQEOUIVWO^YS`YS`XU++++++,,,---/.,/.,0/-0/-1-*1-*1-*1-*2-)2-)2-)2-)2-*2,,1++1++1++1++2,,2,,1++1++1++1++1++1++1++1++2,,2,,2,,1++1++1++0**0**3--3--3--3--3--3--3--3.+41,41,41,30+30+30+30+30+41,41,52-63.74/74/85085.:3+;4,<5-=6.?6/?6-?6-?7,B8.B8.E8/E9-G;/H<0J>2H@3HE6GF4KE5QD4XC2_B2f?.n=,v=,|:*…9)Œ;*“=.›B2¢F7¬F8»F<ÂF>ÉF>ÐE>ÙD@âC?ê@@ð>>ò::ñ;:ì<<äA<ÖC;ÆD6µ@/ª=)ª?-©@-©@-¨?,¨>.¨>.§=-¥>-£=. ?.ž?-š?-–?,“>*‘?*>)>+>->-Œ=,Œ=.Œ=.‹<-‹<-‹<-Š=-Š;,‰<,Š.‹=0Œ?/’C2˜B1¡A1®B6¼C:ÂC<ÄC=ÀC=¹FA²QJ¥XRXQsRIWI>CC793@72>71=60:5/94.83/63.43.43.34/13.13..3-.3-.3--3/-3/-3/-3/.3/.3/02/02/00.11/22021/0/-/.,2.-4/,?0+D0)K3)T8-Z<4dFFu]jƒs‰€«…„¾~ƒÇtzÆmp½ce¯VSšLC‚K?qI_FB]DBW?AN;?H:BE>HGDMHGQIGQHJRGNVKUXM^ZOaYNaXO++++++,,,,,,.,-/.,0/-0/-1-*1-*1-*1-*2-)2-)2-)2-*2,,1++1++0**0**1++1++2,,0**0**0**0**0**0**0**0**2,,2,,2,,1++1++0**0**0**2,,2,,2,,2,,2,,2,,2,,2,,3/,30+30+30+30+30+30+30+41,41,52-63.63.74/85085092,:3+;4,<5->5.>5.>5.>5,B8/B8.E8/E8/G:1I=1J>2I?3FC4FC4JB5OA4TA2\@2b>0j<-q<.w9*}8)…8(Œ:,•=/›B4¤B5²F:ºE;ÁF>ÊG?ÔG@ÞFAçCAîB@í;;ë;;ç>;ßB;ÑD:¿D4¯@-¤>(¦A-¦A-¥@,¥@.¥@.¤?-¤?-¤>/¢>.Ÿ@.œ?.˜?-•>+‘?*>)>+>->->-Œ=,Œ=.‹<-‹<-Š=-Š=-ˆ<.ˆ<.ˆ<.ˆ/ˆ>1‹?1‘D2–C1¢B4­C6ºC;ÁD>ÁD>»EA¹PL²[T¥e\‘f]u_T[UIGMACI?<92?82>71;6094.74-63.43.43.34.24/13./4..3-.3-.3--3/-3/-3/-3/.3/.3/02/02///-00.22022010.0/-0/-3/,8,,;,)C0*K70S<6^IHtbn‡z”жŒÆ„ˆÏz€ÌrxÆik¶WWŸID„E=nG^CAY@CV@DP>EKGQRKWUQ^WU`XS_UR^TT^SY_S^[LaZJaZJ,-/,-/,-/,.-------.-+.-+/.,/.,1-*0,)0,)0,)/+(/+(/+*/+*/+*/+*/+*/+*/+*0,+/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*0,+0,+1-,1-,2.-1-,1-,1-,1-,1-,1-,1-,1-,0,)1-*2.+3/,3/,3/,3/,3/,3/,3/,3/,3/,40-51.62/74/80-92,:3-;4.=4/>5.>5.>5.?4.?5,B5-C6.D7/F90G:1F<2G?4H@5J@6P?5T>3X<1^90b6+m9.t8-|8+ƒ9,;/“=0˜?1ž>0§A3­A4µC8¾E:ÊG=ÔG>ÞE?åC@è@?êBAæDAÚE>ÈD8·B1ªA.¢B,¢A.¡@-¢?,¢>.¡=-¡=-¢>. ?/œ<,š=,˜<-•>-“=,=+Ž=*Œ>*‹<+‹<+Š=-‰<,‰<,‰<,ˆ:-‡;-‰=/†3ˆ@2‰A5‹A4‘E5—D4£E9±I>ºG@»D>»EA¸MG´ZR¯f_£qf‘sh~rdjj^V^SIQFLLBJF=B>5<8/95,74+63,33+43.34.14-14-02-/1,,1+,1+-2.-2.-2.-2./1./1./1./1.02/02/11/11/11/11/11/40/4+0;/3A32C4/J;6]OOymy‹…Ÿ“»”–ϕك‰ÓtzÆjn·_b§Z[”LItHBdA>]>>X?BUAIVLU\U`bbqnn}xv†|rulyoguh_k_W_P]\Hb\Fc]G,-/,-/,-/,-/------.,-.-+/.,.-+0,)0,)/+(/+(/+(/+(.*).*).*).*)/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*/+*0,+0,+0,+1-,1-,1-,1-,1-,1-,1-,1-,1-,1-,0,+0,)1-*2.+3/,3/,2.+2.+2.+2.+2.+2.+3/,40-51.62/80.91.:2/;4.=4/>50>50=4-?4.?4.A4.B5-C6.E80G:2H;3H>5H>5L=6O>6Q=4V;2Z90_7/h70p7.w7-9-‰9.<1–<1›=1¢@3§A3¬B5´D8¾E:ÉF<ÔE=ÛD=ßD@àE@ÞFAÔG>ÄF8²C2¥B-žB-ŸC.žB-Ÿ@.ž?-ž?-ž?-ž>.ž>.š=,™>,–=-”=,=+>+Œ>*Œ=,‹<+Š=+‰<,‰<,‰<,‡;+‡;-…<-†2†@6‡A7ˆB6“G9—E7£G<¯J@¸IB¸GA·LF³TN±d\ªqfŸ~oo|mmseZfZNXMLNAKI=EC7@=4=:188.44,11)23-23-03,/2+/1,.0+.0+.0+/1.-2./1./1./1./1./1./1.02/02/11/11/11/11/11/2015+49-7<23?53H?:^VTxr|Šˆž““¹”—Ê–Ô„‹ÏyÂqy¸kt­hnž\_€XZqSUjRWjT^hZgmfvvr‚tˆ~’‡ƒ•‰~Žv†yr€qfteZeT[ZE`Z@b\D,-/,-/,-/,-/,-/,.-------.-+.-+.-+-,*/+(.*'.*'.*',+),*+,*+,*++)*+)*+)*+)*-+,-+,-+,-+,-+,-+,-+,-+,,*+,*+-+,-+,-+,.,-.,-.,-.,-.,-.,-/-./-./-./-./.,0,+0,+1-,2.-2.-2.-2.-1-,1-,1-,1-,1-,2.-3/.40/51.80.91.:2/;30=31=4/=4/=4/?40?4.A4.A4.C60D71F93G:4H;5J;6K<7N=6P;6S:5V72[6.c60k6.t5,}7/‡9/;0”<0–<1?3 @4¢@3¨@3±C6ºD8ÅE:ÍD:ÕF@×H@ÔIBÌI?¾E:®C3¡B.œA.B/œA.œ?.›>-›>-›>-›>/›?0˜<-–=-”<.“=.>-Œ=,‹<+Š=+‰<*‰<*‰<,‡;+‡;-…<-„:-ƒ;-„<0‚<0‚<2‚>3ƒ?4…A8‡C:ˆD9”J=—H; H>¬KD²KF³LG²SM®`V­sg¦qŒz‘Ž{‚‰ws€ocqbXcUNRDMN@HI;DD8@@49;.46+/1&01)01)/0*/0*./*./*//-//-//-.0-//-//-//-//-//-//-00.00.00.00.00.00.00.1/26+97+98/4;63HE>_^Yzz|‹š”±’—¿•Ç„ŽÃ}‰»{‰¶|‹²}Œ«}ˆšwƒq~‡n}‚n~~o‚~yŽ…ƒ™‹¡”‘¨˜¥”ˆŠƒ–ƒ|{j{i\hTXX@]Y<_[@-.0-.0-.0-.0-.0-.0.......-+.-+-,*-,*.*'.*'.*'.*),*++)*+)*+)*+)**()*()*(),*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*+-+,-+,-+,-+,.,-.,-.,-.,-/-./-./-./+*0,+1-,1-,1-,1-,0,+0,+0,+0,+0,+0,+1-,2.-3/.40/91/:20;31<41=31=31=31=4/>3/>3/@2/@3-A4.C60D71E82F93H94I:5J;6L:6N94Q83T50^72e60o6/x8/‚90Š:/<1”>1™?4›?4›?2Ÿ?1¥A2®B5¸D7¿E:ÇG>ËH@ÊJAÃI>¶F:ªB5žA0™@.™A-™A-˜?-—>,—>,™>,™=.—>.•<,”=,“=.=-Ž=,Š=+Š=-‰<,ˆ;)ˆ;)‡;+‡;+„;,„;,ƒ;-€;,;/€<1€<1>5ƒ@7ƒC:‡D<ˆE<”L@–H<žG>§JC®LI®QL­]Vªj^§€o¡yšš‚›ƒ†•€z‹xm{jbm]SZJQUFKO@EI:@D6;=057,13(01)/0(./).-(.-).-)/.,0/-/.,/.,/.,/.,/.,..,/.,..,0/-//-0/-//-//-//-//-2-17,:6*83-1961HJ?bfX{€z‹““£–°Œ•¶ƒ²¯…™²¤¶’¨³“¨«¤£Œ ž‡ž˜‚™}˜‰œ‹ˆ£”°š˜±›”­—‹£…›„’|k|iXfOSV;ZV9^Z=+/2+/2+/2+/2-.0-.0......------.-+-,*-,*,+),+),+),*+,*+,*++)*+)**()*()*(),*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*+,*++)*+)*+)*,*+-+,-+,.,-.,-/-./-./-./+*0,+0,+0,+0,+0,+/+*.*)/+*/+*/+*/+*0,+1-,3/.40/901:20;31<42=32=31<20<20=20=2.?1.?1.@2/A30B5/C60D63C84D95E:6G96H94K84N50X72_60i70r7/}:1†<1Œ>2>2—@6—?5—?5—?3œ@3£C5«C6³E8ºE;½G=¾H>¹G=°D8¦A5›?0—@/—@-—@-–?.•>-”=,•<,–=/–=/•<.“;-’0->0-?1.@2/A4.?4.@51@72@93A:4B94C84F74H5/Q51X5/a6/l8-u9.€0‹=1“?5•>5“?5“?4•B4šB4 C4¥D4¬B5°D8´E:±E;ªB7¡?4š>1–>0•?.”?+“=,“=,“<+“<+”<.”<.“;-’<-<.;-Š;,‰<,‡;+‡;+†:*†:*…9)ƒ:)ƒ:+9*9-9-€<1<3?6€A8‚C<…F?ˆIBŠICŽJAG>—HCŸNJ§VR§`Z©pe¤ƒrœ”}–¡ƒ¨Šˆ§ˆƒ „~–~yˆup{jdp\]iSR^JJS@BK:>E5:@29<134,22*1.)/,'/))0**1++2,,1++1++1++1++1++0,+0,+0,+1-,1-,1-,1-,/.,/.,/.,2,.8*75(13+(56&EK1\gGu‚d†“yޛБž”Ÿš‹ž˜¥——´ž¢Å¥©Î­¥É­¦Ê°§Ë±¤È¬—¾Ÿ‹³‘ˆ°²Ž²Ž²¬Š„¡‚€™{wŽrdx]Q_ENR7QQ5SR6,03,03,03,03./1./1./1./1/////////////.,/.,.-+.-+/-..,-.,--+,,*++)*+)**()+)*+)*+)*+)*+)*+)*+)*+)*+)*+)*+)**()*()*())'()'(+)*+)*,*+-+,.,-.,-/-./-./+*/+*/+*/+*/+*.*)-)(,('0,+0,+0,+0,+1-,2.-40/40/:12;23;23<34=32<21<21;10<1/<1/>0/=/.>0->0-?1.>3/=60;60;83<94=:5>93@72C60G4.O4+Y4+d5+n8,x:-;.…;.<4‘<5>3@3A2“B1—A2™@0 >1¦@4ªB7ªB9¥@6Ÿ>5—=2•?2’?-’?-‘>,=+‘;*‘;*’<-’<-‘;.‘;.Ž;-;-Š;.ˆ:-†:,„;,…9)…9)ƒ:)‚9(‚9*9*~8,~8,€<1€=4€@7B9„E>…IAˆKFŒMFŒIAŽH@˜JF¡SO¨]X©hb©{n¤Žy™œ’§†‰¬‹‚ªˆ€¡„™€~‹wxnjxadr[ZhQQ]IITCCL;>D60-?1.=2.=4-=6.;819919:29:2;81?6/C2+J1,T2)^3*g7+o9-u=.z2¢B6¡C7žB7™?4–>2”>1”>/“=.=-<,Ž=,Œ=,Œ=.>/Ž<.Ž<.‹2>5€@6‚C:ƒG=…JB‡NE‹OGŒICŽID“PJ˜\Tžg`uiž‡už˜€”¡…ª‰‰¬‹ƒ¨‡€¡„~›zytˆoi}bby]\pUUgOO\HGRAAH8=A388.85.7/,3+)2()2()3)*4*+0*,/+*0*,0**0*,0*,2),2),3*-1+-1+-1+-0,-0,-0,-1+/4)/4*+4-%46!?F%T`8m|Qg‰™tžz¡~ˆ¡zЧ{‘¶‚›ÄˆŸËŸÉ™žÇÆš˜Á•Œ·Š‚­€…®‚Œµ‰„«‰®…‰©‚~œxvolƒfZnSJZ?GM3FJ1DF./0+.0+/0+01,01,01,12-21-32.43/43/62/51.41,3/,4/,50-50-4/,3.+2,,1-,0,+0,+.,-.,---/--/,,.++-*).))+.)/.)-/(/.)-/)-.)-.*+.*+/+*/+*-,*.-)--+-.)./*./*------.,-/-./.,0/-2.+2.+2-*4,)5-*6.+8/*:1,:1*;2+=4-=4->50>50>50=4/<3.;2-=2.<1-<1/;0.=/.>0/>0/@1.A0)@2);4*77-39-28.56.:3-?-)F*'L)'S*&Z/(`5,d<0k@0yA0@/†A1‹B3@3“=0“;/’8-“;/“=.”A1•B2”C2’A0‘>.‘;,—;0—:2’;1Œ=0ˆ?0„?/‚?.ƒ>.ˆ@1ˆ?0Š>1Š<0‰;/ˆ:.†:-ƒ;-{9+~@3w<.q7)w>-w>-v;-}?2{;/‚@4‡E9‰I?ˆLA†MB„PC‡NE‘KI—SP”bY‘paŒ}j‰‰q‰–|Šž‚¤‡¦‰Ž§Š§Œ‡¤ˆ~Ÿ‚uš{o—uiib„_[zXZsUZnSWeNPWEJK=C?6@93;0.6**3')3'+3'+1&*,*-)+***,*(),'+.(,1(-2'-3(.3(.3(02(00)10)1/*1/*0/)-1++0-(//#5,>5,>5.>5.>5.=4-<3.<3.=2.<1-;0.;0.=/.=/.>0/@1.C0*C0)A2+>4+:6-95,:3-<1-?-+D*)I*(N+'T/)Z5-_:1e>/pA/xA-€A0ˆ@2?4‘=3“:2“;19.‹.Œ@0A1A1ŽA/‘?1•;2•;2<2‹=0†>0ƒ@/?/‚?.…@1†>/‰=0ˆ<.‡;.„;,‚:,€;,x8,x<1s9-n9+s>.s>.r8*u:,}=1ƒA5‰E:‹I=‰K@†NA„PC‡NE‘JH—SR’f]Œwf„†p€“wž„¥†ˆ§ˆ§Š§§Š¤‰Ÿƒwœ}o˜ve’i`‹`Y‚ZY{X\wXZnSSaJNUCFH;C@7<737/-3*+2)*1(+.(*,*+**,+),+),-(,/)-2(02(02(02(02(10)1/*1-*3-*3-*12-12.-0,)--%8:,SXBox]€‹i‡–o†™l†žnˆ£p†¤p„¥pŠ­w“¶€™¹‡–¶„“³Œ®{†«x‚¨w‚¨yƒ¨|ƒ¦|‚¤{x’uqˆnh{eYjWMZHEL<@D5;=/12,12,12,12,23-23-43.43.54/54/85085085074/72.61-80-80-7/,6.+4/,3.+2,,1-,1-./-.0.1/-0--/,,.+*/+)./(/1'//)-/)-/)-/)-.*+.*+0,+0,+/.*/.*/.)0/*0/*0/+//-///0./0./0/-/.,1-*2-*6.+70*90+:1*<1+=3*>4+?5,?6-?6-@7.@7.?6/>5.=4-=4-=2.<1-;0.;0.;0.;0.<1/?1.C2+E0+H/+K--L,/K+.I*/E+.A-,@.*A.(E.(M.)X1*b3-g5,j:,o;-w;0=4‡<6Œ<5:4:4Š<2‡=2†>2…?3†A2‰A3ŒB5C5Ž?2=/Œ>1Š>.‡>/…>,†=.ˆ<,‰;.‰<,ˆ:-†:*ƒ;,<)~=+{<+}=1z<1v:/u;/x@1x@1v<.v;-?5‚B8‰F=‹H?‰JA‡KA‡NCŠNF‘JH˜TQ–f\ve‡…n‚‘t{¤ƒ…¨‡ˆª‰ªŒ©ŒŽ¥‰ˆŸƒš}y˜xi–ma’e\‹a\†`]‚`[|]UrVPhPFYEBP?:D93:2.3,*/)*,)**(0'(1&*1&*1&*0'*1(+0*.0+//*.-+.,+0+,0)-0(-1(-1)-01/23/..*'**"57*PUAmv[|Ši€k~“j™jƒŸn€ n~ m€¥q‡¬x¯|‹­zˆªx„©v§v§u¦w¦y¤y€¢}}›yw‘tp‡mh|cYkUMZHDH9=?299-23-23-34.34.34.45/54/54/650761961:72:72961940940:2/91.91.80-50-4/,4..4..3/03/01/01/20.1..0--/-+.0)02).0*.0*.0*.0*,/+,/+*1-,1-,0/+0/+10+10+10+10,11/1111/010.10.2.+3.+3.*92,92,;2+<3,>4+@6-@6-A7.B8/A8/B90A8/A81@70>5.>5.=2.=2.<1/;0.;0.<1/=20=2.B3.E2.L..R+0V'/U&.P'/I).C/.<1+;2)?2)G0(R/)_.*d/)i9/k;/u<3}<6…;8‰;9Š;7ˆ:6‰>8†@8†B9…B9…C7†B7‡A7‰A5ˆ@1ˆA/‡@.‡@.‡>-ˆ<,ˆ;+‰:+Š8*ˆ9*‡:*ƒ:)<){=(x>(x>*‚>1{7.z7.z<1v;-w=/|A3{@2€B7ƒE:†H=ˆJ?†J@‡MBˆODŠQHŒSJŽ\QŽh[‹tb…g€‹m~–vž|ƒ§ƒ„©‡‡ª‰‹ªŠ‹¦‡‡ ‚ƒš~}˜yq•oi”ifgfŒeg‹gd†e_~_Zw[PhPK^JBP?8D62:/.4*,/(+*%2&&5%(4%(2&(1'(/)+/+,.,-+++*+-*+-(,-(,/',/',/*+-.*+1++0+'.+"88,PUAiqYv„c{Œhyh|–iœl}Ÿmyžkz m¥r‚§t€¥q}£p}£p}¥s~¥v~¥x}¤x|¡x}Ÿzz™wuqn‡je|bWkRN[GDF9?=1:8,45/45/45/560560560761761872872;83<94<94<94<73<73<41<41;30;3083072/61.61.5106216213122011/00./1-.2,04+.4+.4+.2,.2,,2,,2,,3/.3/,3/,3/,21,21,32-32.32032032032051051.61.61-;4.<5/=4-?6-A7.B8/E8/C9/D:1D:1E;2D:1C90B8/@5/@5/>3/>3/=2.=2.=20=20>31>31@51E31M02T,4X)3W(2R)1K,1B30:6-77+:6*B4)M2)X/)^/)f:1j;3s<7z=:‚<:†<;‡;;†::‚;7>8A8B9ƒC:ƒC:…@9„@7‚C2‚C1ƒB0„?/†=.ˆ<.‰:-‹9-‰7+‡8+…9+‚:+~=+x>*v?*x>*9-|/'‚8/„>4w4+s5*}A6}C7E:€G<‚I>ƒJ?„KB†MD‡QG…WJ|aNzjQ€pYu]‚|bƒ†i†“uˆ|ƒ£~§‚‚ª…‚¬†©„¥€{ž}z™wz’pzlxlwŒkumr‰lm„gkd`rX[iRR[HHL=@@4;7,70&5*$6('5''3''1'&.)&+*(++)+-*',('+*)+*)+***,+),+),-)*,#$2*'50*86*BC5UZFfpWn}^tˆeqŠbuex˜iw›ks™htšiwŸkz¢nx lwŸmx ny£s{¥u{¥w|£wyžuzœww–tsŽom†hd{_WkPN[GCC7>:195,560560671671782782872872983:94=:5>;6>;6>;6>95>95?74?74>63=52;63:5294194184184395484373243151240/6-06-.6-06-.4..4..4..4/,40-40-40-51.32-32-43.43.43/431542540841850940:5/=60>7/@7.A8/C90D:0G:1H;2F<3F<3F<3F<3E;2C90B71A60@51@51?40>3/>31?42@53?53@72C52I35P16T/6S.5P05J22C52=90<:-=:+C7)I6(Q3)W2)]2+d3,l50v64}77‚87ƒ77‚66~75}:4}<6}>5€?9ƒ@8†?9…A8€B3€C1B1ƒ@0…=/‡;.ˆ:.‡9-…9,ƒ9,‚:,<,|=,y>,x?,|=,‡5*‹2,¡LE§XQ‹A8|90‚F;€K=yH:zJ<{M>|N?}OBQE‡UJ‚_LrkOosR|uX‡w]yb˜iŸ‹s ”z––z|‹£ˆ¨…§‚€¤~{Ÿy~™vƒ‘p…ŽoƒŽp€pp{ŽpwŒms‡kj~bfv\_hSV[GOM>GA3@6*=0';,'9+(6+'3+(/,',-'+.').().(+-(-,*/+*3)*4(*7'*7'(3($<3,E>4IG8QR@]bKgqVjyZn‚]k„\l‰]p‘bq•eo•do—eršfuŸmrœjq›itžnx¢rz¤vy¢vyŸvvštw™vu”rokj…fc|^UlON\ECC7@91;4,671782782782893893983:94:94;:5>;6?<7?<7?<7@;7@;7B:7B:7A96@85=84=84<73<73<73<74<74<74;639529338308/09/.8/080.80.80.61.61-61-61-52-52-63.63.74/74/540540841952:63<94=84@93@70A8/C90D:0G:1H<0I=1I=1J=4J=4J=4I<3F<3D:1B8/A7.A81@70@72?61?61@72@72A83?74@85B86D97G96H96H96H94E80E8/E9-E9+G9,I9*K9+Q7*Z/&d/'n3-z63ƒ98‰;9‹;:‹=;‹A>‡@:‚=6<3:3‚<4ˆ=7‰@7ƒA5B3‚@2ƒ?2ƒ=1„<0;/€/|>/}>/=/†9/1+¢<8ÍlfÙ~y­ZTŒC<ˆLAN@tJ(+C&+E$+C&(F5-LC4VQ>[YD`bJgmQiwVj{Wl‚[g‚Wf†WlŽ\o”an”an–bršfsko›jo™irœnw ty¢xxžwu›vs—su—vs’rn‹li„cb{[TmMM]CGH:E<5@707827828938938939:4:94:94;:5<;6?<7@=8@=8@=8A<8A<8C;8C;8C;8B:7?:6>95>95=84>95>95>95>95=85<73:51;30:0.:0.91.91.91/91.91.72.61-61-63.63.63.74/74/74/540651952;83<94?:4B;5B;3A8/B:/C9/E;/H<0I=1J>2J>2K>5K>5J=4J=4F<3E;2C90B8/B92B92A83@72@72A83B94A:4?82@93B;5D=7F=6G<6K<5N;4M6.N6,Q6+Q6+Q7*P9+P9)V6'f6*r6,~;3‰@9•D@›HDŸJGŸLF QJ™LDŽD;…;0„7-…7-Œ91=4ˆ>5‡>7†=6…<5…<5=4}=3z>3x@3vA3x@3z>3<3ƒ:3ˆ73‘31˜(&³=;ì|zý•’Åhc–G@‰K@xH:nMhV>lX@t[E`L€hPysQ„wUžt\´l^É__ÓV\ÙQ[×T\äouÙzx̆|À~µ•€«•}£’xŸvœŠrœŠt™u•u‘‘u‹’s†‘s‚‘r|‹ny†ju{amoWgbN_TBUE5R/(9/&7.'6/'81):/)=.+A,+F)+H(+K'+H)'TB4YQ9B?:D?;D?;E@8E>8D=7B;5B;5B;5B;5B:7B;5A:4A:4A83A83A83@72@64>71>71>71<71<71;60:5/85.85.74/74/961961961:70<71=82A:2B;1C:1D<1F<2J>2K?3L@2N@3N@5N@7N@7L?6K>5I<3H;2E;2E;2B90A8/@91?80?80?80@93@93<5/MD=M@:K:3T@9R62O0+a<6\3-`5.`4+^/'^/%f6,m=1q=0‰I=G;—I?ŸKAŸF>›>7š=6žD;¦ND¤PE¨VJ«YK¥OB™A5—;0›>6“98‘98Œ65†52†84„?8|@6r>1rB4oA2q=0v:0‚72Œ43’-1š',ÈHIèbaÅEDÍWUáyv«VO†F<„VFmR=i[AibFjeHj`En^D|dLjT’bL²m]ÑnhÛX]à;Lç-Eò+Hõ0Lö@YìI\ä[eånrâ{|Û€}Ûƒ؉‚Ãv½wº„x¶†x²ˆx­Šw¨‹y¥Œxš€o™~m˜xi“oabY„UM{IBxA>u:9:49:49:49:4:;5;<6>=8?>9>=8>=8A>9A>9B?:C@;D?;D?;FA=E@8E>8E>8E>8E>8D=5C<6C<4D;4C:1B92B92B92B92A83A83@93@93>71<71;60;6096/85.74/74/96196/96/:70<71>:1A:0B<0C;0E;/I=1J>0L@2L@2N@3N@3N@5N@7M?6J=4I<3H;2E;2E;2C:1B90@91@91@91@91A:4B92D93I81L/+V.,j76u99{;;…ECƒD?„H@…IA†G>ŽIB™NH¡PL¢OG“D7”B4šB6ŸC8 >3œ7-œ7-Ÿ=0£C5›?0™@0 E3¤G6§F6®H:¶NE´LM¯HL¥@D™9;‘98>:ƒ@8x>3o>0zI;…LA„?8„,+’).³9DÒLWÜKNßMMÊ>=À@?Ð`\³YQ„@5‚TDyaIe[@^]?ihIslOvgJ~dK–cN¼dXÖ_[æUZëANò,Eþ%Dÿ&Hÿ'Iÿ.Nù3Nò6UE8[O5cZ9gaAifEnrOz‚]z‰bt†^r‰_p‰_p‹`qŽ`u’dw”dw”dw”fs’ix–rz—xy–x~˜}ƒ„…‡ƒ›…™ƒz’zr‰om„hhd`y[TmMNaERSAVPBUOC8938938939:4;<6<=7?>9@?:@?:@?:C@;C@;C@;C@;D?;D?;FA;FA;FA;E@:E@:E@:G@8F?7JA:I@9H?8G>5F=6E<3F<3E;1D:1D:1D:1D:1D;4D;4D;4C<4?80?80<71;60:5/:5/94.94.96/96/:5/;7.>7/@9/B90C;0E;1F<0I=1K?1M?2M@0NA1M@0P?5M?4L>3K=2I<3H;2E;1D:0C:1C:1A:0A:0?;2@<3@<3D;4UD—I?–LAœNB¬RJ¾URÌOSÄLK¥@4B0 @0¥?1¥;.£7+¤8+§=/«E6¡>+˜7$:'¥>-¬A/²C2¶D:§02¯:B¹DL½LRºMR­KL–A>‚71{8/v6,x2*„1-œ37¹=GÕGWèM[âFIÏ53Ð:9½31ÈNKÆc]”J?Œ[J}cLj_CgdEtoOpQhJhN°hYäbbõQZôDQö7Iý1Jÿ2Nÿ/Mÿ*Hÿ2Oü0K÷1Jõ5Lò4Mð2Kó3Ló7Pò@XïC[îF]íIaëNcêQeèUhèVkåSjäRiãOiäNiçNlëPoòSsóVuþh…ña|å[tÕUlÍYlÉdr¨R]r-2^&'Y0,W:4Q?5B:-:8)>B1LN9VO3aV6e_?heDquT†e~ŒiwˆdxŒiu‹er‹dr‹cvŒeyhzizj€•v„›~Šž… Š’£—¨–˜©™–¦™‘¢’‡˜†zypƒmg~b^wYTmMPcGSXDXUDYVG7827828939:4;<6=>8@?:A@;BA5G=3F<2E;1D:0D:0E;1E;2D;2E<3E<5E<5@91?80=82<71;60:5/:5/:5/96/96-;7.;7,?8.@:.C;0D0K?/M@0M@0M@/M@0O?2O>4L>3K=2J<3G:1E;1D:0D;2D;2B;1@<1@<3A=4B>5F<3S81[*&‰:?¾T`ÙTeæUfãUcËJOŸ30–:/‘>0™A3®F=ÅIGÕBHÍ>@±B7§F5©B3¬@3¯?3°>3³B4´D6²G5©B/£<)¤;(©<(«:(®6&­3(¶97º9=½7>¼7<¿^õ@aøCfö@fõ?eõ?gø?hüCmÿErÿIsÿOuÿQuþUvòSqçTnåaxÖfv·Wb}15j0/X1*P8,G>/>A.;D/?G/PK._T8g`CokN||`ˆŽr‡‘v}‹qzq|s|szozŠm}Œoƒ’uˆ—z•£Šœ©•£®¦±¡¬´§±¹®°·°«µ­¡«¢” ”ƒ‘‚s„qh|c]tXSlNPdHRZCWYDYZH671671782893:;5<=7?>9@?:BA/K?1M@0M@0NA0O?/O?0O?2N=3N=3J<1I;0G;/D:0D:0D<1D<1B;1@<1A=2A?3B?6K=4\5.w32­LSÛ]iæM_å@Q×6E·&+¨1)7(’:&—<)¬@3ÃD=Ô>?Í;;±?5¨B4ª@2­?2²@5¸C9¼H;»J<¬>/ª?/¨=+¦;)ª9)°:,·;/¼<1ÊFAÎDAÐ>?Ð79Ö7<ÞBEâLNÝROÄC>ÆKCÍTLÔSMÙKJÛ?Bà5>á27Û4.Ú7.Ð1+Ï:4¿84³@9µ[P–UC{N9‚bI†kP„`F’[F­fTËrdçmhêEKò:Dê9Cç=8@?:@?:C@;DAGB>GD=GD=HC=ID>IE2I=1G=1G=1F<0F<0E;1E;1D;2C:1A:0A:0@91@91=82<71;60;60;7.;7.;7,<8-?9-A;/D0L?/M@0NA0NA0O?/O?/O?2N=3M<2L;1I;0G;/F90C9/C;0B<0B;1@<1@>2A?3B?6N;4m84—FEÄY_ÛWbßCQÞ8FÔ3;½++­1'¡8%˜:!—9 ¤;&¶>.Ã:2¾71§7,¢:-¥9-§7,¯:1¸B8ºE;·E:®>2­?0§<,¤6'ª6)¶>0ÃD;ÊG=¾8-Î@6áD?ìBBô=Aó9>ë27Þ.0Û75âGBèSLåNGÜ=9Ù10ã/2ê67Ù1(ÞÒA>ÒGBÝOMëWWíNRïDMð:Gö5F÷2Fø.Dû1Gþ7Nþ8Sý8Tý8Vþ9Wÿ;\ÿ>aÿAeÿCkþ;eýjý?mú>nø>oô=mö:jÿHrÿ;aÿ?dÿKnÿKn÷NmïUoãZnèr‚Âaj˜ILt:8\6-P9+PC2UM:^QAreUˆ|n•‚Ÿ‘¦§Ÿ¡¦Ÿ–œ˜•ž›ž§¤¦¯¬¦¬¨¢§£¦¨£µ´°ÂÁ¼ÌÉÀÑÎÅÕÐÌÕÐÍÔÎÎÕÏÑÑËÏËÆÊ¿½À°²¯˜Ÿ˜€Œ~m~k`t[WnRVjNS`FV`EX`H560560560560671893:94;:5=<7>=8A>9C@;DAHC?HC?GD=HE>ID>ID>JF=JF=MF2@@4P91r1/¨JKÁSV»>D½06Â03Á//º1)©1!£9#œ=!™;›< ¡=#¥;%¤6%ž6) 8-¢6,¥4,­81·@:¸C<²@6±B7­A4¨-Ï>-Ù5+á*&í"%ú%+ÿ*1ÿ.4í)*ç.+á3,ß4,à3,ã2,é0-ç2+Ú2%Ö6&Ð2&Ï7,Å6.½>7È`UÒq¦eSVBŠM:£WIÈf[ßd_çRTèCIõFMí@Dß??Ô@<É@8Æ@7ÑFAãMLïJNô@Kù9Hý7Hü5Hø3E÷6Gú;Mú8Pü7Rû6Rý6Uÿ6Xÿ9]ÿ;aÿkÿ?mÿ@qÿBtÿBuþBuüBtùBpÿFmúAaþEeÿKjþKkÿVtÿ_zõ]tòj~æp~Óow®^aƒCAg6/hB7sUJye\Œ}v£–­£¡²®«¶¶¶²¶¹ª¯³°·½¶½Å½ÁÊÀÃÊÃÂÊÉÆÍÕÎÖÝ×ÛâÚØçÝÛéÝÝæÚÜåØßä×ààÔÞÙÏØÊÅ˺ºº¢§£ˆ’‡t‚qexb\sW[oS[jM\iK]gL561561561560561671872983<;6=<7@=8B?:DAHE>HE>HE2G=1E=2D;2C:1C:3A:2A:4@93?74<73<71>7/>7/<8/=90>:1A:2C<2D=3H@5I?3L@2MA1NA0P@0O@-O@-L?/L>1M=0L;1J91I81E80C90@9/>:/;;/<<0=>0>?1A?0S8-‡<7Ä\[ÊZY®86«.*²1+®.%­2#¬9&¬B*ªF,¦D'£A&£A&¢<#Ÿ9# 9*£;0¦:0¦7.­<4¶C<·E;°@5«=0¨Dá;=Ö<<Í@9Á>4¶8,¹6.Ä94âHHé@Eð;Dö:Hú:Iø8G÷;Iû?NþAUÿ?Vþiÿ>lÿ>oÿ>pý>qú@rø@t÷Aq÷CjÿMmÿSs÷Jhë@`ýTsÿg…ÿe‚÷]wï_xçh{Üp}Æqx§gg^X{ZQ—~wª™’¾°­Ä¼ºÆÂÃÈÇÌÇÇÏÃÃÏËÊØÌÊØÑÊÚ×ÎßßÔäæÛéêàëíãëïåæòèæôèèðäæîáèíàéêÝçäØâÑÊÑÁ¿Â««©‘–z†xl{hbu_`rXbpVboScmT21/320431651875984984984;:5<;6==5??7AA9CC9EE;EE;HH@HH>HHLC4J@4KA5MC9LB8F=4B90E<5C:5@93?74@85?75<74<42C:5B94A96>95?:7>:7?;8@<9B?:D@7G@6J@4L@0O@-O@+L?,G@.F?/I;0K81M53K65J88F;9B?:6904,«=,­<,³=/½C4ÄF8À>1º2&Ç9+Ì8*Ð8+Ö8-Û7-â5.é3/î1-ñ.,ô.-ó0,ñ1,ê5*ã7)Ý:)Û:(Ü9&Ô3Ð3 Ï8'Æ7'¾6(ÂB5ÏSIÈNCÏSKá\Wî]ZðPRí>Cò9?÷?GêAFßCDÕAAÈ?9»<3±;/°HH>HH9H?:F=8B;5D:8A96?74?74@85@85=85;62=4/=4/=52<74=96>:9=<:>=9B?:D?9G@6J@4M@0O@-P?+L@*B?,B?.F<0H:1J65I56F35@65@<9:=6;>5@@4E<-J9)^B4€L>®QB«;- 2#¡6&£:'ž7$ž9%£>*¡;%§<(®?+³@-¶=,·9*¸6(µ7)ª9)¥:*¤9)¥;+¨>.«A1«B/«@.®?,«:(±<+¿E6ÆH9Á?1¼8+À6)Ë7+Ï7,Ð9.Ñ;-Ô8·;1®:-ª<-«=.¶E5ÆL?ÔNEÜGCã?>ï?Bú?Fþ@JøCJ÷CLúDPÿFTýBSù>Sü>XÿBaÿFhÿCiü?iù@jùBpüFvþJzÿK{ÿJzÿHtõKpñQsõ\zù_{ûXwüNqýEkúDlïEiÚKgÈ_p±nukLI~t°–‰Ì²¥äÓÉìãÜëçæêéîêçòíâóöãùûáúÿâýÿçÿÿìÿÿòþÿöþÿùûþú÷ýúõü÷ôúõòøïðôëîñèíïæëæÝàÜÖØÊÆÅ³²®ž¡šŽ“Œ‰…ˆƒ•‡‰€†Œ~/.,0/-10.21/43/540762761:94::2<<4>>6@@6BB8CC9DD:IF=IG;JH;LI8MJ7NL7NL7OL9KI:NKBTRS_^fihxmm…lkŠkhƒ`YiYQ\OGRH@KH>GG=EE93>:1=9083-94.;60<92=:3>;4?<5@<3E>4G?4I?3L@0O?0P?/P?-L?,<;&:=(?<+A;-B71A62>42;30=84B;5H94N2.Y,)l/.‡;= FE£;0¢2$Ÿ1 ¤9'¥<)ž7$ž8"¢<&¤;&ª=)±A-¶A/¹>.»<-¾:-¾-­>-­<,²?-°8(¹>.ËL=ËG:¼6*º2&É9.Ð6,Ô6+Ô8,Ö:.Ø:/Ü8.ã6/è3,ð0-ô.+ô.+ð1)ç2'Ý6&Ô8"Ò7!Ý8$Ü5#Ú9'Ú>/Ó=.È6)Å9,ËA7É<5Í>8ÙEAåKIêJJéCCì?AëCCÞCAÕD?ÍB=Â=4¶:.®8*«:*¬;+¬8)ÀD8ÔNEÝIEà@@è>A÷BIÿHPôAGô@IùCOýGTþEUú@Uû?XþA_ÿDfÿCiÿCkÿFpÿIwÿK{ÿL|ÿJzÿFxÿHwÿKtúNtÿZ|ÿa€ýUvñCdûIkÿTvÜ?\ÍI`Ø{…¸||aC;|n®ŽÕ³§óÛÑûìåúòðù÷ú÷ôýôìûúëÿÿêÿÿìÿÿîÿÿóÿÿ÷ÿÿûÿÿýüÿþûÿýùÿúøÿøöÿõöýóôûðôùðóðçêåßáÓÏξ½¹­®¨¢¥ž£™£—£«žž¦—›£–/.,/.,0/-10,21-32.54/650880991;;3==5??5AA7BB8CC9HEQPL^]bmlzzz’‚¡€‚¨€€¦{u—rkŠe_{YSmTLdMEZG@PB;2?=1@<1?;/A;-F?/H?.K?/M@/O?0O?/P>0L?/@=*?>,@=.?;/?;2>93=:5:94<94D95M51V-+j)-„28ž8C«>C¦7.¥7(¥:(ª?-¨?, 9&¡8#¤;&¥:&«<)³>,¹@/½>/Á=0Å=1Ä>2½?3¶=2²9.®8*¯9+°:,²:,³9*¶;,¹;-ÄB4ËE9È>3¾1'À2(Í9/Ö5+Ø4*Ú6-Û7-Þ7.á6,æ3,ì1*ó0,ô.+ô/)ï0(ä2&Û4$Ò6 Ð5×2Ú0Ú4$Ü<.Ö=/Ð9.Í=2ÒD:Ä5-Å60Ê;5ØD@âMIåKIÞC?Ö=8Ó@9ÎA8Ç>4¾VádtþŸ§ÓŽd92lJ>¥ynÐ¥œõÔËÿéãÿôòÿýÿÿüÿùóÿüïÿÿïÿÿðÿÿòÿÿôÿÿ÷ÿÿûýÿüûÿýúÿüøÿúøÿù÷ÿö÷ÿõöÿôøþó÷öëïìãäÚÕÒÉÆÁº¹´³´¬±´©°¶ª¶¾³°¸­¬´©10,10,0/+0/+10,21,43.54/77/880991;;3==3??5AA7DA8IE:LF:NH:PJ:RK9RM:SL:QK=OJDVTUfdqwx††¨¹“ÃÆŽ‹À‡ƒ¶{w©pmšid_[~UPnNJaKGXEBM?=B;7895296/85,85,671783891;;1>5L?6K>5F<3B92=82:946;47<59<5>:1H4-Y2-w78”?D¦>E§9<ª;0ª<+«@.¬A/©@-¥<)¦;'«>*§8$­:'µ<+¼=.Á<-Å;.Ê<0Ê=3Å?6¾>3º:/·7,·7,¸8+º8+º8+»7+ÇA5ÍC8Å8.Á1&Æ3)Ë7-Ï5+Û4+ß3)á4-â6,ã5,ç5+ì1*ð/*õ/,ö/*ò/)ì0'â2#Ù4!Ð5Ï4Ö1Ù/Ø2"Ø6)×9-Ô:0Ö?6ØE=ÖF>Í@7É<5Ë@9ÖKDÙNGÒE>Å;1Å=1Â<0ÀCòBLûIUÿJYýFXúCYûC]û@_ûBdÿElÿJsÿNzÿO|ÿLyþIvÿJwÿTÿT}ýJqùImÿStÿVtøNiëD^äF]êXkÿ–¢ÿµ¼óžŽHFk.)¦kcÍ–óÈÁÿãÞÿñðÿüýÿýÿü÷þþöÿÿöÿÿ÷ÿÿøÿÿúÿÿüÿÿýýÿýúÿüøÿûøÿùøÿø÷ÿöøÿõ÷ÿôøÿôøýñóóéêäÜÚÖÑÍÍÊÃÉÉ¿ÊÊÀÊÍÂÉÐȾȿ·Á¸65143.32.10+10+21,32-43.66.77/880::2<<2>>4@@6B@4JD8ME8OH8RK;TK:TM;SL*F@*G?*H@+IA,IB0IA4HB6HA9G@:K=?ž51§;/ª<+ª?-ª?-©>,©>*¬?+°?-«8%²9(¹:+¿9-Ã9,È:.Í:0Ï<4Ë>5Æ;4Â91Á8.Á8.Â9/Â8.Ã6,Å7-ÑC9Ð@7Ã0&Ã,#Ð7/Ö<4Ó2*à3,ä2(ç2+è3*ê3+í2+ð/*ó-*ö/*õ.)ñ0)ì1(á4$Ú5"Ñ6 Ð5Ø7#Ù3#Ö3$Õ3&Õ5)Ô8,Ô<1Ö?6ìYQáRJÓHAÌC;ÊE<ÌI?ÈE;À>1¼:*¼;(¼:*¹:)·:(¸:+¼>0¿A3ÁA6Á<3Å<6ÏA=×EEÝGHäIMëLPèBFê@CðCIùKTþNYüJZüF\üF_øA_ùBaýEiÿJpÿNwÿOzÿNxÿLvÿQ{ÿRyþOvýOtÿVyÿ]{ÿSoîD^úTlîQd÷dtÿ’žÿ‹•ôƒ‰Ç`d§MMµjgΊXÿÞÙÿïîÿúùÿüþýûÿýúÿþûÿÿûÿÿûÿÿüÿÿûýÿûûÿûøÿûøÿüùÿûúÿûúÿøúÿöøÿó÷ýñóùíïòææçÝÛߨÒÛ×ÎÝÛÏàÞÒßáÖÜãÛÏØÓÅÎÉ<94;8185052+41*41*52+63,74-85.96/;81=:1?<3A>5C?4JB7MC7PG8SJ;WK;UL=UK?SJCSJK]Wcnl‚‚‚¦‘•Åš ÚŸ¦ê¢©ñ¡¥ïž ë™›å•˜Ý”•֑ʉ‰½‚ƒ±zy¡rq‘fc~XVkPN\IGRFCLCBJ??K==G;:@;9:<94?;/C=-E@,F@*FA+EB/EC4CC7BC;AC>@ACBLCANEEOCHNAIL>HI>GDCHAA=2L:.gF7ƒOAI<Ž?2”8)¥>/©>,«>*¬?+­@,¯@-°?-±<*±8'¶8)½9*Ã9,È8-Ì8.Ò91Ô;5Ï:4Í:3Ë81Ë81Ì92Í:2Ì70Ë6/Ó<5Õ>5Ò91Ì2(Î4*Ø;2Ú<3×3*ä1*é1'ì1*î2)ð1)ò/)ô-(ö,(÷-)ô/)ð1)é3(â5'Ù6%Ò7!Ï7 Ô9%Õ8%Ó6%Ñ4%Ò4(Ó7+Ò8.Ð7/ãNGèXPçZSÚQIÌG>ÄD9¿@7¹>/¹<*¹<&¹<(¹:'¸9(º;*À>0ÃA4ÉD;Æ@7É@:ÑFCÕIHÖHGØGJßIKæFHèBDíDIõLSüQZûO]ûL]ûK`öD^÷DaùFfýIlÿNuÿOxÿOxÿPw÷VxóUvôTvüYxÿ]{ÿZwûQkòI`ýWköUgêM^ö^mâKZæTaåTa×XaÁefȃ~å«§ÿÔÑÿëèÿóòÿøùÿþÿûüÿûüÿûüÿüüþüúýýùúý÷÷ü÷ôÿú÷ÿûøÿüûÿûúÿøøÿóóýîñúëîðáäéÝÝäÙÕâÙÒæßÕëçÛñíáññåìóìÛæâÎÙÕ@=6=:3:7074-52+52+52+63,74-74-96/;81=:1?<3@=4B>3JB7MC7RF8VJ:WK;XL?:6@<1A>/C@/CB0BC3BD7?D=>D@CVCIaLRhU\o\br`dobbjd`afXWaJDlG>ƒSE•XF“J7‘@+™>+¨A.®@/®A-¯@-°A.´A/²=+°7&µ7(¼8+Â8+È8-Í6-Ñ7/Õ81Ø;4Ò72Ð72Ð72Ñ82Ô94Ô94Ó83Ó6/ÞA:Õ8/Ñ3*Ö8/Þ=5Þ=5Ú91Ü5,ç2)ë0'ï0(ñ0)ô/)÷-)÷,(÷,(÷-)ô/)î2)é4)á5'Ú7&Ô7$Ï8#Î7"Ï8%Î7$Ï6&Ð7)Ò9+Ñ7+Î4*Ë4+ãNGód\ë`YÕOFÄA7º;2µ9-¸>)¸>'¹<&¹;%º9&½9*À2ÊD9ÊA9ÎE?ÕKHÓLIÎGDÍEEÖHGãIIæCDèEHòMSøSZùR\÷O^úOaôH^õG`øGdûIiÿNrÿQxÿRyÿTzðUuïZwù^}ý^|ùUpõMgùOiÿYnÿ[mÿctðM^÷TeôO`üUgõL_äR_À^_»vqל˜úÉÅÿåãÿíëÿôôÿÿýüÿÿûÿÿûÿÿûÿþýýýýüúþùöýøõÿøõÿùöÿúùÿúùÿööüððøéìôææëÝÝèÚÙäÙÓèÞÕðèÝùóåÿúìþþòôúöáëêÓÝÜB>5A=4@<3>:1<8/:6-84+73*62)62)73*84+;60>93A<6E>6I@7MC7RF8UI9WJ:XK;ZLA[NHTIMXR`gd|~§’Ê— ãžªö¥°ÿª³ÿ«²ÿ¬´ÿ¬²üª±ùª¯ó¨¬ì©«èŸ¡Ú™šÒÁ±tr¡he’]Z‡XR~XQzYQvVOnMH_C?M?:@?;:B?8>>4@B5BE:?D=:CB>FH?LUDVnQfƒarŽisŽtvx„o€€^lŠ[c’WYžWU¦VM¦M?Ÿ@.œ9$ :$§<(¬=*®?,±@.³@-´?-¶=,¹;,º6'¾6(Ä6*Ë7-Ñ7-Ö8/Ú91Ú83×84Ø95Ù:6Ø93Ø61Ø61Ú83Ý:3æC<à=6Ú70ã@7þ[Rÿlcÿ]Tç?6å3)í2)ñ2*ô/)ô*&õ(%ø(&ø+(÷-+ó0,í2+ã1'Ú0#Ô1"Ô4$Ó:(Ì;&Ê<(Í<)Ï<*Ò:,Ò9+Ò8,Ñ7-Ú@8Ï81ÜGAôc^åXQËB<Å@;·4*·:&¶<$¹<&º<&½:(¿:+Ä<0Æ>2Ç>4ÌC;ÙPJßXRÔOJÃ?:À?:ÏHDÞHGâGEæJKïPTñRWïNVíKXñL\ùRføOf÷Ke÷JfüMlÿQsÿRvýRvôWvîXuõXuû[wÿ\xÿZsÿWnÿVkÿbuýVgÿ\mÿ[lñFXôDXÿQeîVeÆfgªieʋ網øÒÏÿëçýïîüø÷ùýüùÿÿùÿÿúÿþüþýÿþüÿûøþöôþùõÿû÷ÿùöÿöôÿööÿõõöèèæØØãÕÔÞÐÍáÖÐñçÞüôçþøèÿüéÿÿóúÿùèñðØáàC?6B>3A=4?;2=90;7.:6-95,73*73*73*84+:5/=82@;5D=5H?6LB6QE7TH8VI8WJ9YK>ZMEUJNWQ_eby{¤ŠÉ”⛦õ£®þ«´ÿ¬µÿ®¶ÿ¯·ÿ°·ÿ¯¶ü¯´ø¯²õ©ªë¢£ã˜˜ØŒŠÉ€»uq®ie c^˜`WŽ`Vˆ]TVPtMIbFCTBAIAAC<<:AB=FEACD?A?@DBEOMRWVdch†quš}¢‡}Ÿ’}œ {š¥pФ`u¬Yi¶VaºQU¸HF°@4¬;)¬<&­='¨8$¨7%«8&®9(°8'²9(µ7(¸6(»3%Â4(Ê7-Ó:2Ù<3Þ=5ß<5ß<5á>9ß<7ß<7á>9åB=èC=çB<æA;å@:æB9ä@7Ü8/Õ1(Ø6+ëI>ÿ[Oñ@6î6,ê+#î)#ø-)ÿ/-þ,+ö((ú0.õ4/ï61ç6.Þ3)Ö2&Ô2%Ï6&Ë:'È;'Ê<(Í:(Ï9*Ð7)Ñ5)Ð4(Ó9/Ï5-Ô=6åPJåTQÛLHÍB?·1(¼;(»=&½<'¾;'¾9(À8(Â:,Ä:/È>4ËB8ÕOFÜWPÒRIÃD=¿C;ÌHCÛLHßJFåMLëSRíTWëPVéNVìOZ÷VføUhùSiúRküRmÿSqÿStÿRuòMmøUtÿ\zÿ_{ÿ\vÿUoûRiûReüUf÷RbÿZhÿZhóN^øScþYißS^¶`_—^W¶}Ù©¥îÈÅýáÞùééýøõúüùùÿÿøÿÿ÷ÿýúþýÿÿýÿûûÿ÷õýøôþùõþùõþöóÿ÷öÿõõöêêêÜÛäÖÓÝÐÊßÕÌïåÛüõåÿùçÿýéÿÿïúÿøèñîÛáßEA6EA5C?4A=2?;0=9.<8-;7,84+84+73*84+:5/=82?:4C<4G>5JB7ND8RF6TG6WG7YIBZEJpW]‚cs˜r—¥z§®«²{£¸vœÀp“ÂcƒÀTnÂG\ÐK\ÑHPÄ<<º5.¸9*µ<'°<%°;'°;)²:)´;*·<,»<-À<-Ä<.Ä6*Ë8.Ó<1Ù?5ßA8á>7à<3ß:4Ü71Ù4.Ø3-Þ93æA;ìE?éB<ä=5ã<4Û4,Ø4+Û7-Ô2'Ì, Ö6*éG:õK>ò@6ï4-ð-)ö,*ú,,ü,,ø*,ð*)ì/+è2.ã5.Ü4+Ø1(Õ1'Ñ3'Í7(Ë:)Í:(Ð:)Ò;*Ó:*Ô8+Ô8,Ñ4+Ö<4Õ:5Õ<7åONíYWÙEEÂ3/À;,¿<(À;*¿:)Á9)À8(À8*À8,Æ=3ÇA6ÏJAØUKÒRGÆG>ÀD:ÇG>ÖKDØICÝLIäSPåSTâPSâMSåNWòXdöZhý[pþZrüVnúRlûQlÿQpýGmÿPvÿZ}ÿ[{ÿVrýTkþWkÿ\mûYhøZhûamö`kí]gïfnìfmÉ\_ ]W{OF˜mfÁ˜”ݺ¶ðÔÑôàßÿõôùù÷ùÿýùÿÿ÷ÿýúþýÿÿÿÿýÿÿøùüùôüùòüùôýøôÿùöÿøöùîìïäâåÚÖÛÐÊÜÒÈîäØýöäÿûèÿýçÿÿíúýôêðìÞãßIE9HD8FB6D@4B>3@<1?;0>:/:6-95,95,95,:5/<71>93@;5E>6I@7LD7OF5RE4UE5WG8WI>XMKXNW^Zqpp–€†ºŒ–Ô•¡é©õ¨°ù©±ù­³ý°·ÿ±·ÿ²¹ÿ´¸ÿ´¸ÿ¯±ü«­ø¥§òŸžê—–⌋ׂÍ}yÅum¶pgªf`ž_ZYX„QQuGGcA>Q=5DH8BT=C`@EnCJ€OU–]d«fx¿kÉnšËo˜ÉiÈ`ƒÉWxÆIgÄ;UÆ2HÙAPàEMÑ;<Æ71Ä?0½@,±:$­6"­5$®5$³5&¶7(¼8+Ã;-È/Û?0Ü@3Ü@3Ò6*æLBåJEÎ50ßGFóZ\ßIKÕA?È2ÈF9ÏOBÎPDÆH<¿C7ÁC7ÎH?ÑF?ÕJEÛPKÝROÙMLÚKMÜKPëX`ó[güaqÿauúXmõOgõMgÿNkÿOuÿRyÿUwÿTqüTmý[pÿcuÿjxÿguúboõamídlãflÙhjÎghµfa^TeG<^U©ˆÍ«©åÇÅïÚÙÿóóùøöùýüøÿÿ÷ÿÿûÿÿÿþÿÿüÿÿùúþûöûûóûúõþûöÿýùÿûøþôòøíéêßÙÞÔËÝÓÉíæÖÿøåÿþèÿÿæÿÿëøúïêïèãæßNH:MG9LF8JD6HB6F@4D=3C<2?80>7/=6.=6.=60>71@93?:4C>8EA8KC8NE6QD3RE2VF6VH;ZMGVMR[Whlk‹~‚±Š“Î’Ÿãš¦î¦®÷©¯ù­°ý¯³ý°³ÿ°´þ°³ÿ¯³ý«®û¨«ø¤§ô ¢ïšœé“•⊌ن…уÉ{u»mk¬dež_a’Y[„RQsNHbWFY_CQmBLEM˜MT¬U]¼[bÊZhÙRpâRußTuÙPlÒJbÍBWÇ8JÅ.?Ô8EãCKæGKØ>>Í>6ÌF:ÃH6¶?+·>-¸=-º<-½>/Ã?0ÊB4ÐD7ÕE:ÙE9ÚB7Û>5Ù;2Ù6-Ù5,Ú3+×3*Ô1*×4-Ú7.Ý90ß80Þ7/Ý6.Ü5,Ö/&Ù5+×7+Ï2#Í1"Ò9)Õ>-Ô;)Ø<-æD7øJAýD?ù64õ*-ö*-÷/2÷67í55â30Ú1,×0*×/,Ù0-Ù0+ã81ä91â:1â;2à<0ß=0Ü?0Ú>1Ñ7+ïWLøaZÓ;6Ñ;:æPQÜFHæPQÏ<4Ê:/Æ8,Å9,Ä:-Ä<.Ã;-À;,¾:-¾<.ÃA3ÇH9ÇI;ÂD6¾@2¼>0ÉF<ÊE<ÎIBÕPI×RMÕNKÓKK×LOéZ`ð^hüfrÿhxü]qòPeóMeýNkÿVzÿTxÿRrøTmö]qûhxûjw÷erüetó_mì`kêkrßruÃjfªd\žla}fVXH9kXJ”|r½ œÞÂÁîÖÖþîïûõõûûûûÿÿùÿÿýþÿÿþÿÿûÿÿúýÿþùûþõûüöÿþùÿÿúÿþúÿûõÿ÷òñèáäÜÑáÙÌðé×ÿúäÿÿæÿþåÿÿê÷ùëíðçèéáQK=PJ1ÃE6ÃE6ÅF7ÉE8ÎF8ÑG:×G<ÚG=Ö>3Õ;1Ö8/Õ4,Ö3*Ø4+Û4,Ú6-Û81Ý<4à=4ß<3Ý90Ü5-Ü5,Û7-Ò.$Ý;0Ú=.Í1"Æ-Î7&Ò=)Í:&Ì9'Ô8)â:/ó=9ÿ@@ÿ<>þ37ó,/ê,.á+*Ø*)Ô+(×/,Þ44ä88é99ï75ð74î73è71ã7-Ü6*×5(Ñ5&Í5(çPEÿmcÛHAÈ42×CCÓ>BêVVÙA<Ò>4Ë8.Æ6+Æ:-Æ/Á=.»9+»<-¾?0ÀA2¿A2½@.¼=.»<-ÃC6ÄD9ÈH?ÐPGÓRLÐOIÒNLÕONé^cîagûitÿnzÿduõVjõQiÿUoÿWvÿVtúXpñ^pônyöw€íksÞXañ`mñ`mìboïs}숊Ì|ªth™yjskXON:_VGƒqg¯–’ÜÀ¿ïÕØüéëþôõýûüýþÿúþÿþýÿÿýÿÿûÿÿùþÿÿûùÿõúýöÿÿúÿÿúÿÿøÿý÷ÿþöùðçíåÚéáÔôïÜÿûåÿþåÿÿãÿÿèùúêòôçîðåSM=RL4D=3B;3A:2@93A:4A96@;7A@;CC;IE9MG7OG2RF0UF1UH5WK?RHFXR^jg‚}§‰“Ä’žÚ˜¢ç¤§ö¦§ú«©ü«¬þ¬­ÿ­®þ¬®û¬®û¨¬ö¦ªô¤¨ñ£§ð¡¨î §í¤è›¢æ™žâ’šÛ‹“҆ʃ„ˆ·ƒ¨ˆyšmˆšcz©Xi»Q_ÏMYàIRèAIê=Aé=;ã>8ÝC9ÖH:ÎI8ÅF3ÂC0Å@1äTIàG?Ú;7Ø64Ø88Ø:;Ñ98È74À:/¾<.¿;.À:.Â8+Ã7*Æ4'Æ2&Î4*Ð3*Ñ3(Ô3)Ö3*Ù5,Ý6.Ü8/Þ=3Û=2Ü;1Û8/Û7-Ú6,Ø4*×3)Õ3&Ó3%Ð4%Ï6&Ò=)Ñ>*Ê9$À2È:&Ê4%Õ1'ç51ú<<ÿ=@ÿ7=÷37ê-1á-.Ù--×/.Ü43ã9:é;=ð9=ö26ø03ô01í1/ä1*Þ2(Õ1%Ï3$É1$Ñ=1új_äTLÈ95Ð@?Ë:=äRSäJHÜC=Ñ:3É6.Æ8.Å;0Â<0¿=/º;*¼?-½@.¼?-º;*º;(½;+¾<,¼>0¼>2ÀD8ÈLBÌPHÊNFÌLIÐNLèaeìaføhrÿo{ÿhx÷Zk÷UjþZrÿYsû]tîaræjtë}€ñ‡‰èwyÚ_dñgtþm|óeuëlwö‘•ì¢ŸÄ”Š¢|hjUHQSK>PJ>êDFå@DÙ8=Î65ÍB;ÈD8ÉC8ÇA5Æ>2Ã9,Â6)Â2'Æ2(Ë3(Î4*Ó5,Ø5.Ù4.Û4.Û4,äB7Ý=1Ù7,Ú6,ß9-ß9-Û5)Õ1%Ø8(Í2 Ê1!Ï9(Î8'Ç4"Ê7%ÔC0È7&Î8*×6,Þ5.æ3/î53ö:9û?>ÿLKúHFòBBì>=ê<=ç7:å26æ,1ô+1ø)/ô,.ï/.è1+à4*Ù5)Ó7(Æ0!À.ôdYë]SÏ@:ÔDCË;;ßMMêRQàHEÓ;6É6/Æ8.Æ9/Ã;-¾:+¾<,Á@-ÀA.»<)·8%¸9&½<)¾?.µ7)³7+¸>1ÁG:ÅK@ÅIAÈIBËJEåa_æ^`ñdjþnwþkuó]iðXeø]mú^sõbtèdoãlrì~ù‹ö†…éqsøryÿy†õaqàXföˆ‘ÿ´´Ð®¢ ›‡]jPDR9QT?jbU›ˆÚÀ¿òØÙöàãÿô÷ÿúýÿþÿýüÿþüÿÿýÿÿûÿþùýûÿúôÿòòþòùÿôüÿöûýòÿýôÿÿôÿÿóûõç÷ñáþùåÿýçþüãþýáÿÿêÿÿñýýóüüòXO@WP@WN?UN>TK2G?2H>2F@4GC:GE9JG8NI6RJ5UJ4UJ4VK9XNDULMZTbkhƒ{~§‰Ã‘™×˜Ÿç£¤ö¥¢ù¢¢ü¡¢ü ¤ÿ¢¨ÿ£«ÿ¤­ü¡ªõ¡©ñ¡¨ì¥¨íª©ï­©ó±©ö¬©ø ©ø—§ò’¡â–ŸÖ¦£Î¶ž¾¹…œ¸gz¿L]ÑERß>Mç;Gç?ß<=ÝEBÉ:4ÊD9ÊF:º1)ÛJEèJIéCEë>Bè;?æÚ<=Ô<;ÏB;È?7ÊD;ÑMAÍK>¿=0¸6)½9,¿7+Ã6,È5-Ë2*Ñ/*Ô/+Û2/Þ5.çA5ß9+Ù1$Ý3&å9+ç;-ß8&Õ2Ï2Ì4Ê5!Ç4"Ç4"Ê4%Í5'Ï5)Ê0&Ï2)Ñ5)Ò6*Ò4(Õ3&×3'Ü4)à2)æ3.ë52ë33é/2ç-2è-4í.5ö-3ö+/ï+,ì/-ê5.ã9,Ù7(Ð4%Ã-Ä3"çXHéYNË;3ßNIÅ41ÚHHáOPÜJJÔC@Ì;6È80Æ8,Ç9+È<+Å<*Â;(¾9&¼;(»<)º=)º=+·<,´8,µ;0¹=1»?3»?3¾@4À@5ÄA7ïjaõpiêc_ômjûqqìadôgmÿpyÿlzûhxðdoébiëdjîlnîqoîqoûy{ÿ}…ùZlücwßbpû¬¯¶ªš}‘u]rQJY:LR8snZ¥•ˆË·°íÕÓÿîðÿö÷ÿ÷ûýøüüüþþÿÿþÿÿÿþÿûÿþðÿôåþéæûêïÿîøÿöüÿôþÿóÿþñÿýñÿûîÿúêÿùæÿùãÿùáÿùáüúåÿÿõÿÿûÿÿûYPAXO@XO@VM>UL=TKÌLAÁC5¸:,·9+¹7*¿7+Æ6-Ë4-Ñ2.Ø3/á53ä84ä>2á;-Þ6)ß5&á5'á5'Ú5"Ó4Ñ9$Ë9"Ç9%Ç:&É<+Ë<,Ì8,Î4*Õ3.Ö5-Ó7+Ï7)É6&Ç4"Ë4!Ï4"Ø2$Þ2&ã0+æ.,æ,-æ,/æ-2è.3ì+.í,-ì0.è2.à4*Û5'Õ8'Ò9'Õ?.»*ÖD5Ð>1ÙF>ëVPÚB?ØBAçUVâRRÜKHÔC>Í=5É9.È9+Ç8(È;*Ä;(¿:'½<)½>+º?-¹@/¶>.²:,´;0·=0¸>1º?0½?1ÁB3ÅC5ëi\òmdçb[ðkfõolèbañklütxÿq~ÿo|öirí]fêY`ñbf÷qpþzxûvwÿx~ùRdþ[pä]nö¦©©¦“jŒkZtON_;SZ;us\©ÖĸöáÜÿõñÿúúÿúûÿûüüüüúþýûÿþúþÿõÿúíÿóáÿéáýæéÿëóÿñøÿòýÿòÿÿñÿýïÿýíÿúéÿöåûóàúòÝüôßü÷äýúóüüúÿÿý\PB[OA[OAYM?XL>WK=VJDã=?å==åAá>CàBè;?ã9<Ü68Ö66Ñ96Ì;6ÕHAÄ;1¾5+ÅA5ÍK>ÆH:»=/·8)º6)¿7)Ç7,Ï6.×50Þ71æ95é=9×3*×5*Ú6*Ü6*Ý5*Ý7)Ú:*×>,Å4!¿4¹4!¹6"¼8)½8)½3(À-%ã@;å>8Þ=3Õ<.Ì9)È7$È7"Ì7#Ò7%Õ3$×/&Ù.'Û.*Ü.-Û//Ü./Û,)ß0+à5-Ü5,Õ3&Ð4%Ð9&Ñ>*ÔA/Â1 çSEÒ;0ÚA;ÞC?èJIðTUíUTçSQãOMÝJCÖC;Ï<2Ê8+Å6&Ä7&À7%¼7&¹:'¹<*·>-µ=,²=,°:,±;/´<.µ=/·=.¹?0¾C4ÃE7Ü\Qêg]äaYðlgöpmça`ìfgójqàR^ï^kõhqòemñ`gôeiùqqþxwútuÿnuóJ]øRhä[mñœ¡£œŠa€`UoHOd=W`Aww]­¥’áÑÂÿîæÿøñÿüøÿþúþÿúûÿüûÿýûÿýùÿûóÿöèÿîÜþãÚøÞáùáèûåïüèöýëýþìýúéÿúêÿ÷æúñàôèØòçÕöëÙøñáþúñýüøÿþû\PB\PB[OAZN@YM?YM?XL>XL>UI;TH:SG9RF8RF8RF8RF8PF:LE;KGEç=Fã?FÖ:>Ñ?@ÑEDÆA<º61Å>:êZYÝABã@Cæ=@ã:=Û89Ó97Ð<8ÎA8ÏE;Â:.»2(À/¸9(½8)Â9)Ë8.Ò:/Ù80à91è;7ë>8Ø1+Ù2*Ü3,Ý5,à5-ß7.Û9.Ö=/É7(Æ:)Á<+¾<,¿;.Á;0Å<6Î95ëC@í@<ä@7Ù=1Ï9*Ç9%È:&É;%Ï<(Ð7'Ï1%Ñ1%Ô1(Ö3,Ô1,Ñ/*Ó2*Ó5,Ó7+Ð7)Í5'Ê7%Ì;(Ì>*Ì;(Ï<,ô^PàF<Ò3/Ò.,æ@@ûWXÿusÿroÿjgö^YçPGÕA7Ç5(½. Ä8'À8(»8&¸;)·<,µ=-²=,°<-¯;.­<.°.¼B3ÀF7ËMAß`Wâa[ôpløtræ`aä]aæ]dÖHTçYeógrôgoöelükpþsvþvvûpsûenñDXôKbåXkë’– •ƒ_zYQlCSh?\gEy|_°ª”çÜÊÿõèÿùðÿûñþþôýÿ÷ûÿúùÿúöÿøòüóêûëÚøÞÎóÒÊëÌÏìÎ×îÒàðÖéóÛò÷áöõáûöãüõãõìÛíáÑéÝÍíáÑñèÙüõíü÷ñþùó\PB\PB[OA[OAZN@YM?YM?YM?WK=VJ@Ð@?ÐIE¿>8³2,ÈC<àUPÜDCáACã?@á>?Ú?=Ô@<ÑD;ÏF<Ç=2À8*½5)½9*¿=-¿=-½;+½<)Â:*Ç;*Ï;/Õ;/Û8/à8/ç83é:5æ95ä52ä20æ21ç32æ40Ý2+Ô0'Ë1'Ë7-È:0Ä7.Á4-Ã40Ì:;Ý?@ë8;í76ä71Ø5,Ì4&Æ5"Ä7#Å:%Ë=)Ë8&Ì4&Î5'Ô8,Ô:0Ó9/Ð8-Ð>1Ê;-Å8'Ä7%Æ9'Ç<)Ç<)Ç:(Í>-Í:*Ø>2áC:Ô/-ä::à24ß56×53Ö;6ÞC>åKCêQIêSHèTHäUGË?0Ä?.¾<,¸=-·>-´?.°?/®>0¬<.¬<.¬<.¬=,­<,±=.·A3ºD6ÆLAÞbXâc]ðnlôrrå`cå`eç`g÷kvûoz÷kví`hð_fýlqÿx{ÿy|úmsø^jóAWôC]èUh懣“ƒg]YtI^uIhwPˆf³²–èâÌÿúéÿýíÿþïýÿòûÿôøÿôôÿñíûêäòáØî×Åèǻ伺޺¿Þ¼ÇàÀÍâÃØæÌãëÓìîØôñÞ÷òßóêÙìàÒèÚÍêÜÏïáÖòèßñèáòéâ[OA[OA[OAZN@ZN@YM?YM?YM?XL>XL>WK=VJQI>QI>SK>UL;XM9XM7YL9XM;WK?ULGYSWe^nnjƒut–~}¥„…±†‰´‡‰¹Š‹Á‹ÈŽÏŽŽÔÕӔӋʃˆÀ|¸u|²ov­io«ljœ€lˆ“cy®YvËPoãBdð7Vö4L÷8Hï@EåFBÝJCÛJEáGGèCJò=Nð>LäCI×CCÌA>ÎIDº;4°4,ÉI@ÕLFØBAÚ?=Û;;Ú<;Ø@=ÔE?ÍG<ËG:À8*Á8(À8*¾9(¼9'»8&½:(À;(Ä;)Ê=,Ò<.×;.Ü8.á6.ä6/è50é32è./é,0î02õ47õ77î45æ21Ú.*×4/Õ62Ñ32Ï/1Ò/4Û6=ê:Dí06î02æ3/Ü3,Ñ5)Ê7'È9(É<(Æ8$É6$Î6(Ó:,Ú>2ÝA5ÝA5ØA6ÓG8ÉA1Â;(À9&Ã<)Æ=*Å<*Å8&Ì:+Í7)Í0'æC<Û2/ï?Aã/2Ú*,Õ1/Ò5.Õ81Ö90Ò8.Ì5*Æ2&À1#ÎE5ÆA2¼=.µ:*±9)¯9+«:,ª:,«;/«=0¬>/¬<.«<+­<,²>/µA2ÉSGàg^àc_êjiînoæchðjqõoxúq{ýt~ömuîbködnÿrzÿx~ÿquúipøWfùAYô@[êQfá~ƒ¬—†ykmˆ]o‰ZyŠ`—r¶·˜ßÞÂùôÞüúåÿÿïûÿïõÿïïÿëçúäÜïÙÐãÍÅÞÁ°Ö­¨Ó¦ªÐ§°Ó«¶Ô®¼Ö±ÇÚºÒßÁàæÌèêÔòíÚòéØîâÔìÛÑêÙÏìÛÓéÚÓæÙÑåØÐ[N>[N>[N>[N>ZM=ZM=ZM=ZM=YLUL=XLNÝAEÔFDÈA=ÉHB´:/±7,ÎOFÉB<Î=8Ð64Ï10Ð51Ó>8ÏE;ÈF9ÃD5¾9(Ã:(Â:*¿:'½8%¾9&¿:'Á:&Ä9&Ë:)Ó:,Ù9+Ý7+á5+ä3+ê3-ë*+ñ*-ø-3ü/4ÿ17ÿ37ÿ38ý58ù8;õ8<ò9>ò9Aô9D÷7Fû6Hþ5Eô+5ô-2í12ã4/Ù6-Ð8*Î;+Î=,Ë5&Ñ8*Ù;/ß=2â>4ä=4å>5ßA6ÙJ<ÏG7ÉA1Ä<,Â9)Â9'Æ8*È9)É2'Ó9/á@8ëD>Þ0/à..ë46è66Ø3-Õ7.×90×:1Õ;1Ò;0Í:0É;/ÖL?ÌF:¿@1´9*°6)¬6(«7*©8*¬;-­=/®>0­=/«<+«<+­<.±=0ÀKAÚdZÞc^èkiðosêinõrzüvîfp÷oyùryöjsþlvÿwÿv}ùhoùcn÷RbþB[÷ZM=ZM=ZM=ZM=ZM=YLVJ>XL>YN5É83Ç/,Å*&È/*Í:3ÌC9ÃC6¼>/À;*Ä;)Ã<)Á:'Â;(Ã<)Â;'Ã8%Ä5$Ê7%Ô8)Ù7*Ý5*á3*å3)ê2*õ33ÿ58ÿ8<ÿ4:ÿ-2ÿ(-ÿ(-þ+1ü-3ö)0ò&1÷)6ÿ,?ÿ*Aü 9ó/ö"0ó(.í,1æ0/Ú1,Ô3+Ñ5)Ð6*Ô6+Ý90æ=6ë>7ë:4è71è50â92ßH=×K<ÓE7Ë=/Ä6(Â3%È6)Ï8-Î4*Ô6-æC<ß82à21Ò ì89å63Õ1(Ò4)Ò4)Ï5)Î6+Ê6*È5+Å7+ãYNØRFÊH;¾@2·;/µ;.µ<1µ<1¯9-±;/±=0±=.¯;,­9*­9,®:-±<2ÐYQÜb]ìppôvyîmrõq|ör}ÿzƒÿ‰ÿy€ôhq÷epÿq|ÿuÿktø^jöOaÿA^÷8WéG^Ûntº‹™©„‚žn~šg—hœq¡©‚´º–ÈÍ­ÕܽÌÙ»ÁÔ´²Ì©§ÂŸž¼˜š¶–²Œ±†‰³†µ~¹„•À‹œÂŸÄ‘¨Å™²È¡¾ÎªÉÒµÚÙÄæßÍêÞÒéÖÏáÌÉÛÆÃÔÁ»Î½µÈ·°ZM=ZM=ZM=ZM=ZM=ZM=ZM=ZM=XK;XK;XK;YLYM=WMCWLHXNOZPX]Ub`Yia\rjfokŽsp›vq§{u³ƒ~ÁŠƒÉŠƒÇˆÀŠ~¼ˆy²ƒr¨†r§t«‡l£†\„HL¤B9¶A:ÍC@Þ@?è:;ô<>ÿDE÷><ó=<ì>=ê@AëBIêCMëANãALÐ>>Å@9¾?6·>3°,º7%Á:'Ã<)Â;(À9%Â9&Å:'Ç:(Ë:'Ð9(Ö6(Ø2$Ú."à/%ì7.õ=5õ82÷40÷0-ø**û&(û%'û%'û%'û&*÷!)ø".ÿ'7ÿ(>ÿ!;ÿ6ý1ÿ'8ï#,æ#+ã+-Ý--Ô+(Ò-)Ü41â62è64î66ò65ò12ï./î,,å/,Ü92Ñ:1Ò91ìSK»"Ä+#ßF>È.&Í.(Þ<7èE@â:7Ø/*Ú.*â51å<7ß>4Õ<.Ï5)Ë3&Ì5*Í;.Ë;0Å8.ìbXàZOÈC:¹6,º:/¸8-±3'´6*°0%°2&®2&¯4%°6'²:*´<.³=1°:0ºC;Ö\Wìppñsvöx|ûyƒõq|ÿ|„ýw€út}üs{ÿr~ÿr}ÿmxÿgsü`nôI\ÿ>\ÿ>[äAVÔek´•€’¡zƒm}™f~”c‡—j”Ÿwž¦ ¨ƒœ¨„’£Š£|€Ÿvzšqyšo|r vƒ¤u‚­wƒ³y‹¸‘¼„“¾†—¾‡œ¾Œ¢½§¼“¯½š¾Â§Ï̹ßÓÇãÒÊÜÇÄÔ¿¼Ìº¶Á²«¹ª¥ZM=ZM=ZM=ZM=ZM=ZM=ZM=ZM=XK;XK;XK;YL]P@[OC[NFYNJZPQ\SX_U^_Wfd\tibƒng‘qjxp¬€y¼‡€ÄŠÄ€Á~ºt«Œn¢—q¤¡u¨šjž™W{=Aª5+±5+Â<3Ó@8Ý>8è?:óA=õ=;õ;<ô;@ñ>Bî@IèAIâ@KÚAFÇ<9½=4¶<1±;/«:,®:+½A5ÐJAÚG@ÜA=Ô63Ð51Õ@9ÍC8»9+²5#½8'Â;(Ä=*Ä=*Ä;(Æ;(Ç:(Ê9(Ï9(Ï6&Ô2%Ú2%ã5*ê8.ï80ð91ç1&ç/%ê.%ï,&ö+'û+)þ,+ÿ-.ü*-ú%+ú$.ÿ'7ÿ$;ÿ7ÿ3ü0õ0ö.9õ3<å*1Û(,Ü.0Þ02Û+.ñ:>ô7=÷4:ö26ö/4ø03ù25ô87Û2-Ú;5×82äE?äE?Î/+Ñ2.Á"Ô51á?:èE@à=8Ø3-Ù2,Ý60Ý:1Ô:.Ï9*É5'Ç5(È9+Ê<0Ê<2Æ9/ícYáXNÉ@8º4+Â91Ã:0¿6,Â9/¿5+¾4*½4*»5)¸6)µ5(´6(°6)´;0»B9ÓYTèljïqtöx|þ|„øv€þ|„üyùv~þuÿsÿp}ÿkwüdqý_nöI]ÿ>\ÿ>\éCYÓeh®Žw‰˜oz•bu’\xŽ]cŠ•k˜p‹•p…”mp‡]l‰]h‰\g^k_q•ey›izŸk¬t„±vŠ·|»}¼“¼‚–½†›»‰›µ†¡³‹­¶—¾½¨ÏÆ·ØÇ¿ÖÁ¼Ï¼¸Æ·´º¬©²¤£\L<\L<\L<\L<\L<\L<\L<\Lù:Aö=Eï@GæAHÙ@EÏ@BÀ;6¸90±9+­9*©8(­9*»?3ÏF<ÙD>×96Ù74Ú;7ÜC=ÝOEÎH<µ3#¾9(Á:'Ä;)Æ=+É=,È<+É:)Ì9)Ï7)Ï2#Ó/#ß4*î=3ô?6ñ91é4+à4&ß5&â2%å/$ë,$î+%ñ+(ò+(ó+-ð(+ò&/ø(6þ%:ý7ü3ø3ô%7ò0;ó5Aò8Cð;Dðä,6ð2<ó/;ö.9ö-7õ.3õ.1ó/1í42Ü0,â=9Ú64ß;9ÿmjåCAÑ/-Î/,Ù:7ß@<àA;Û<6Õ7.Ö5-Ö5+Ò6*È6'Ã6%Â6'Ä8)Å;.Æ<1Æ<1Å;1ë`YáTMÉ<3¿0(Ë;3Ñ>6Î;3Ò=6Ø=8×<7Ô=6Ï<2É;1Ã9.¼6*¶6)¹;/¼@6ÏTMãgeíorøz~ÿˆû|ƒû|ƒûyûx€ÿwÿsÿn}ÿgvû`pü[mõG^ÿ\ìFZÎ`až~ev…Zi„Qh…OmƒRt…X{ˆ]}ˆ^x„\q‚X`zM_Pa…UeYn•`uœg} j~£mƒ¬r„²tˆ¶x‹¹y‹¹y¹z‘º~”º“±•¬€›©†©­’ºµ¢Ç¹®Ë¸²È¶´¸¬¬ª¡¢ —š[K;[K;[K;[K;[K;[K;[K;[K;ZJ:ZJ:ZJ:[K;[K;\L<\L<\L<]K=]K=]L<^M=^M;^O<^O<^O<^Q@^Q@]OB[OC\NE[NF\OI]OO^P_bTmdY{i^‰pgœ|t­…{·ˆ{³™…º¥…´¯€ª¸z¡ÆxŸÑuœÌcŒÈMlÜFRßA@ÕA=ÏE;ÌH;ÍG;ÓE9ÞA:î@Aõ0ÎD:Õ<7Õ31à;9åA?áD?èSLßUJ¿:+Á9)¾7$À7%Ä;)É=,Ê=,Ë9*Î8)Í4&Ò2&Ù2)å9/ñ>7õ>6ð5.ä/&à6)Þ6)à4*ã1'ç.)ê-)ì*(ì**ê),è',ë'1ò)9ö&<÷!;û=û%Aû6Hä(6ç.<ÿP\ÿ`lÿP\ò;åGDÛ=:Ú<9Õ:5Ò80Ñ7-Ð6*Í4&Æ3#¾5#¹6$»8&¿;,À9é=9æ?9á@8Ù?5Ð<2È:.Á9-»9,»=1ËNHàc_ìnoú|ÿ„ˆý~…øy€øy€üyÿx‚ÿt‚ÿn}ýetù^n÷VhóE\ý8Vÿ^N>\O?^NA]OB^PE^OJbNYbQdcTqdZ}le‘xr¢w¨ƒv¤”}§¬†«Â‰©Î‚žÚw”ál‰ÛXwÚD_óBTúDPïJPáIHÐE>ËE<ÐF<ÙD>èBBð@Cõ@GõBHíDGßCDÏA=Â?7¿@7µ=/®:+«:*ª9)®8*»;.Ì?6áFAâ=;îBBëAAÞ;6ãJBæXLÕK>È@2À8(¼3#Á8(È<-É:*Ë7)Ð8+Î0%×3)à8/é;4í:5í60ë0+å,'ã0,ã1-ç10ì31ó25ö37÷48÷6;ì-5ê,6í.=ñ0Có-Fö)Gý+Nÿ3Rô9Lå3?ð@Mÿ_lÿlzÿWfõCSõ>Pî3Dí3Aí3>é6<ã99Û83Î4*Ç/$Ë2*Ç.(Ð72òYTö\ZòXVÛA?âHFÜB@Ô<7Î70Í6-Ï8-Ï9+Ê7'Â5#¹8#³9$µ:(¸=-¹;,¶6)¼7.Æ=5ÛNGÙEAÎ50Ð1-á>9ç@:ã81ç51ë20î21ë52ç83á:2Ø:/Ð9.È:.¾6*º8+ÈIBÜ_Yënlû}€ÿ…‰ýƒõv}öw~üyÿx‚ÿsƒÿk}ýdvù^pôSeôF]ý8Vþ=ZïL]ÀTRz_BWhÑC?ÖEBãEFèBDîAEíCFçDEÚEAËB:¿?4»?3±;-©8(¨9(ª9)°8*¼:-Ê;3èIEé??ë=>å78Ú2/ÞA:îZPôh[ÚPCÉA3¾5%Â6'Ç9+È9+Ë7+Ò8,Ñ0&Ú6-æ;4é;4ê40è/,ê-+ë--ó49õ3;ø3=ü3=ÿ1>þ0=ý1=ù1>õ0Aò1Bô4Kõ5Nõ0Nö-Oÿ1Xÿ>_æ3HùO\ÿanÿ_nÿWfûP`ôDXé8JóAQê:GÝ2:Ò/2Ê2-Â8-½;+¼:*Ä:/À2(ÙJBúkcÝLGáPKÏ;9Ï;9àLJÔ@<Ê70Ê7-Î-±9)¯3'º:/ÊD;ÖGAØC=Ô72×2.ç;7ì:6è2.í2-ò,-ô,,ò./ï31è71â:1Ú<1Ò>2Â6)º4)ÅB:×XRçjhú|}ÿ†‰þ€„õv}÷xýz‚ÿx‚ÿqÿi{ûbtø]oòQc÷I`ÿ:Xý?[ðO_ºQNqX:Sf8]uEa|InSv†Y{ˆ]~‹`g‚—l€œl}Ÿm|¤o}¨p€©o‚ªnƒ©l…©lˆ«qˆ®qˆ°r†³r„³oƒµp…·r‰¸t‹µv‰¬tŽ¥wš¨„°´™ÈïØÌ¾ÚÑÌÂÂÌ«±Á›¡±ZK8ZK8ZK8ZK8ZK8ZK8ZK8ZK8ZK8ZK8ZK8[L9[L9\M:\M:]L:^K<`J<^K<_L=^M;_N<^O<^O<^O:_P;`O;aP>aP>aP>aPÉ@8¾>3¸>1¯9+¨7'©:)­<*´<,Á=1Ï?7ß=:å99ã03â/2à42Û94æMEülaòh[ÙQCÆÍD>Á63É;7äUQÕF@É91È8-É:,È9(È9(Ä=)±?'¦<&¨;&¬=*«7(¬3(¼=4ÓLFÖGAÝE@Û96Ü30é73ì51ë0+ô1-ý,/ÿ+-ú./ô1/í4/æ81ß;1Ø>2É9.½3(À;2ÏNHáa^÷yzÿˆŠÿƒ‡ùzû|ƒÿ{†ÿx„ÿn~þew÷^põZlëL`õIaü9Wû=YîM]²JGhQ1Qd6\tDf~Nuˆ[Žc„h†’jˆ—n‰žsˆ¤t„¦t§r}¨p¨n©mƒ©l…©l…¨n‡«n…­o…¯o°l€²k‚¶n…·r‡³t‡­t§wœ¬…²¹šÈƯ×νÙÒÌ»¿Ê¤¬¿’š­[J8ZK8[J8ZK8[J8ZK8[J8ZK8[J8ZK8[J8[L9\K9\M:]L:]L:^K<^K<^K<^M=^M=^O<^O<\O<`Q>aR=aR?bQ?bQ?aP>aO;bL>hOKgNRbP\cWkjfuv”}|œx—‘z–«•Æ„’Ú}…ðuzþlmÿY[ýDLþ/Iÿ5Rÿ4½=0µ?1¬;+©8(­<,´?.»@1ÊA7ØC=Ù74á85Þ..â30æ:6Ó0'Ï5)ëUGÿwjë[PÑC7Ê<0Ë;0É7*Í6+Ô:0Ú70ß82å63ç32ê01í12ô36ý4<þ%6ÿ#9ÿ"9ÿ"9ÿ!8ÿ6ý5ø6ï2î9ð%Bï(Gî&Jñ'Mÿ3\ÿEhÿbuÿ`l÷WcñQ]òP]ïMZâ@MÔ2=Ú=FÌ7;»/.®/(¦5'¢;(›?&œ>%ª9'²8+ÒVJ»;2Ä?8¾41½2/ÎC@åWSÕHAÈ91Ä6*Å6(Ä5%Æ5$Ã:(±<(§:&¨7%­9*¬4&¯1%Â?5ÛRJÙIAáHBÞ;6Þ2.ê41í1/ï-+ü22þ,/ý+.ù+-ó++í-*æ1*ß4,Ö8,Ñ=1¿2(¼7.ÈIBÙ\Xówwÿ‰‹ÿ‡Šû€…þ†ÿ}ˆÿv„ÿj|þ_s÷XlöTiêD\õD^õ6Uñ:VàLZ¥HC^K-Mc5Uo?b}JtŒ\€–g‡˜lˆ›nŠ r‹¥vŒ¬z†«wªr~§m|¥i}¥g¥g‚¦i‚¥k‚¨mƒ«m‚¬l®h~°i³j„¶o‰¶s‰¯rެx™°„­»˜¿Å©ËʵËͶ½Åžªº‹—§]K7\K7]K7\K7]K7\K7]K7\K7^L8]L8^L8]L8^L8]L8^L8]L:]J<]K=^L>\L<\L<[N=]P?^SA`SB_R?`P@bQAcRBdQBdNAdLBjMIhKMdPYf[lnk†w{ž€…­‰ˆ²ƒ©¥‡©¾ˆ Ð‚’ây~ðsqújbÿa^ùJWñ>Që:Lî?NïCQê@Kæ9Ê=4Á;0¸:,§6&¯A0­<,¬6(¿A5ÌF=Ì=5Ð72Ú85Ü71Þ5.Þ6-Þ8*Ý<*×:'Ó6%Ù;0ðSLòZOÙE9Ç8*Í>.ÔB3Ò:-Ô3+ðGBá//î5:ó6=î,7ÿBMñ'3ú&2ÿ)2ÿ(2ù'ý"*ÿ'/þ'/ð&ð)ù+7ê .ì&7ñ-Aç#;ÿXrç-Dÿ]lÿ_iþZcùU\õPWëHMÝ?@Í84Ë>7ÄA7·?1¦7&™2!™6#š;'Ÿ<)§8-®7/ÂE?¿;7½31Ä64Å54ÔDCÛLHÚKEÑD;È:0Ä4)Ç5(Ë4)Å5*¼1¹=3Ö_Yésqÿû„†û‡Šÿ„Œÿxˆÿh}ÿ_wÿ[uÿUoøLføEcñ:Yô;[æ?YÛ]i‹@;VF-L^6YuBg†Mw–]}œcg€¡jƒ¦n‚¨o€§n¦m~¥l}¥i|¤h}£f£e£f¥l¦m«l¬k~­g®f±gƒ³i‡µm‹´r°vŽ®|™´‰§½™±Á¤²Á®¦²°˜žz…‹]K7]K7]K7]K7]K7]K7]K7]K7^L8^L8^L8^L8^L8^L8^L8^K:\K;^L>_M?^N>[N=[N=\Q?^RB_SC]QA]OB_OB`NDbPFcOHeNHiMJgNQeS_g_tnny~¨€‡»‡ŠÁž•Ê£‹»«£¹xÓyƒê|{ôvjöi`ø]aóOZìFRòHSøIVõEPï?Jë;Eä9?à:<Ú::Õ=8Î?7Ç>4À/Ç8(Ê8)Ó;.Þ;4öJFä01ð6;ö6Añ.<ÿ@Nï'4ó$,÷%(û),ý+,ü*+ø((ö((÷+,ï$'í%(ê%,ý;DÙ'ð4CüARØ&6ÿjuÿbjþZaüW]ôOSåBC×<8Ñ>6¾8,¿D5¹H6©>,™/)(’(ž-%°:6ÑTPÎHGÃ54Æ45Ñ==ëWUØGBÖG?ÐA9Ç9/Æ3)Ê6,Ð7/Î70Ç=3Â91Â5.Ã2-É4.Ñ83Ø?9ÞE=äJ@ÞA8Ú6-Ý0*ç0,ò21û03û03ô02ó12ô01ó/0ó0.î1-ç4-ß9-×=1¿3$¾aP@`P@]P?\O>[O?[RC[QE[QG\OG\OI_PMcQOfTTgUUgUUgV\h]nli†sv£|ƒº‚ŠËŠÔ˜‘× ŠÊª‚´¹}ŸÏ€“䄆îvósjûeg÷S\íGQðFOöHR÷EQòAKî=Eä7=à7:Ù99Ô<7Í@7ÅA4¾?0¶>-­>-ª<+«:,¸B6ÇH?À;2»0)Ê:2Í6/Ð6.Õ7,Ø8,Ù7(Ù8&Ü9&à:*Ý4-Û4.âA9éOCÞH:È5%È2#Ù@2â>5õHDè13ò5;ù7@ø4@ÿESø2?ð)0ë#&ì$'ù13õ-/ï''ì&%õ12ë)*ö8:è+1â)1ë3=ÿR^ï=Kÿ[gþ^fñV\îOTðMRêEIÝ:;Õ74Ô?9À6,Á?2¼B5³=1¬7-¥3)¡,#œ' š%©/*ÇECÂ::¼,,È35×ABô^]Ð?:ÒC;ÐA9Ë=3Ì9/Ô=4Ú@8Û@;Û@<Ø=;Ý>;ãA?ä>>à::ã?=ëIDàB9Ý<4Ù5,Ý2+ç1-ð31õ12ø02ô02ô02ô01ó/0ó0.î1-ç4-ß9-Ø>2À4%º8+µ;0Ð[Tízwÿ“’û‡Šúƒ‰ý~‰ÿr‚ÿdyÿ[tÿTqÿNmÿFgû=_ô=\îEbßTg¢AHp;3SH2Qa<]xEf‡Nr“Zu˜^tš_xžc{£g{£gy¢fy¢fy¡cx byŸby a| bz cz¢f{¤h{§h{¨e{©a{©`}«`®`‡²jеn‹²s‰¬t†¦w‚žuy“no†lSeYAPM2A>^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^M9^L8`N:aP<`Q>]P?ZN>YOCXPEXOH[QO_UTbXYeX_iYcl\fk^glaildqok‚rtšy~µ†Ê…ŒÚŒŽáŽ‡×Ÿ‹Ó­ŠÄ³€©½yŽÌ{Þzò‚wÿsrÿcgùU\ôMTõGPôCMò>Gï-±=0¼F:ÌRGÇH?º5.º1)È91Í81Ó;0Ù=1Û;-Ù6'Ü6&à8+à5-Û2+à=4ìNBãK=Ò:,Ñ8*àB6ß7.ð>:é/0ð16÷4<ü8BÿNZÿLUý>Eò38â$&í/1ê,,ð22è**ë/.ò::Ñæ37Ý,2è9@ðEMÿXcóMWØ=CÚADáBFá>AÞ9=Ü89Ø88Ó97É83Â91½:2ÀA:ÍNHÖVSÐNNÃC@²72¶95ÏKIÙMLãQRïYZêRQñYVÉ51Î>6ÒB9Ð@7Ó?5ÙB9àC<â@;é?@ç8=ì9=ò?Cï:?è58ì>=öMJÞ93Û60Ú3+Þ3,å4.ì30ò21ô01ô02ö/2ö01õ/0õ/.ð0-é4-à8-Ù?3Â6'·5(³9.ËVOï|yÿ“’üˆ‹ý‰þz‡ýoücwÿXqÿOlÿFhÿ@cû9\ô?^éKdØZh…35g;0WO8WgCa{Kj‰Ps’Yt•\u˜^wby¡ez¢fw dv awŸavž`xŸ`xŸ`{Ÿaz cz¢fz£gz§fz§bz¨`z¨]|«]~­_†²g‹´nŒ³tŠ­s†¦u€qtŽii€dQcUDSL8G@^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M;^M9]K5_M5`P9_P;\O>ZN@XOFXQKYPQ`W\g`hnfsshysg{sg}qh}ol}pq†rw—v}«z‚Á‡Ò„ŠàŠ‹å“ãŒÚ „¿žuŸ l‚¬nq¼vlÒviòsmÿllÿgiþ^`ûRWõFMï3Û=1Ú6*Ü4'â6*à3,â70ä=5åE9âF9ÞB3ÞA2â>2Û0&ê72ì0/ï.1ñ.4ú7?ÿPXÿ]dÿZ_ÿOSá.1ã03à,-÷EEè66Ü,,Û-.ë>@Ü25Ù37ÿbhà=BË*2Ê-4Á&*Õ;=á@EÛ6:Ù37ß9=Ü7;Í/0Ì43Í;;ÕGFÞRSì`cõilôekê^aÄ@>ÆE@å^[øhgÿopÿjjåKK×=;É40Ñ>7×D<ÖC;Õ>5Õ<4Ø:1Ü41î5;ñ-7ð,6ò.8ï,4ë,3ó9<þJKß3/Ü3.Ú3+Ü3,ã5.ê40ï4/ò21ô02ö/2÷/1ö.0õ/.ð0-ê3-â7-Ù?3Æ8*´2%²8-ÃNGï|yÿ’‘ÿˆŒÿ‰ÿw…úl|øatûTnýHgÿ>bÿ:_ú6\óAaàNeÂWap/+_?0[W>^lIe}Mk‰St’\u–_v™_xžcy¡cx buŸ`uŸ`u_vž_wž_xŸ`{Ÿaz¡bz¢d{¥e|¦d|§`y§^y¨Z{ª\}¬^€¬a…¯g‡®m‡ªp…¥sƒ r{•nrŠjexe[k^RbU_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N<_N:^L4_N4`N8^O:[N>YOEZSMZTT_ZahbprmzuŒ{u‘{q“zp“vp’qt“rxšt}¨w¶zƒÄ~†Ï„‰Ú‹ŒÞ–Ü™ŠÍ›…¶¢ƒ£ª„‘«~yŸl[šQ>¼MBÔQIâWRëWUñSRñKMí>Cå4:é9<æ9;à;9Ø=8Ó@8ÊB6ÀA0º?/³9,ºA6«5+£.$¾I?Ùg\ÙdZËUI¸<2¸6)À3)Î:0Ù;0Ú6,Þ3)ä6-ß1*ä71ã;2Ý9/Þ>0ãF5äB3ß9+ß1(é4-ð31ï-.í*.ô17ÿEJÿV[ÿ]bÿ\aâ9<ã9<Õ+,ôJKâ89×//Û57Ì()Ì'+øXZÝ>BÕ9=Ñ6:º#Ä(+Ü<>æAEÝ49Ù,2Þ17Ù05Í(.Ò37äKNöaeûhnùcl÷`iú`løbkÖLLÕNJê\ZêVTçMMãHFÏ42Î3/ÙA<àKDäOHßJCÙ@8×:3×6.Ü.-õ2:û-:ø*7õ'4õ)4ø0:ÿ>CÿJJà1.Þ3,Ü3,Ý5,á4-ç4/í4/ð3/ô02÷/2ù.1ø-0ö..ñ/-ë2-â7-Ù=1É;-³1$±7,ºC=ìyvÿÿˆÿ|ˆÿqöhxö_rùRlûDcÿ9^ÿ6]ú6\ðFcÑN`¢IMe5+VD0[Y@^lIe|NkˆRt‘[w•_x™`{ždz cvž`s›]rœ\s›\tœ]v^wž_{Ÿaz¡by¡bz¤b|§b{¦_x¦[x§Yz©Y{ªZ~ª_ƒ­e…¬k‡©m‰§s‰¥u„s|”ru‰pnlfwe_P=_P=_P=_P=_P=_P=_P=_P=^O<^O<^O<^O<^O<^O<^O<_N:aP6aP6aO9^O<[OA[RK\VV_Zakgvso†}z—‚~¡|¥}w£{u¥xv§sy©s}°x¸{„¿~†Ä„‰ÉŽÎ”“Íš“Ç •½«›µ¼¦²É­©Å¦”ªˆmœfJœE2¯A4¶@4ÂB9ÖHDèNNîJKì?Cë=?é;=ä<;ß=:Ù@8Ð@5È>1Á=0½:0¾?6¯4,§1'»I?ÑcVÖh[ÕeWÃOBº>2º4)Ç7,Ö90Ù5,ß2+ç60â0,ã4/â7/Þ7.à>1åC4ä>0Þ4%æ4*é0+ð3/ð..ï-.ò14ó78öBEöMRüY^éFKöQWØ37ëFJÝ8<æAEÚ7:Î.0Ñ05äHKÒ7;Ð7:¹#%Õ;=Û8;å;>ëÿ0=ú*7ü.:ÿ;EÿCHûABã1/ß4-Ý4-Ý5,â4-æ3,í4/ñ40ô02÷/2ù.1ø-0ö..ñ/-ë2-ã7-Ø:/Í>0µ1%±7,²;5ésqÿŠŠÿ‡ÿv†þi}óató[p÷PjúCbÿ7`ÿ7aù;_ìLf¿O[~86]=0NF1VX@ZeEcxMj…RrŽ[v”^yša{ždxžas›]p˜Yp™WqšXqšXt›\uœ]y_xŸ`x¡_y¢^z¥^y¤\x¤Yx¤Wy¥V{§X©_‚¬d„«h†¨l‡¥o†¢q€šmx‘jq…ij~cbv]_P=_P=_P=_P=_P=_P=_P=_P=^O<^O<^O<^O<^O<^O<^O<_N:cQ9cQ9aP<]P@ZPG\TR_Zaa_mtrŠyx˜€¨ƒ°~~°yy¯yu°wwµw|¾x€Á}…Ä‚ˆÄ…ŠÁ¿—–¾ ¼¬§»¶¬µ¾³±È¸«Ð¾¦ÖÁ¢Ñ»–Ьˆ¯oT®\G¤G5¨>0ÂG?àWQïWVñNOé@Cê=?æ<=â=;ß=:×=5Ñ:1É90Á80Á<5¹:3¸=5ÁOEÇXMÇ]OÑeXÓcUÂL>¼:-Å8.Ò91×4-ß2,ç60æ40á2-à5.ã<3çC7æC4â:-ß3%ê5,æ.&ð0-ï/,ð31ñ54ç-.â24çBF÷X]öW\ÿouåDJëHMà@Æ02Ö:=òHKî9>ð7?ø=Fò7Bè-8ô>Jÿ]gÿmwÿjrÿcn÷]gú^kÿaoÿ]nùYeò\]ãPIâJGÕ74Ò/0Ù54Ò0.Ø95ßD?ãJDâIAÙ@8Ó6/Ö4/Ü71è66ê'/ü0<þ2=÷+6ù0:ÿ>Eý?Aì44â3.à5.Þ6-ß4,á3*è3,ï4/ô41ö01÷/2ù.1ø-0ø..ò/-ë2-ã7-×9.Ñ?2¶0%²6,°61èpoÿ‡ˆÿ†Žÿp‚ücxñ\pôXn÷OiûBbÿ9aÿ`P@`P@_O?_O?_O?aQAbRB_O?]M=]M=aQAcSCbRB`Q>dS?aP>]P@^QI[QPZSZeapsq‰yxšz|¥~€±€¹}ºxz·rs´lo¶twÈv{Ì€ƒÊ‹Æ–—䤾²°»¼¹´ËƳÓ̰ÙϬÛϧÜÏ£ÝУÙ˜٘Ѩˆ¸€g ^FËzgÖue½H?×QN÷ccéKLå?Aâ89ä::â:9Ü75Ù61Ö;6Ë81À5.ÇB;»<3¿I?ÆXK¹OAÎdVÑcTÌXIÅG9Ä:/Í6-Ø7/á6/ã4/ß0-ß2,à70ä=4à<0Ý7)ß5(å7,ä/$ê/&ì/)î1-î20ë40è51â64×79æJNõY]íNS×8=×6<ùX`ÿ~„ÿ~†ÿouÿgoÿipÿflõ\añX[ûZ_ÿUZÿDKü8Bû7Aö2>î+9ì0>ñ=HÿS_ÿ`iÿgrÿepþbmÿcnÿ`oý]gíSSßF@Ö85Ö41×11×/.Ø31Û94áD=ÜB:Ù?7Ö<4×90Û81à93æ66ð7<ó4;ó4;ö4<õ6;ò59ë33ã1/Þ3,Þ5.ß7.à5+ä3+é2,ï2,õ20÷12ø03ú/2ù.1ù//ó0.ì3.å7.à?5Ì8,¿6,¯/&¸;7ÒXWÿ˜šþ{ƒÿm€ÿe|ø\rðPhôGeüCeÿ;dù9`õNlÓRd‰=?P, C;&CG.KM5Y_CZjEcxMqˆZx’bx–`t•\r–Yq˜Yl•Sm–Rn—So˜Tr™Xt›Zuœ]uœ[t›XtWv Xw¡Wv¢Wv¢Uu¡Tt S{¥[{£]zž^u—[m‹Ub~MXrCSj>AW0?U/`P@`P@`P@_O?`P@aQAbRB`P@_O?`P@bRBcSCbRB`P@fVG_QF\OG^TSaZad`omkƒvw–wy¢{}®}¸x|¹quµkp´lo¶nq¾uvÐ|~Õ‰‰Ó˜˜Î¨§Ç¸¶ÁÉźÓαÛתâÛ¥çÞ¥æÝ¢äÛ¤âØ£ÛÑ ÔÇ›Ó¼š»œ€©}dÅ‹wÊ}m´VJÒa[örpìZ[çKLã?@ç=>ë>@ç;;â66Û64Ö=8É83Ê?8¹6.¸>3½K@¶H;È]MÝo`Ô`QÆH:½5)Ä0&Ô6-Ü5-Û0)â51å95ä=7à<3Ü8.Û5)ß4*ã5*ì7.í5+í2+ë0+ç0,ã2,á4.Ý52Ö87Ø>@äJLóW[ú^bü\dþ]eÿaiôS[ïNVñQYÿ_gÿjqÿflõZ`óNTí4:ñ,5ô*6÷-9ñ'5å!-æ'6í7CþPZÿZdÿblÿdmÿenÿcmý[hõQZåEEÞ<7Û64Þ63ß55Ü30Ú2/Û62à>9Û>7Ø;4×:3Û81ß82å95ç:6é9;ê7:ë7:î79î79ì65å31ß2,Ü3,Ý6-ß7,â6,å2+ê1,ò1,õ20÷12÷03ú/2ù.1÷//ó0.ì3.å7.ß<3Ô=2Â8.¶1*·74ØZ[ÿ“ûs}ÿfzÿ^vùWo÷OiùFfû?bü^QA^QA^QA^QA_RB`SCaTD`SC_RB`SCaTDaTD`SC^PCbUM\QM[QRcYbkdtqm„vu•y{¤y{¬y~¶x|»nsµei°`g¯jn¸ruÆ}}ׇ„Ý—”Û©§Ø»¹ÏËÊÈÜØ¿åá´éäªíè¦ðé¥íå¤çá§âÛ§×Ï¡Ëܸ¯©››ƒk¨ƒp§o`œRGº]UÝmi÷uuï__äJLå@DëADì>@è8:â66ß=:Ô;6ÔA:Â70·7,·>3®=/¶F8Ûj\ßi[Ù[MÊB6Å2(Ñ4+Ù6-Ù2,Þ52éA>ìGCà=6Õ2)Õ1'Ú2'Þ0%æ4*è1)ç.)æ/)ã2,â7/á=4àB9Æ-(Ê43ÜDCðVXú^b÷ZaóS[ñQ[èFQêHSïOYü\fÿmvÿntôY_ã>Dé.5ô-4û2<ü2>õ+9í'4ö6EÿKW÷ISõPWøW_þ^fÿckÿ`i÷RYéBIÞ97Þ71ã75é<8ë;;æ95á51Ý60Ý:3Ù;2×90×90Ü71á83ç:6é<8ã99ã99å97ç98è88æ74á40Û2+Ú6-Û7-Þ8,â6,ç2)ë0)ó0,÷10õ12õ13ø02÷/1÷//ò0.î3.ç6.Ý90ÜD9Ç80»4.µ/.ä_bÿƒˆølwþbxþWsúPmþLlÿCfö:]ó;_ìIfÔSgDJl;4O>,=<':?(ED/FH0Q\U'B\/E_2Ic6WJ:ZM=\O?^QA]P@^QA_RBaTD`SC`SC`SCaTDaTD`SC_RB\PDZOMZQVbXcjcsqm†vu•xz£z|­w|´sy·mr´bi¯]d¬ag±lr¾x{ʉ‰ß•‘夡䶵áÇÄÙÕÑÎáÝÄçä¹ëæ¯îê­îè¬éâ«ãÛªÚÓ©Ë¡»¶™¥¥›™„“ˆv˜q™rc›bW³i`Ïrmû‹‰õutê[]æLNèCGí@Dìô@?ï=;æ95à72Ý82Ú91Ù80Ù80Ü71ã73è96é:7â:7à;9ã:7æ:8ç:6å84à5.Ú3+Ú6,Û7-Þ8,â6,ç2)ë0)ò/+ö0/ô22ô23÷12ö01ö0/ò0.î3.ç6.Ü8/àF<É91¾3.¶,,îfjÿy€øgtÿbyýTqþKkÿGjÿ>cò6Yë=^ãQhÄXeˆBBgC7[N;GF1AC-JH3EE-LU6Sc>btLlƒUp‹XnRkPiŽKgIhJh‘Kj“Mk”Pm–To–Wp—Vt›Xs›Uq™So—Pj“MgJeŽHdG`‡D]AWy=Rq8Mi6Lf6Ne7Of8Lf7Oi9Sm>UH8WJ:[N>\O?]P@]P@_RBaTD_RB`SCaTDaTD`SC_RB_RB^QIVMR_Xhnf{tp‰xt—xw¡xz«y{´sy·jr³`g­[c«_g°jr»v|Æ€„Γ•àžžä­®ç»½æËÉßÔÓØÝÛÎá߯åá¾æâ¼äß¹à×¶ÚÐµÎÆ±¾µ¦­§›˜šŒŒŽ€‰…yŠ|q‘vk›si¨meºoi扄î~ósrñedñWYðMNîDEì@@ã:7à;7äB=ÞE?Ì<3Æ=3ÄB5¯1#®0"ÇI;ÜXKÖN@Ì=/Î8*Ð6*Ñ3*Ö42õUUÿkhú]XãD>Ü;3ß;2ã80â4-ã2,â1+Ý0)Ô0'Í/$Æ/$Â0#Å9,À4'Á3)Ë:5×CAÛEGÛBGÚ@HàDOëOZòVaòVaú^iÿgoóYaáBGê:<í57í38ï28ñ3=÷9CÿHSÿV_ä6?Ý4;ß6;ëADùJOüIMô;Aé13è51ë95ï<8ò<9ó;9ð:7é73â70ß;2Ü;1Û:0Ü90ß82ä73è64é75æ:8ä;8æ:8è:9è;7æ95á6/Ü3,Û7-Ü8.ß9-á7*å3)é1)ñ0)ô1-ó32ñ33ô22ô01ô1/ò0.î3.ç6.Þ7/àC:Ê70À1-À13÷jpÿqzúftû]túPmÿCfÿ=dÿ9cõ8^æEdÙZm«V[wE>dJ=aYFTO;KI4PI6GE.GP3L\8ZlFf|Nm…SmŠRlŒMhJfŽHgHg‘Ii’Lj“Ol•Sn•Vo–Ut™Vs˜Un•Rj’LfKcŒHaŠF_ˆFZBX|?St;Pn8Ok:Rl=Wn@ZqCUo?Vq>WqARE5UH8XK;ZM=[N>\O?^QA`SC`SCaTDaTDaTD`SC`SCbUEaVP^Vcje|yu}yšzy¡xy©vy°sw´jr³cj°[c«]e®hp¹v~LJшŒÓ™Ý£¥à¯³ã»¿åÆÇãÏÎÞÔÓØ×ÖÑÙ×ËÙÖÇ×ÑÅÒÉÀÌþʹ´¨¬£šŠ‹†x{tyvquleleogŽa[`[ÀsmØyuð{ü|yÿrpýccöSTðHGïC?ê>:á<6àA;Ñ:1ÓC:ÝTJÂ>2¸6)½9,Â=.È?/ÏB1×C5Ö@1Ñ7-Ð2/êLMú_]òWSßD?Ù:4Û81à70æ93ç92ç92â:1Ú9/Ñ9,Ê8+Ä8)°(¸3"È@2ÓI>ÒD@Ë;:Ì7;Ï:@Ñ7AâHRíV_ðYbõ^g÷`iêU[ÜAEå@>ì?;ñACúGJÿLTÿQYÿT]ÿV^á4:Ú/5Ü/3ç7:ô=Aø;?÷48ó12í42ï95ð86í42ë20ê20ç40á4.ã<4à=4ß<3Þ;2á83ä73è43è43è88ç98è88ë99ë97é75â5/Þ3,Û7-Ü8,Ý:+ß7*ã2(ç0(ï0(ò1,ñ42ð43ó32ó11ó1/ñ1.ì3.ç6.à91Ù<3Ì71Á0-Ñ@CÿnuýkuùbqðRiõHfÿ;aÿ4^ÿ6bû>däNiÊ\i‹GFjF:]L<]VCXQ>RJ7OG4ID.DJ.GU2Sc>^sHgMj‡OjŠKgŒGgŒFfŽGfHgJi’Nk”Rm”Um”Uq•Uo”Qj‘NgŽKcŒH`‰E_ˆF^†G\‚E[~DWxAVr?Uo@YpB]rG^uG[sCYtAXs@NB2QE5UI9WK;XL\P@^RBaUEbVFbVFaUE_SCaUEfZJh]YngwupŽ|x™{y wx¦vw­pu¯jo¯ah¬^f®_g°em¶pxÀ}…ؙ͉ؗ Ö¡¨Öª±Û´¹ßº¿ßÀÁÝÃÃÛÇÆØÆÃÔÅÁÐÁ»É¼³Ä»°Áµ¨¼¦˜¯–‹œˆ…Œqqqtpopfewhe†nj„_Y•d_›ZT¹f`Ùsnðzvÿ{wÿwsÿhfüZWþRNõHBæ=6çD=Ø;4ÛG=ê\RÅ;0Ä<0½7+¾6(Ç>.ÑD3ÔB3ÔA1×A3Ò86Ø>>ÝCCÜB@Ö=7Õ81Ø7/Þ7/å:3æ93å:3â;3Û>5ÕA5ÑE8ÌG6®-¼;%ÍJ8ÑL=Æ=5»0+À00Ê9>×AJáKTëU`ðZeð]eìYaßLRÔ>@Ï4/Ø7/à;9ê@@òCHõDJñBIî?Fâ5;ß26ã36ï8<õ79ø14û/2ü14ï20ð95ð74ì0.è,*ç0,æ3.à3,ä=5à=4à=4à<3ã:5æ95ê65ì65ì57ì57í57î68î66ë54ä2.Þ1+Þ7.Ý9-Ý:+ß7*á4&æ1&í1(ñ1,ð42î53ñ42ò21ó1/ñ1.ì3.ç6.â;3Ò4+Ò:5Æ20çUXÿpxùcnòZiçI`óEfÿ8bÿ/]ÿ5bÿBhÜLe±PYj5/^G7XK:UN;[P>VI8M@0JC0@F,AO.K[6Xj@bxGfJhˆIf‹FeŠDc‹BcEeŽHgLh‘Oi‘Rk’Sn’RlPhNd‹JaŠH_ˆF_‡H_‡H_…H_‚H]~G]yF]wH`wKcxOczN]uC[vAZu@JC3MF6QH9TK.ÑE6Ë>-Á2"Ê7'ÛE7ÞE?Ó97Ì3.Í50Ô;5×=5Ý<4á=4ä;4ä92Þ5.×4+Ï5)Ê8+Å<,Â?-ÔS>ÈG2½<)¾:-Ã=2Ä;5Â74Â43ÜKNÞMRáPUåTYèY]åVXÜMOÓD@É5+Ñ7+Ø7/Ý52â24å26æ18æ.6ì4>ì3;ó5?û9Bý4>ú+5ÿ(3ÿ/9ø-3ù57ù59ð./ë*+é0.è51â5/ã<4à=4à=4á=4ä;6ç:6ë76î66ì46ë35ì25í34í55ê41ã1-Û0(Þ8,Ý:+Ý:+Þ8(à4&ã3$é3&ì4*î50î52ð42ð3/ò2/ï2,ì4,ç6.ä=4Í/&×>9Ì35ùbgÿoy÷[iðNcêC]ùEhÿ:eÿ0]ÿ6aöGhÉJ]“CFR,#VI8SL:OH6[O?UI9F?-HF1>B'@J(IU1Sd:_rEe}Ig„JeˆHcˆCa‰BbŠCcEeŽHfMhPiQlPkMfJcŠIaˆG`‡F`‡H`†I^G^F_}G`|Ia{Kd{Mf|Nf~N]xC]z@^{CDB6FD8JF;PG>RH>WI>]M>_O?`Q>aR?`SB_VGbYRgb_ojnso~wq“zt |y¨yw©pp¦gg£`a¢\_¤`b­fhµopÀyzÌ„‚Ö‹ß–’眙栞ݡ¡×££Ù¤¤Ú¦£Ø¥¢×¥¡Ô¤ Ó¥žÑ£Í¢šÉ¢™ÈŸ–Ù»Ž‚°ƒ|žrn}igld^`fZZkYUrWP}WNŒWO•RI¨ZPµXPÁZSØkdìyrù‚|ÿ‹†ùuqÿusí_]ßPLÙEAïZTÌ71Å2*Ä6*Ã7(À7'Ã7&Æ9(Ê;+Ð<.Õ?1Ò8.Ö<2×?4Ó;0Í5(Í3'Ø:/â@5à90á90Þ7.×7+Ï7)É:*Æ?,ÄA/Â=.Æ@4ËE:ÍG<ÌC;Å<4»2,¶+&Ç<7ÐEBÙOLàVSãYVáXRØOIÐC:Ì;*Ó:(Ü8,â5.è./ì*2ð(3ô'6ú->ú+?û*?ý)?ÿ(?ÿ&?ÿ$<ÿ$<ÿ$8ÿ'9ÿ+<þ,9ó+5í.5è45ç;9Ý84Ý:3Þ;4à;5ã:5æ95é73ë54ë35ì46ë54é54ç53â5/Ý5,Û5)Ü8,Û9*Ü9(Þ9&ß8&â7%ã6%æ4&ì5-í4/ð50ñ4.ñ5,í5+ê5*å7,à90Ø7/Õ:6Û?BÿmwÿbsûSjõIcÿKjö6[ÿ6_ÿcçNj¯IV^$"D, ?:'HE4PMC/?G/BH&EK%KS.S]8[kDavKd~NdƒJb†F`ˆBa‰@c‹BeFhJlPm‘Ql‘LiŽHgŒGf‹HfŠJe‰Ic…HaƒGdƒJdIbGc~GdJdHe~Ga}C[{<\=_‚B=?4?A6FC[K>]M=`O;`Q<^SA^VIc[Xhcinlyso†tp•vpžtp¢pm¢gfŸaaŸ]^¡\\¤ed°kjºtrÅ}{φ‚Ù‰à”Žæ˜“å›–Ùœ˜Õ™Öžš×ž˜Ö—Õœ–Ô›•Ñž–Ñœ”Íœ“Ê›’ǚ牻ˆ®‚xtk|mdif]^f[YiZSoWM{UJŠVKšVK°\RºYRÁXRÓfaàqjãvoí~wý‡…ÿ‡…÷usîgdãUSëZUÇ2,Â/%Å7)Ã7&À7%Á8&Ä8'È;*Ï;-Ó=/Õ9,Õ9,Ó:,Ò:,Ñ9+Ñ9+Ô8+Ø8,ß;1à90Ü8.Ö8,Ï9*È9(Á:&¾9&¾6*Á80Æ=5É@8ÊA9È?7Å<4Â91¿4-Ç>6ÑH@ØOGÚQI×NFÌC;Ã7*Ê7%Ó8$Ý7)å4,í//ô+3ù)7ý(:ÿ+@ÿ*Aÿ)Aÿ&Aÿ#@ÿ!<ÿ=ÿ:ÿ:ÿ 9ÿ%;ÿ);÷-9ð19ê7:å;;Ü94Ü:5Þ;4à;5ã:5æ95é73ë52ë35ì46ë54è64ä71ß6/Ü5,Ù5)Û9*Û9*Ü9(Ü9&Þ9&ß8%á8%ã6%ç5+ê3+ë4,ë5*ë5*ê6(ä7)á7*ß;1Õ4,Ó54óTYÿesÿ[põGbÿIhÿAdÿ;`ý3[ù;aòMmÍLb‰8?S*$A5'69(;<,B@1DA0@?-=B.>G,=CKP'\b_„?b‡B69.:<1??7DA:KB;OE/Ô>/Î6(Ë/"Ú:.Ú8-Ù7,Ö8,Ð:+É:)Â9&¾7$½5)À6,Â8.Ä:0Ç=3Ê@6ËA7ÌB8Ç:1Ê@6ÏE;ÐF<ÒH>ÑG=Ê@6Å7+Ì6%Ö6&ß7,ç4/ñ03ö-5û+9ÿ*<ü';ü'=û%=ù#;û!:ú7ü7þ6ÿ8ÿ6ÿ$8ý*;÷2<ñ6=ë8;ä::Ü94Ü:5Þ;4à;5å95ç85é73ë52í36î47í55ê65å61á6/Ü5,Ø4(Ú8)Ù9)Ú9'Û8%Ý8%Þ7$à7$á6%á5'â4)ã5*ã6(ã6(á7(Þ6)Û7+Ý<2Ð1+Ø88ÿkrÿ]nþPiñ<[ÿHlÿ7]ÿ>eù5[î>bæVqª?Qa#(L/);7+07'37&9<)@=*A<(@>)BB&?FXa4s~T€Œdw‡`hSa}La€G`ƒC`…?a‰@cŒ@hŽEjJkMl‘Nn“Mk‘HhHgŒGh‹Kh‹KfˆLd†Je„KdƒJc€FdGf‚Hf‚GeFb€Bc†DeŠEhH25*58-;<4A>7G@:KB;RE.Ñ>.Ë8(Ç/!Ò6)Ó5)Ò4(Ò6)Ñ9+Í<+È=*Ä;)Ä:-Ä:/Æ90Æ9/Ç:1È;1É<3Ë=3ÓD<ÓE;ÐA9Ë=3Ë<4ÏA7Ï@8Î;1Î5'Ù5)â5.ë31ò/5÷+6ù)7ü):ù&9÷&;÷&;ø'<û&<ý%:ÿ$:ÿ#:ÿ"7þ#7ú%7ù,;÷5>ò9?è8:à87Ü94Ü:5Þ;4à;5å95ç85é73ë54î47î47î66ê65æ72á6/Ü5,×5*Ø8*Ø8(Ø8(Ù8&Ú7&Ü7$Ý6$Ý6$Û5%Ü6(Ý7'Ü9(Ü9(Û:(Ù9)×:+×:1Ð3.ëHKÿoyÿVjøD_ø<_ÿAgÿ3\ÿ8bø>cèMlÅOe€0=J C1-11'.6'4=,=B.B@+B<$E>$HE$U\0p~MŸr—¨|ƒ˜mj„W_{J]~E_ƒCa†@bŠAfCkJl‘Lm’Om’Oo”Nl’IiŽIhHiŒLiŒLhŠNg‰Mf…LdƒJdGe‚HgƒHh„If‚Gd‚DgŠHiŽIl‘L-3'36+891<;6B=9G@:MD=QG=SI=SK>UNDZUQa^eigumklkŠjhb`XVˆPP†QQXYš`cªfj´orÁuxÉ|Ђ…Ö†‡Ù‡ˆØŠ‰Ù‹ŠÖ‹ŒÏ‹ŠÌŠ‰Í‰‡Ð‰…ш„ÑŠƒÑ‰‚ÐŒ„Ï‹„È…Á†º†°‡¥~w–m…„Yj€SZnVTc\RZaOZ_HeZDxUB’LD¸TRÐSWÛRYå^dèejãklæuqäunâoh÷~vÿ‚{ÿ‡~ôl`É?2Á8(À;(¿='¿='À<'Â;'Å:'Ç8(Í7)Ø:/Ù8.Ò8,Ï9+Ì:+É:*È9)É7(Ï9+Ñ7+Ò8,Ñ7+Ï7*Ì8*Ë<,Ë>-Ê<0É=0Ê<2É;/È:0Æ8,Å7-Å5*Ð@7Ð@5Í=4É9.Ë80Î;1Í:2Ì5,Ð/%Ù0)ä20ì25ô/8ù-9û+;ü,<ü-?û.?ü/@ü/@þ/Aÿ/?ÿ-?ÿ.@ÿ)9ü)8÷+7õ0:ñ6=í8=ã77Ü43Ü94Ü:5Þ;6â:7å95ç85ê65ì44ñ48ñ48ï56í76æ72á6/Ú6,×5*Ø8*Ö9(Ö9(Ø9&Ø9&Ù8&Ú7&Ù8&Õ8%Õ:&Ö;'Õ=(Ô=(Ô=*Ô=,Ô<.Ñ7/Ú;8ÿ^eÿaqÿPi÷<[ÿAiÿ4_ÿ4`û1YôKlÛYq•>NZ%-C),:2/-0)08+7@/:B+<<"A<UH(`[5{…S£lª¾‹¨¾Ž¥wo‹[aK^F`„DcˆBeDj“Go”Np•Po“So“So”Nl’IiŽIgŒGiŒLiŒLi‹OhŠNf…Je„IdƒHe„Ig…Ih†Hg…Ge…DiŽIi‘Kl”N+1%.4*470893>:7B=:HA;KD1Î8*È4&Ê8)Ë<,É:,È:,É;/É;-Ê:/È9+È5+Ç5(Ê6,Ï;/Ò>4Ó?3Ö?6Õ>3Î7.É,#Ò+%Ü-*ç02ð39ö1;ú0<ý0?ý0?ù0@÷1@÷1@ö0=÷/<÷-9ú,9ú*7ý/<ù/;õ0:ð3:í6;æ69ß55Ù42Ü94Ý:5ß:6â:7å95ç85ê65ì44ò59ò59ð67í76æ74ß6/Ú6-Ö6*Õ7+Ô8)Ô8)Ô9'Õ8'Õ8%×7'Ô9%Ð9$Î<%Ï=&Ï?'Î@(Î@*Ð?.Ò;0Ñ61ëHIÿfrÿOdÿHfû7[ÿAmý/]ÿ7aò4XãPj¼Ufm19E(*E697325406906=-3;#38CCja:…TŸ®w©Á‡µÎ—¯Ç“’®}v”be†Q`‚F`…BcˆBgFm–Jr˜Or—Rq•Up”To”Nl‘KhHf‹Fh‹KiŒLi‹Ni‹Og†Kf…Je„If…IhˆIi‰Hi‡Gf†CjJk“Mn–P(0#+1'/4-350764<85@=8C>8IEù4>ù1>ú0@ø/?ò.<ï/<í/9í07ï-5ï,2ò+2ñ*1õ2:õ3;ò5;ì59å57á55Þ65Ü75Ü86Ý97ß:6ã:7æ87é77ê67ì46ô5:ô5:ñ7:î87æ74à70Ú6-Ô6*Ó7*Ñ8*Ð8*Ð9(Ð9(Ð9&Ñ8(Ð9&Ë9"È:"È>$Ç?%È@(È@*Ì=-Ï;1×96üU\ÿ^qÿGcÿ?aÿ:aÿ7gþ3bû8`íFdÅNa‰@IS12A64@:<:46?56<7179+4="9CSZ.‚‚P¢§q±ÅŠ¯ËŽ°Ì’¦Ã’®}{™egˆQ_E^ƒ@c‰@iDo•Js™Ps˜Sq•Uo“Sn“NkJgŒGeŠEgŠJh‹Ki‹Ni‹NfˆKd†Id†IeˆHgŠJh‹Ii‰Hf‰Ej’Ll–No™Q&.!(0%-2+13.331764:95<;6GD=DD*¾;'¼7$À4#ÑB2ãOAäN@ØB4Ë7)Ë7)Ð>/Ê;+É:*Ç8(Æ7'È6'Ê6(Î8*Ð8+Ó;.Õ;/Õ9-Ò6*Õ7,Ú<1Ý<2Ü71è88ñ8=÷:Aû9Bú4Aõ/<ò,;ï,:í/;ê19ê38ë48í57ñ56ô36ó57ð37ï6;í9<é69â45Ý33ß76à;9Ý86Þ97á96ã:7æ87é77ê67ì46ô5:ô5:ñ7:ì89æ95ß82Ø7/Ó7+Ð8+Í:*Í9+Ì;*Í:*Í:(Í:*Ì;(Å9"Â:"Ã=$Â>%Ã?(Æ?+Ê<.Ï81ß<89?48E26C41=:)>E&FU*bs?›a­½±ËŒ«É‹¦Ã‹º„ެz{™ef‡PZ|@^?a‡>hŽCo•Jr˜Or—Rp”Tn’Rn“NjIf‹Fd‰Df‰Ih‹Ki‹Ni‹NfˆKe‡Jd‡GeˆFgŠHh‹Gh‹GeŠDk“Lm—OpšR(0!'/"(-&).(.0-3317839:4==5?@8DE@JLKORYVXeZ\s]^}YX‚[Y‹^]–ee£nn¶wxÈØ„…⌌ðŠŠì†‡ä‚‚Ü€€Ö‚€Óƒ‚΀ƒÈ„ǃƒË„„ΆƒÐˆƒÓ‹„ÒŒ„ÏŠ€ÅŠ€¼‰€¯‡}Ÿ€xwozkegf]Xm[Qm[Mi\Lf^Kd_IeaHhaGo_FoP;…UA¥]O¿aYÑYXÝQTîS[ø\`ùheæYPÔD<Î70Ñ7/×:1Ö=/Ô;+Ï9(Í:&Ï9(Ñ:)Ô8)Ø8*Ü5,Ü5,Ð/%Í3)Ì8,Ê>/Å@/Á@-¾=*¼9'Â9)¾0"éWJßK?Ã/#Ñ=1Î2Ü<0Ù7,Ú8-â>4ìC<õBEò9?ð2<ö4?ö2@ñ-;í-:í2=ì7>æ5;ä68å78ë99ð:9ñ78ï77ò;=î<<ê::æ87á85ß74Ü75Ü75Þ97á98ã99æ::é9;ì9<í9<ï8<ô7;ó6:ð8:í9:ç;9à;5×90Ï7,Ê8+È9)Ç9+Æ:)Ç:)Ç:(È;*Ç<)Á9#Ä='¾:#¶4¼9%ÉD3Ï?6Ê1,ÿ^eÿVgÿIbÿ<\ø1X÷0Yû6cõBiçYo¬FQo33N3,B?6>C<@78@-1L/3K2.A9&DJ(Zn=~š_ž¸w¨Å‚¬ÊŒŸ¾‚˜¶€”²~‚ nf„RXvBY{?]€>c‡AiDn”Im•Ll”Nk’Ol‘NiŽIfŠDc†Bc†Bf‰Ih‹KfŠLdˆJg‹MhŒNg‹Kf‹HeŠEf‹EjIk“Jq›QržSt U*0")/#).').(-/,130561782;<4>?7AD=HJGOPTSUaXYkZ\u\Z^]‰db”kj¤utº~·‡ß‹Œéð‰‰ë…„ ؀~Ҁς‚Ì…†É†‡È‡ˆË‰ˆÎ‹ˆÏŒ†Î†ÌŽ…ÈŠ€¼‰±†|¡‚x‘{s€tknlb`e]Re`Me^Kf^Kh]Ki\Ij^Hk_Gn^Ew_G[C’YF­ZLÇVPÞRSõQXÿX_ðUSãLEÙ>9Õ60Ù6/Ü90Û9,Ö9(Ó8&Ñ8&Ñ8(Ô8)×7)Ü6*ß4,Ý5,Î0'É5)È9+Æ=-ÄA/Á@-¿<*¾9(Ä8)Ë<.äREÜH<È4(Ì:-È:,Â4&Ê=,Ë<+Ê;*Ê;*Ë:)Ì9)Î8)Ï6(Ó7*Ö8,Ù7,×3)Õ1'Ø1(Þ7.ç<5øDGñ8>í/9ï/:ð0=î.;ë1<ë6?ä5:Ü36Ø22ß:8îEBøIFøDCó?>é:7ç98å97â96á85à85á98á98à87â88å99ç9:é9;ì9<í9<î7;ó6:ò59î68ê88ä;8Ü:5Ó9/Ë7+Æ8*Ã:*Â:*À;*À;*Á<)Á<+Á<)½9$Á?)»:%³5¹:'Á;/Ê:2Ø<=ÿ^gÿPdÿA[ù8Wö6[õ;`ô>dãIe«?Lƒ?>_:2G;/:>08>2F<:R>=N0.S8/VK5ciEx[°pÂ}¡Æš¹}š¹€š¶ƒ©xrŽ^YuETp=\{B_@b†@iCm“Hl”Kk“LiMiMgŒGe‰Cc†Bc†DgŠJiŒLhŒNg‹MiOiMiŽKgŒGgŒFfŽEl’Im•LpœQoRt U-1"-1#,/&,.)//-11/34/45-9;0<>1@B7EHAKMLQRWUUaVWi\Yt^]fdŒpn zx·…ƒÎ‹ßêŽïŽŒíŠ‰ç‡„ßÓ|Ë}ȀƅLjˆÆŠŠÊŒŠÉŒŠÉŒˆÅŒ„¿‹‚·‰€­†|¡€v{p€ujpndbi_Vc]M_aL_aKc^Jg\Jl[In\Ho]Gq]EwaIxX?‡S=£VDÇXOãUSøOTþMSâ><Þ<7Ý84Þ71á6/á6.Ý7+Ú7(Ô7&Ó8$Ó8&Õ8'Ø6)Ý5*à3,Ý5,Ë3(Ä6(Â9)Á<+Â?-Â?-Á<+À8(Ã5'ÜJ=ÚF:ÕA5Îå84â62à72à72à72á85â96ä;8ä;8á77ä88æ8:è8;ë8<ë8<ë8<ì8;ï58î47ì57ç77â:7Ù:4Ï8/Ç7,Â8+¿:+½;+»<+»<+»<)»<+»<)¸9&½@*³9$±6$¶;+µ0'Ã40ìPTÿ[iÿJ`õ:Uð7Vñ@]ïHfçHdÍNa‚89e?6R@2DA09=,57)>6+K9/E-#R=,g]Bˆ_’«t—»{–Áz–¿{”³xœ¸…š´…€šm\uKHb5Nh8[xB_}?cƒ@hŒDl’Gj’Ih’JgLfKd‰Dd‡Cc†DeˆFh‹KkŽNkOjŽNiOiOiMhJgHh’Hl”Ko™Ms¡Vs£Wv¤Y24&04&01)01+12-23.34.46+9;-;>-?A3DF9IJDMONRQWSS]XVd\Zoda~nl”zw¬„‚ÃŒ‰Ö‘㔑ê“뎋≅قÌ|Ã|¿€~½„‚Á†…Á‰ˆÂŠÃ‹ˆ¿‰…¸‡®…}¤…{€vŽyn~rgmmaak^Vi[Pc\J]`K]aJc^Jh[JmZKqZJtZIv[FsWAxR;ŠQ=ªYFÍ[PãTPðFIñ>AÛ2/Ü5/á51ã60ã5.á5+à6)Û8)Ö7$Ó8$Ñ8&Ô9'Ø6)Ü6*à3,Ú6-È6)½8'¼7&½:(¿>+Â?-Ã;+Ä8)Æ4'éUIÓ<1Ì8,ÑB4¾5%À=+À=+À8(Ä8'Å9(Ç:)È9)Ë7)Ì6(Í3'Ò6*Ô3)Õ2)Û4,ã:3é>7ì?9ì=:è45ì59ï6;î5;ê2:æ39ä7=â<@óUVübbÿmjÿidóVQäA<ß63Ý4/ß61Þ71Þ71ß82á85â96å97æ:8å78æ89è8;é9<ë8<ë8<ë8<ì7<î5:î68ê67å97ß<7Ö<4Ì9/Å9,¾9*º;*¶;)µ<)µ<+´=)³;*³<(³:'·@,­8&­8'³;-«+"Ã54ý`gÿTdúG\ð-=@-@C.DG4IK>MNFQPNRRRVUSYX]a_lkius›€}²ˆ†ÇŒŠÓ•’ᔑâÜ‹‡Ó„Ä}º|µ|³~·„º‡„¹‰…·Š„²†¨z›€xs‡znzrfjm_^j[Ti[PjZKfZJb_Lb_Le^Li\Kn[Lr[Kw\K{ZG~UA†R=›RA¶VFÎRHÚG@â88å33Ý1-ß3/â5/ã5.á3,ß3)Ý5(Ü9(Ó8$Ð9$Ï:&Ñ:'Ô8)Ù7*Ý5,Ø7-Ä;+¹:)µ6%·8'½;+Â=.Ç;.Ç7,Ð90õ\TÖ=5É5+ÏA5¸3$·:(¼?+¿:)Ã:*Æ:+È:,Ê;-Ì:-Ï8-Ñ7-Ð3*Ò1)Ö1+Þ71å<7ê>:è;7æ74é75ï;<ðë8>è7=ê7;î7;î79ê7:ä::ß=:Ö=7Ë;2Ã;/º8*µ:*³;*¯<)¯<*¬<(¬;)¬;)ª;(¬=*¦8'§9*ª8-¬/)Ë@CÿhrôM^óH[íDYåH[ÙO^ÉT]·TWœXUdM?OL9LG4JE1FD-?B'=D#>H#KV.\g.==1==3==5;<4;=2;=/?B/@D-CG.FJ3KL:NOAQQIRRHYWJZZN_^\gerqn‰{y¡ƒ€·‡…Čьӊϊ…ǃº~y¯zw¦yv¥{v¬|y®€|®ƒ}©ƒ}£x—|t‹zrvksrffm_\j\Sk[NlZLl[Kk[Ki]Mg^Mi]Mj]Mn]Ms^Mz]MZI“`O›VG§N@¸J=Å@7Ï6.Ø1+Þ1+á51á6/â5.â4-à2)Þ4'Ü6&Ú;(Ñ9$Í;$Ì;&Î;'Ñ:)Õ9*Ù7,Ó9-Á>,´;(°5#²5#»9)Ä<.É;/Ë7-Ù?7ø[TãIAÎ:0Ì@3¸6&¬3 µ<)¼9'¿7'À7'Ã7(Å7)É7*Î7,Ñ7-Ù<3Û:2Þ93å<7ê>:ê=9ç85ã41è96ë<9ì::è8:ì>@øPPÿbcÿppùheâTPÊ=6À1+É40Ö;7ß=:à;7â;5á:2â94á83ã73ä73å55æ66é69é69ê7;ë8<ë8>ê7=è7=é6:ï8<ì89è8:ã;:Ý>:Ó>7É<2À8ÛTXûepîK\ïI]éJ\ÛM[ÉQZ´VV ZRŠ`RPI7HM9NI5H@+;567>O%Lf6lŠTw”\„›e‰šd›f£k”­t˜°|ƒ•mn}\Q`Cg{HiƒFl‹Gm‘Gj“Gf’GbGcŽGhJlMo’Pn“PlMiŽKjJj’Ls›TsUsSržQržOs¢Rw¦Uz«Zv¦Zu¥[s£YRK;RK;RJ=RJ=RJ=RJ=RJ=RK;UNXQ?YR@[TD\UE\UEb[HaZHaYLbYRe][kaiqftuj{zn„|pˆs‹s‰|p„uj{mbre]jc`k`_g_\c_Z^^ZY^YUaZRbZOe[Og[Ki\Kk\Ik\Gm]Fm]Fj^HicMqfTqZJuOB‹WJœ\P£YL¬ZL¥N=¦E4§<,±7(Â8-Ñ80Ü41Ý1-ß6/Þ7.Þ7.Þ7.Þ7.Û7+Ø6)×7)Õ8)Ô8)Ò9)Ò9)Ò9+Ò9+Ô8+Í;,½;+¶>-®9(©1 «2!·9*ÀÔH9Â=,·2#ÝPFØJ@ÔF<ÔD;ÚG?ÞG@àC>à<:à74æ87ì::ì::ç77â64à93Ü=7ÙF>ÏB9Ä:/¼4(·1&¹5)¿;/Ã?3Ã:0É<3Ò?7Ú?:â=;ç;9ì89í9:ç7:å8:å8:å99å97å97å95å95à40á51ä65å76æ89ç9:ç9:ç9;ë;>æ9;ß99Ü=:ÖA=ÍB;ÁA6·?1©:)£<+ =*›<(™:&–:%—8&‘8&A0‹<-‡/#‘/&¼LJämoçloÍVZ½LNµNOªQM¢UO›XO—]R•aTŠjSWZ/:M7FTa)~ŽP›°oŸ¼yœ½x’µs~ah€L\mCYdBT]BHP9?D0:=,@C2<@1:>0]sBgƒHpKo“Kl’Gj’Ii“KgJlPm‘So“Sl“Pm’Mk“Jm–Jm˜IqœLqžMrŸNr¡Pt£Rv§UyªYzª^y¦cm™ZbŽOWN?WN?WN?WN?WN?WN?WN?WN?XO@YPAYPA[RC\SD]TE^UF_VGd[JcZIcYMcYOf[Uj_]nbdpdhreltgpvirvirsfmm`gg[_bXY^[VZZRYVOWTKXTIXTH\VH^WGcZKcZIf[Ig\Hi]Gj^Fk_Gh`IcbMngTv\MSFšVM«VO°RJ·QE¯H9¬C0¬=,±9)¾8,Ë80Õ62Ù40Ý6.Ü8.Ü8.Ü8.Û7-Ú8-Ù7,×7+×7+Õ7+Õ7+Õ7+Ô8+Ô8+Ô8+Î:,¾<.¶>.®9(¦1 §2 ²:)¹>.¾<.Æ:-Ç4*Ë4)Ò;0ÜE:áOBßQCÝOCÛF?Ø@;Ó<5Ò;4Ö=7Ú=8Ü86Ý33ç77ë78î79ë78ç77å97â=9ÛB:ÊA7¿?4¸:,±6'¯5&²8)¸=-¿@1ÅA4Í@6×@7ß=8ã:7é77ï56ñ7:é6:ç6<ç7:æ89æ87å95å95ã:5â92ã:3ã:5ä;6ä;8ä;8å99å99ä:;ã;;ß<=Ù?=ÐA;Ä?6·=2¬;-¥;+ =*œ=+—<)–;(’:&“8%Œ:%€9'€8)‰5*<5¿QP×eeÑ^a·MM¬NL¤TMYP˜\Q—^S—^S˜_VŒfQ`_/Sg*^r3zO™¯n¥¾|™²pˆ bj‚HauBTe;JX7FP7?H59?158-:^tEgƒHqMp”Ln’Hk”Hk“Lh‘Km‘Qn’Tm”Sm”Qk“Lk”Hl—Hm˜HpJpJp Ls¢Qu¦Tx©Xx©Xx¨^m—Xb‹QY‚H]TE]TE]TE]TE]TE]TE]TE]TE[RC\SD]TE^UF_VG`WHaXIaXGe]Je]Hd[Jd[Le[Qf[Uh]Yh][i]]j^^k__k__i^\f[YbWS_VQZVMWTKUQHRNCQMBSOCWQCXRB^WG^WEaYFc[Fg\Hi^Hk`JhbLbaMngUy_PˆXN¢[U±VQ²IE¸E@¹@7¸>1·;/¸8+¼8+Ã9,É;/Ñ:/Ù8.Û7-Û7-Û9.Ú8-Ù7,Ù7,×7+×7+Õ7+Õ7+Ô8+Ô8+Ô8+Ò9+Í;,À>0¶>.­:(£2 £3ª:&³>,¹>.Ä?0Ä8+Å2(È4*Ð<0ØF9ÜM?âNDÙ:6Ø43Ô20Ö42Û97á=<æ<<é;<í9<î5:ë27é26è58å99á<:Ù@:¾8-µ:+±6'®4%­5%°8(µ<+»=.ÈD5ÏC6ÖB8Ü=7â94è64í55ï79ê69é69é69ç77ç77æ95å95å:3ã:3ä;4ä;6ã<6ã;8â:9á99Þ88Ý9:Ü<<Ú@>ÓB=È?9¹:1­7+¥7(¡;,<+™<+”;)“:(9&7%Š9&z6#y6%ˆ9, F=¹SOÀWT¸PO«IF¢MHœSL™YP—^S—aW—aW˜_V‹ePsrFzV“¦n¤¹€«À‡ž³{|[[oaXIaXIaXIaXIaXIaXIaXIaXI_VG`WH`WHaXIbYJcZKd[Ld[Je]Hf^Gf^Ig_Lg^Of\Pf\Rf\Sh]Wh]Wh]Wh^Ug]Te[QdZPc[N]YMZVJVRFRNBPL@PM>TN@UO?WQAYTA[VC]XDaZGd]Jf_LfaMdcQleUv\OŠ[Q©b\¸ZX¶FD¹<:Ã<8Æ;6Ä:0Â8-½8)¼:*¾?.Ç?/Ó9-Ù7,Ú8-Ù9-Ú8-Ø8,Ø8,Õ7+Õ7+Ô8+Ô8+Ô8+Ô8+Ô8+Ò9+Í;,Á?1¶>.¬9'¢3 3¢8"¬=)µ@.¼?-¿:+Ã7*Å5*Ë7+Î:.Îî7<ì38é06æ25å58á77Ú65Î61·5(¯7'®6&¬7&¬7&®9(²:)µ:*ÃA1ÊB4ÔA7Ü?8â;5æ95ë76î87í68ë78ë78ê86ê86è94ç:4æ;4â92á:2ß:4à;7Þ:8Ü:8Û97Ù99Ö<:Õ@<ÒC=ÊA;»;2¯6+¤6'ž7(œ;*˜;)”;)’;(:&8$Œ7#‡9%€=*v5#5'™E:ªPH¬MG©LG¦QLPJ˜UL”ZO”^R•aV•aV—aWgT‰…_™©x­½Ž¦¸ˆ¡ts†YN`8/A->3B%:F.=F3;A3:=2:=4<=599-?@2<>39<1<@29B/?L2PbNK:NK:NK:PMTQ@VS@XWC[ZF]\H^]Kb`Qf^QmWJ†[R¬ic¾c`ÁMMÈBCÐ;=Ô89Ó84Ì70Á9+º=)µC+¼B+Î;+×7)Ø8*×:+Ù9+Ö9*Ö9*Ô8)Ô8)Ô8)Ô8)Ò9)Ò9)Ò9)Ò9)Í;,Á?1¶>0«:(¡6"š4›7 £=&¯B-³;*º;,Â:,Ç9-Ë8.Î:0Ð<0Ù:4é9<ì4<æ39ã28â38á48â38â25é6<é49ç4:ç7:ã9<Û76Ð21À0(´6(­:(­:(«:(«:(«:(¬9&¯7&¸:+Á;/Î>3Ø?7à=8ä;8è96ì87î66î66î66í74ê84è:3ç:3ä<3á:2ß;2ß<5Ü=7Û=:Ù><×=;Ô>=Ï@<ËB<ÅB:¹=5­7-£5(ž7(š:*–;)“<)‘;*:(Š9&‰8%ˆ7$ƒ8%ƒ@-u4"{3%“G:¤QI¡NFžNG¡WN˜UL’XLZN\N]R”`U—aWhW‰f˜¥z©€Žj]kHDS42@&$2-:&0;*5=.9?3?1;=28;0;?18A.>K1PbÜ87Ô70Ç;.¼?+±C*µA(Ê;*Ô7(Õ8)Õ9*Ö9*Õ9*Õ9*Ô8)Ô8)Ò9)Ò9)Ò9)Ò9)Ò9)Ò9)Í;,Á?1µ=/«<)¢9$™6•5›;"§A*²B.¹@/¿;,Ã7*Å2(Ë4+Ò;0ß=8ê5:î3<ë6=é8>ç:>ä;>ã:=â9<ß58á7:â9>á=>Û=>Ñ96Ã2/¶0'¯9+«>*«>*©>*ª=)©<(©:'«8%¯6%¹7)Å;0Ð=3Ù<5ß<7ä;8è;7î87ï75ï75î85ë:4é;4ç<4ä=4â>5à?7ÞA:ÚA;ÙA>ÕA?Ñ@=ÍB?Ã?:»@8³=3ª8-¡5(›5'˜8(•<*‘<(<)Š<(ˆ:&†9'„7%ƒ6$6%}:)t3!~9*—OA£YNœRG•OE˜VJ•YN[MŽZMŒ[MŽ\Q“_T™`W‘gW~xXyƒ^r|ZU`B;E,/;%0;*0<.3=24<16<2?1:<17:/:>07@-=J0Oa;bxIk‡Lu”Qu™Qt˜NqšNršSpšRršQsœPr›Op™Kn™Jp›LsžOv¡Ry¥X{§Zz¨]x¦]qŸWg”O]ŠEX‚B`‡NY€ISzCg^Og^Og^Og^Og^Og^Og^Og^Og^Og^Og^Oh_Ph_Ph_Ph_Pi`OjaPjbOjbOjbOi`Oi`OiaNiaNiaNh`Kh`Kh`Ih`IhaGhaGhaGf_Le^Kb[I\WDWR?PM:LI8IH6IH6GH6GJ9GK:HL;IMì;Aê@CæAEàBCÜ@AÙ??Í12Ð66Ó:<Ñ=;É;9¾71µ4.­4)ª<-¥>+¥>+¥@,¥>+¤>(¦;'©:'ª7%²7'¼8+Å8.Ì70Ô94Ü=9æ>;é:7ì95ì95ë:4é;4è;4å=4â>4àB7ÝC9ÚC<ÕB;ÏA=Ê?<Ç=;¿>9±<3©:/¢8+œ6(˜7'”8)‘:):(‹=)‰<*‡<)ƒ:'‚9(€7&6%}6$x3#x5%…B2˜UEWK”PCPD•ZL“YMZN\Q\Q’[T•\U˜[VŽbUkbEV`=JS4=G,6?*2=,4>35?66=68?8=B;CF=EG/;9*78*=>0:<17:/:>06?,=J0N`:awHk‡Lu”Qu™Qt˜Nr›OršSpšPq›OrNqœMp›LošKrNu¡Ty¥X«`~©az¥]qœUf‘L_‰G]‡E^ˆIb‰PY€ISzCh_Ph_Ph_Ph_Ph_Ph_Ph_Ph_Pg^Oh_Ph_Ph_Ph_Ph_Pi`Qi`QmdUlcTjaRi`Qh_Pg^Og^Mh`MiaNiaLiaLiaLh`Ih`IhaGh`IgaKf_Le^Kb[H\WDUR?PMSQDSPAXLÂYSÙROàDEà::Ü75Õ;3Ê>/º=)µ8"É:)Ï8'Ð9(Ò;*Ò;*Ò;*Ò;*Ò;*Ñ:)Ñ:)Ñ:)Ñ:)Ñ:)Ñ:)Ñ:)Í;,Á;0¶:.­<,§>+™9#3“7Ÿ?'£9#°;)À>0Æ<1Ì8.Ð7/Ù<5ã?=ì=Bî?DéCEâDCØ@?Ê;7À50»1.¹/,¼51¾:6»<6³:2ª8.¤8,¡:+¡=-Ÿ>+ ?,¡@-¡@-¡A+£>*¦=*©;*­:(²7(¹5)¿5+É90Ô?9àC>ä=7è;5è;5ç<4å<5ä=4á>5Þ@5ÜD9ØD:ÒC;ÊA9Ä?:¼;6¸85°93¢7-™8(•5'“6'‘:)<*‹:)…8&ˆ=*…<+ƒ<*€<)~:'|8%{6&{6&y1#€8*ŒG8–SC’PB‹L=RE™_S‘WL’YN”[R–]T–]V—\V–YTŒ^QaX;EM(6@8A&>G26BE*;:&78(=>09;069.:>06?,F7GK=IK=AE4KJ6\Q;aE/ƒJ9Àj]Üg`ãUSäFEåA@àA=Õ>5É=0Æ=-Æ4%Ë5&Ì6'Í7(Í7(Î8)Ñ;,Ó=.Ò<-Ò<-Ò<-Ò<-Ñ;,Ñ;,Ñ;,Î<-»2(¶7.±;/¨:)š7"”5•7œ9"®A-³;+º6)Á4*Í6/×<7âC?êHEèDEèEHÝCCÉ:6»61´80®8.©4+«9/©9.¤8. 8-›9,–:+“<+’<+–=+˜=*™>+š?,›@-A, A-£@-¢;*¥:(«7(°6)¶6+¾8-Ä;3Ì<4Ú=6à=6â?8âA7âA9ÞB6Ú@6×@5ØH=ÒE;ÇA8»;2²5/ª3-¦1*Ÿ2+™9-’;*‘9+:*‹:)ˆ;)‡;+…<+€9'}8(|9(|9(|9({8'y6&x3$w- ‹A4—OC“MAŽL@‘QE“UJŽRG˜\R˜\R‘UMTL—ZU•XS”WT“gZ]T5IQ*AK(BK,>H/7@+2=-4?14<1HPCZ^PW[JMO:DF.AA'==%:;)>?1;=2:=2;?14=*;H.PbF7>F7=E6@F8>E5>F1HL5MI0U?'Q:¼sbËcXà_ZëUTçGGâ@>àA=Ø?9Î:0Í9+Î=,Ï=.Ï>-Ï;-Î;+Í9+Í:*Î:,Ð:+Ð:,Ð:+Ð:,Ð:+Ð:,Í;.É?5ÅB:¼B7®=/Ÿ6#–1–1›2¨5#´6(Ã;/ÑA8ÞE?æIDéJFêKHÞCAÛEDÐB>¼<3¯9/©=0¥?1Ÿ=0Ÿ?1œ>2—>0”>/=/Š>.‡@.ˆ?,Ž=*‘;*’<+“=,”?+•>+—>,™>,Ÿ@.¡=-¤:,¨8,¬8+±8-¶:0¼9/Ê<2Ð<2Ó?5ÕA7×C9ÖC9ÔD9ÑE8ÊB6ÃA4¹=3°:0©6/¤5.Ÿ4,™7,’:.Œ=,Š;,ˆ;+†:*„;*ƒ<*<,~;*|;){9)y:)x9(w8'u6'w4$€4'D7˜NC‘K?ŒJ>QD’TIRG“SJ˜XO˜UO—VPœ]X”WRŽSOŠcT]W5Xc9_jBZfBIT66C)4@*0:<19<1<@25>+;H.PbMKD63Å?3ÅA4ÃA3ÁA4¶;,²:,ª8-£7+ž6+›6,˜7.”:/;/ˆ<,‡;-„;,‚:+€;+€;+<,};+z;*z;,w9*v8)u7(t6)v4&ˆ;1”F<–NBŽJ=ˆHEI0?C(=@#:<$89';<.8:/9<1=A36?,MK4Ñ>4Ò>4Ò>4Ó?5Ó?5Ó?5Ó>7Ó?;ÑB>ËD>ÆF=ÂF<ÃI>ÇM@ÎPDÙSHÝPGâMGäIEäGBâC?àA=ÛB=ÕFBÉD?º?7«=0Ÿ>.šC0•G3”I6F4ŒE3ˆC3…B1€A0}@.zA.|?-‚:,†8,…9+†:,†:,‡;-‡;+ˆ;+‰:+‹:)Ž8)8*•9,™;/=/¢<0ª:/­8.¯9/°:.°:.°:,¯9+®8*¨7)¥7(ž6)›6*•7+’8-‘9/Ž<0ˆ<.…<-ƒ;,9*:*~9*}:*};+|:,z;,y;,w9*s8*q6(r7)u5)ŒD8’H=‘K?ŠH:‡I<‹OD“TK—TL–QL›TP˜QO”SO–\X_Xh^—~j””p…’fu‚WYh?CR+?O*P`B)=A(;='78(:;-79.9<1=A37@-NKB1=I1?G/LG1S>+g=-•ZL­_Sœ>4ž3+¶?9ØXUóigödeëRUæJNèNPÙIAÓF<Í@6Ë>4Î@6ÒD:ÕG=×G>ÚJAÚJAÝJBÝJBÞKCÞKCàKDàKEëSRèTTãSRÜROØSLØSLÛULàUNàLHáIFãEBâC@äB@âC@äEBàFDÙJFÊE@¹>7¬=2¡?2˜B1’E3G4ŒE3ˆC3‡B3ƒ@0?1~?0z?/|>/€:.ƒ9.ƒ9.ƒ9.ƒ;-ƒ;-ƒ;-ƒ;-9*‚9*…9+‡:*‰:+;-<.“;/›;/ž9-Ÿ9- :,¡9,¢8+¢8*¢8*Ÿ8)œ8)˜8(”8)9*Œ:,‰:-‡;-„:-‚:,9+€8*}8)}7+|8+{9+z8,y9-x:-v8+q5*o5)q7+t9+ŒH;I<‰I=„I;…K?ŒRF“WM˜XO˜QMœUQ˜RP“VQ’`YˆbWƒg[†zdnrQZi@JY0AR(IZ0Wi?dvNj|VXiEL[:?L.:D)C-B47@-;H.L^8_uFi…Jt“Pt˜Pt˜Nr›Os›TpœQnMmžLp¡Pw¨Y|ªaz¨`rXi“QZƒA\„EaˆIeŒMgŽMgŽKhJfŠLc†PY{IRtBi`Qi`Qi`Qi`Qi`Qi`Qi`Qi`QkbSkbSkbSkbSkbSkbSkbSkaUlbYlbYlbYlbVlbVlcRlcRldQldQldQlcRlcTlbVlbXlbXlbXocUnbRkbQlcRlcRkbQg`Pd]M^WGYSCSM?MJ;KH9GE6EB3?B/;H.?H-OC-a=-ƒE:«XR´NJž,+²:9¹=;ÓSRòpnþvvñehëX^ð^_ãUQÚPFÔG@ÐC:ÑD=ÔG>ÖGAÖG?ÙHCÚJBÜHDÝJCÞJFÞKDàKGàKGâHHáGIÜHHÙGGÖHD×HDØGBÛFBàBAäABæBAèBBçCBäB@ßA>ÛA?ÛJGÊC?¹<6®>3¢@3˜A0A0C3ŠA2ˆ@1‡?1…=1‚<0€<1=1=1;1;1ƒ:3;1;1€.™9)–9(“:*:+Š;,‡;+„;,‚:+‚:,9+7)~6({5){5){5)z6)x6*x8,w9,s8*p4)o5)r:-v<0‹M@‰K<„J<‚M=…QC‹VH’XM—WN“NI™TO—VR•\Ue\{^PfVF`^GEO->N)?O(J\2_rEk~QexKXj@M_7@Q-6E&7D*=F1=D4:>07;-8:,:;-68-8;0>B47@-9F,I[5[qBeFr‘Ns—Os—Mr›Os›TpœQmœLo Os¤Ux¨\z¨`s [i“Q`ŠHYB^†GeŒMgŽMfJeGgŒGhŒLa„NXzHQsAi`Qi`Qi`Qi`Qi`Qi`Qi`Qi`QkbSkbSkbSkbSkbSkbSkbSkbSlbXlbVlbVlcRlcRldOldOldMldMldMldOldQlcRlcTlbVlbVocUmaSkbSlcTmdUlcTi`Qf_Ob[K^WGXQARLÐB>Í@9ÒC?ÒC=ÔC@ÕD?×CAØD@ÙECÚDCÝADÝADÞDFÝGHßIHàJIãIIåGHçACêADìBEìBEçAAâ@>Û=:Õ=:ÚFFÉ=<¹83°;2¦@4˜?1‘>0@1ŠG]/AV-7H$1@!6B*=F5PK8MH5ID1DC.@F*DD([B,ˆTG¯\X«>A¬/3ÎINÆ?EÀ;>»;<ÄFGØZ[ãefÛY[ÌGHÑJGÐEBÍB?ÐB>ÔFBÔFBÐB>É>7ÏD=ÏD=ÒD@ÔEAÖEBÙECÚDEÝDFÞ?Cß@DÞBEßEEáGGàFFàBCá>?èBDé@Cè>Aç=>ä>>ãA?áC@ßECÖBBÅ98¶50°;4¦?6š>3=/?2ˆ)=C5ã?>â@=â@=ÞC?ÓB?Å>:¶93ª70Ÿ:0—=2Ž>3†>2ƒ?2?3=2;3„93†93ˆ81ˆ92…;0„<.„<.ƒ;-;/€:.€:.€:.~:-~:-~:-~:-};/};/};/};/}90}90~80~8.€7.€7.€7.~8,€8,~8,}9,|8-{9-z8,x8,x8,x8.x8.w7-v8-v6,t6+s5*q5+m1'r6,n4)m3(o6+m4)q8-I=…SH…SJ†RGˆRH‹PHQJ”QK•RL“TMTK‰[N‚cQo_HYU:MV7O_;j~YbxQYoHUjCRg@Mb;IY5CR17D&4>#2:#6;'<>0@B5@@6<>358-39-4:.7:/9=/;?.=B,%Q?)kP=XG„NBˆE=“D?±WV¸TT»QQÀPOÀNMÁMMÂLJÃKJÐTTÈHGÂ=>Ä=:ÐB@ÓEAÏB;Ç>4ÊD9ÉE9ËF=ÍG>ÔFBØDDÜAEÝAEáBFáCDáCDâDEâDCáFDáFDáFDàEAßD@àB?ßA>àA=àA=àA=ÞC?ÔE?ÈC<º>6¬:0 90”:/Š<0‚<0€A2~@3~>4<3ƒ:3†91ˆ81‰90‡;.…<-„;,„;,ƒ;-‚:,‚:,‚:,9-9-9-9-~:/~:/~:/~:/}90}90}90}90}90}90|90|90|90z:0z:0y9/y9/y9/w9.w9.w8/w8/t8.s7-r6,r6,p6+p6+k1&q7,m4)l3(o6+l3(p7,~H>„RI…SLˆQJ‹PJQL”PM•QN”SOŠOG…SH€[K{ePsiPhkLfqQgxT^tMXnGPf?La:K_:K\:GV7CP4>2;=04:03;05;16<0:A,>D*Q[9^mDkRpŒRp“Sq™RsSsžVxŸ^|¢exžak‘T`†I]ƒF]ƒF\‚E`†Ia‡Jc‰Le‹NdŠMbˆK`†I^„I]LRtBIk9i`Qi`Qi`QjaRjaRkbSkbSkbSjaRjaRjaRjaRjaRjaRjaRjaRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTnbTqdTo_Pm]Pm_RqeYog\ldYhbVfbWpl`{xi~{jyizubpiVe`JTT(MB.S@/U8(]7*l=3n70u91~;5‡@:’IB›PJ¥XP­ZR»^YºSN·GE¼B?ÈDBÑFCÓD@Ï@:ÐA;ÐC<ÒE>ÔG@ÖGCÚFFÛEFÞDFßCDßCDßCDßCDàDEßEEßECßECÞDBÞDBÜD?ÛC>ÜC=ÜC=ÜC=ÛC>ÖE@ÎE?ÃB<³>5¢:1”8-ˆ9,ƒ;-‚@2@1~>2=1ƒ:1†91‡81ˆ:0‡;.„;,„;,„;,‚:,‚:,€:.€:.9-9-~:/~:/~:/~:/~:/~:/}90}90}90}90|90{8/{8/{8/{;1{;1z:0y;0x:/x:/x:/x:/t8.t8.s7-s7-r6,q5+o5*o5*j1&o6+m4)k2'l6*i3'm7+}G=‡PI‡PI‹PJŽQL‘RM’SN”UP‘VPŒWO‡[P~^OtbNoiQorUlwYfwUQeBK_:EY6DU3EV6GV9GT8ER8?I0*7;*:<.<>0;=/9;.6<25=26<26<0:0=@-=C)MW5Zi@f|MlˆNn‘Qq™RuŸUtŸWz¡`w`n”Wc‰L\‚E\‚E\‚EZ€C_…Ha‡JbˆKdŠMc‰La‡J_…H]ƒH[}JPr@Gi7i`Qi`Qi`QjaRjaRkbSkbSkbSjaRjaRjaRjaRjaRjaRjaRjaRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTnbTrdWoaTm_Rk_SkaWlcZle[jf]jf]xtiˆ„x‘•’Œ~‰‚r}zg`cNOT>DG2FE1HC0F=,L<,VC4P9+R6*V4*Y5)\6+a9/e=1m=1ŠKBSJ®UO¶NK¼FDÆABÒDCØFFÔ@>ÕA?ÖB>ÖE@ÙECÚFDÛEDÝEDÞDDßCDßCDÞDDÞDDÝEDÝEBÞFCÛFBÚEAÙD>ØE>×D<×D<ÙD=ØE>ÔD<ÓF?ÉF>ºA8§;1˜8,Œ9+…<-ƒ@0@1~?0=/ƒ:1„:/‡9/ˆ:.„:-„;,„;,ƒ:+‚:,‚:,9-9-9-9-~:/~:/~:/~:/~:/~:/}90|90}90{8/{8/{8/{8/x8.{;1y;0y;0y;0x:/x:/x:/v:/s7-s7-s7-r6,q5+o5*o5*m4)j1&o6+l3(h2&k5)h2&l6*|F<ŠOGŒOJPKRMSN‘VPWPŒZQ‰]R…aUy_PiZGd_IdhO\fKN]@EU8AQ4=M0G2:A/9=,9=.9=.8<-7;-7=36=56;46<2:<1;=/bxIj†Ln‘Qs›Tw¡Wx¢Z{¢ar˜[e‹N\‚EZ€C\‚E\‚EZ€C_…H`†Ia‡JbˆKa‡J`†I^„G]ƒHY{HNp>Eg5haQhaQhaQibRibRjcSjcSjcSibRibRibRibRibRibRibRibRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTlcTrfXth\sg[mcYjaXle]snhzwp~w† ”¨¥œ«§œ¨¤™£‘™–‡z{kcfSOR?GJ7EH5BE2BE2EH5KL0A9,A7+@6*F4(S5*qB8ŒPHŸPK¯IG¿GIÌEIÓBEÖ@BÙ@BÚBAÛCBÚEAÚEAÜDAÜDAÞDDÞDFÞDFÞDFÞDDÝEDÝEDÚDCÚFB×FAÖF>ÔE=ÔE=ÓF=ÔE=ÕF>ÔA:ÓC;ÎE=ÁB9®>3ž9-‘;.Š.€=-;/„:-†:-‡;.„:-ƒ;-‚:,‚:,‚:,9+9-9-~:/~:/~:/~:/}:1}:1}:1}:1|91z:1|91y90y90x8/x8/v7.y:1y:1x90v:0v:0u9/u9/t:/r7/q6.q6.p5-o4,n3+n3+m4+j1(m7-j4*h2(j4*f2'j6+}D;NGNHQJTLUOŽWPŠYRƒ[Q{YMv\OkZJ]UBYXDY^HOYA?K3:H/7E.4B+5A+8D.=I3CL7EN9BK6?H5.5<,4:,5<45<56;56;49;0:-;@)GP1Ra:`vGi…Ko’RuVy£Yy£[xŸ`n‘W`ƒIZ}C[~D^G^G]€F`ƒIa„Jb…Kb…Ka„J`ƒI_‚H^IW|ILp@Bf6haQhaQhaQibRibRjcSjcSjcSibRibRibRibRibRibRibRibRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTlcTkaUndZpf\lcZkd\rmg„|‘Œ§£ µ±®ÄÁ¼ÉÆÁÉľÅÀºÀ¹±¹²¨¤œˆ‚rfcTPQ?FI8>E3;D1:F28E38E38C2:B34(P:/e?6€EA¡PO¿X[ÊQVÊCIÕFJ×EFÚFFÛEDÝEBÞDBÝD?ÞCAÞDDÞDFÞDFÞDFÜDCÜDCÜDCÚDCÙEA×FAÕF@ÓF=ÒE<ÐF<ÑG=ÔE=Ô?8Õ@9ÐC:ÆC9¶A7¥=0–=/Œ=.†>/‚?/>.€=-<-ƒ;-„:-…;.‚:,‚:,‚:,‚:,9+:+9-~8,~:/~:/~:/~:/}:1}:1}:1}:1z:1z:1y90y90x8/v7.v7.t8.w8/u9/u9/s9.t8.s9.r8-r8-q6.q6.p5-o4,n3+m4+l3*j4*h2(l6,i3)f2'h4)e1&i5*{B9ŽMG’MH‘PJTLVO‡XNYO|\Qs\Nk[L`WFVSBPSBJQ?@I64@,3<+2;*09(09(2;*5>-9B1G4:F2:C25@/3>-1<,3:33954954928919;.;>-;@*CL/O^7]sDi„Mp“SwŸYy£Yw¡Yq˜Yf‰OZ}CX{A\E]€F]€F^G`ƒI`ƒI`ƒI`ƒI`ƒI_‚H^G]€JV{HJn@Ae7haQhaQhaQibRibRjcSjcSjcSibRibRibRibRibRibRibRibRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTlbVj`VjaXkdZkg^upjˆ…€Ÿžš°°®ÃÂÀÓÒÐâáßçæäçãàãÞÚÞÖÓÙÎÈμ²¸¥——‡zym]_YIKL:@E1;D/>J6=H7=F5;C4;>5:;3983880==3C<2N71a84ˆHH¯]_Å`dÊWZÍQSÓNO×MKÛKJÞHGáFDãDAâBBßCDÞDFÞDFÝCEÝCEÜBDÜBBÛCBÚDCØD@ÕD?ÓF?ÒE<ÐF<ÐG=ÔE=Ù@:Ù@:ÑB:ÈC:¼C:¬@4™;/Œ9+‰=/ƒ>.>-€=,<,ƒ;,ƒ;,„<-‚:,‚:,‚:,9+9-9-~8.}9.~:/~:/}:1}:1}:1}:1}:1}:1z:1y:1x90x90w8/t8.s7-r8-t8.s9.r8-q8-r8-p7,p7,p7,o6-o6-n5,n5,m4+l3*k2)i3)g1'k7,h4)e1&h4)b0%f4)zA8MG’MH‘PJŽULˆXNYOxZOr\Nk^N^WGRPAKN=CJ:9B12:+08)17+17-06,/5+/5)08+2:+4<-9D4;F5=H7-.800621622717829;0:<.:?)?H+KY5[qChƒLq“Vwž[w¡YsœVgP^IUx@WzB[~F[~F[~F]€H_‚J_‚J_‚J_‚J^I^I]€H]€JUvIJk@@a6haQhaQhaQibRibRjcSjcSjcSibRibRibRibRibRibRibRibRkbSkbSkbSkbSkbSkbSkbSkbSlcTlcTlcTlcTlcTlcTlcTlbVpg^ng_lgatqj‡„¡ œ¼¼ºÎÐÏÏÏÏàààòòòúøùû÷ö÷óðñìéðâßèÐÆÝÁµÁ«¢‘}ub^\GKM7CH2AI2AI4@G5BD7AA7B=9C97?:69<5>?7B71J.+d66QR³giÆnmÀ\\ÇZWÐVS×QNÜLKâHHæCDåBCßCFÝDFÝDFÝCEÝCEÜBDÜBBÜBBÜDCÙCB×C?ÓD>ÒE>ÐF<ÐF<ÔE=ÜC=ÛA9ÒB:ÊD;¿E:°A6œ:-‹5&ŠD69A208+/7*6<247058157247025.06,08-19,6A3:E5=J9>K9-,6..400511606718:/:<.:?+WzB[~FY|DY|D\G_‚J_‚J^I^I^I]€H]€H]LStIHhA?]7icSicSicSicSicSicSicSicSicSicSicSicSicSicSicSjcSkbSkbSkbSlcTlcTmdUmdUmdUmdUmdUmdUmdUmdUmdUmdUldWibZgd]vsn“’ޝ¯­ÄÆÅÚÜÛêîïóôöö÷ùüüþÿÿÿÿÿýÿûúü÷ôýòì÷áÔòØÇàʵƶŸª ‡ˆ„ibbFEH-DH/CG0FE1GD5F<3C60F42H:9>=9>?:B:7I75cGF’jjÅ“’è­©Ò‹‡ÇtnÀ]XÆSPÕONßJLçFKéFKßEGßIKÚDFÔ;>Ø>@áGIàDGÖ:=Ú@@Ú@@ÙA@ÖB>ÔC>ÑB<ÐA;ÑA9ÞC>ÛA9Ó@9ÊA9¾B8°@5Ÿ:.8*Œ=0‡>/ƒ>.>-€=,<+=*<,:+9-9-~8,~8.|8-|8-|8-|90|90|90|90z:1z:1z:1z:1y=5w<4w;3u:2t91q8/p7.p7.o6-m7-m7-l8-m7-l8-m7-m7-i2+m6/p92o81k4-g2*g2*h3+e0(i7.d2)]-#`0&_/%b2(s>6ŒOJPKˆQJRJ}YMv_QfYITN>DE5>E5:C25@04&DR1WlCh‚Rs”]wž_r›Wk”R[~DXyDTu@Tu@WxCZ{F[|GZ{F^JbƒNbƒN^J\}H_€K`L^~MTsJFd@2I:3L95K<9?:7BA?MHE]RPyjg£Ž‹Î²®èÅ¿ÿ×Ñ쳪͂|Àc^ÊVVØRSßHMÚADÖDEÕEEØHHÜJKÛEFÕ<>Ö<>ÛACÙ??Ù??ÙA@×A@ÖB>ÓB=ÒA<Ó@9ÜA<Û@;Ó@9ËB:¿C;±A6 ;1’8-Œ=0‡>/ƒ>.>-€=,<+<,<,:+9-9-~8,}9.|8-|8-|8-|90|90|90|90z:1{;2{;2z;2w<4u<3u:2s:1r90n8.o6-m7-m7-l8-l8-l8-l8-j8-l8-l8-k6.n70o81n91l7/i4,g2*e3*c1(d4*_/%^.$b2(^.$`0&p>5JE‡RL‡XR~XOrVKdRDQJ:>?/:A16A05@03>04<14<15;17:379477577557246116//6./7,.9+1<.4A08E49H58G44E24B1.8/.5..3--2+23+46+8:-9=,7?(DQ3WlEh‚Ut•`wbp˜YgPY|DWxCTu@Tu@VwBYzEYzEYzE[|G_€K_€K\}H[|G^J^J^{MSnKF_A9R4icSicSicSicSicSicSicSicSicSicSicSicSicSicSicSicSkbSkbSkbSlcTlcTmdUmdUmdUmdUmdUmdUmdUmdUneVneVlfZed_y{x—™˜²¶·ÍÑÒäéìôùüúÿÿûÿÿüÿÿýþÿþþþÿþüÿÿûÿÿúÿÿôþüçúùÝïðÑáåÄÒØ´¼ÄŸ ¨ƒ‡‘l`gEQX7DG,DC.JD4LD7KA8I>:C;9SJKia_wvœ’¾³¯ÙÎÈêÜÓþèÝÿóéÿäÛð©£ÃecµBEÇDIÚRVÛUTÑMKÊDAÍCAÔFE×EFØDDÙCDÖ=?×>@Ø@?Ö@?ÖB@ÓB?ÓB=ÔA:Ù@:Ù@:ÒB:ËE<ÀD<²B7¡<2“9.Ž<0‰=0ƒ>/>.=-~<,€=-€=-9-9-~:/}9.}9.|8-{8/{8/}:1}:1{;2{;2{;2{;2z;4x<4t;2q;1r90o9/n8.l8-l6,k7,l8-j8-j8-j8-j8-i9-j8-j8-n91m80m80m80m80i7.f4+c1(d2)a1']-#_0&c4*\-#_0&sD<}PJVP~YQpTI^J?OC7?<-46(2;*0;+1<.2=/4<14<15;17:379479668357257227007/08-.9+0;-2?.6C27E48G48G49F54>33:2/4-,2(/0(13(57*6:)6>'DQ5YmJk„Zw—fwœfl“Z_‡KWxCWuCTr@Tr@VtBXvDYwEYwEZxF]{I_}K]{I]{I_}K^|JZwKPgJAW@3I2icSicSicSicSicSicSicSicSicSicSicSicSicSicSicSicSjcSkbSkbSlcTlcTmdUmdUmdUmdUmdUmdUneVneVneVneVmg[jkfƒ‡ˆ£§¨¹¾ÁÐÕØåíïóûýõýÿûÿÿûÿÿüÿÿüþûýþùþýøÿþ÷ÿÿóøýæôýÞî÷ØæòÎÝéÃÎÚ´¶Á™¡«†€‡efmLMQ6FH0HJ5KI:HD9D@7OGDj`_‹€¤š™·¯¬ËÆÂÞÛÔêæÝúñèÿûñÿ÷íÿÝÕû¶±åŽÊcd°@?ÃPKÉTMÉPHÃF@ÈGBÔMJÖKHÐ@?Ò>>Ó??Õ?>ÕA?ÕA?ÓB?ÓB=ÓB=Ö>9Õ@:ÒC=ÌE?ÀE>²A9¢=5•;2Ž<1‰=0ƒ>/>.=/~<,€=-€=-9-9-~:/}9.}9.|8-{8/{8/~;2~;2|<3{;2{;2{;2z;4x<4r90o9/o9/m9.l8-k7,j6+h6+i7,i7,i7,h8,h8,h8,h8,h8,m;2l7/j5-i7.j8/j8/f4+a1'e5+a2(].$a2(b3)Y* a2(yNE\VvWRiNGWC:I<3@:.:;-8<.08)/:*3;.4Ð@?ÑA@ÒC?ÑC?ÑC?ÒC=Ó?;ÒA<ÐE@ÉE@½C>¯@9 >5•=3Ž<1‰<2ƒ=1=0=1~<.=/=/~:/~:/~:/}9.|90{8/{8/{8/|<3|<3|<3{;2z;4y:3y:3w;3n70m80l7/l7/k6.h6-h6-h6-i7.h8.h8.g8.g8.g8.g8.h8.k92h6/f4-g5.i70h70e4-b1*c2+b3+_0(]1(]1(V*!b6-{ULtYRaNHN?8A7.=6,;9-9;.9<139-3;.5;/6<06<07:/58-47.69049238139/39/2:/19.19,.9+.9+/:,0;-3>.6C2:E5Qn>Qn>Qn>Qn>Qn>Sp@Sp@WtD[xH]zJ]zJ_|L_|LZwGRlECU?6D7(6)gdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSicSjcSkbSkbSlcTlcTmdUmdUmdUmdUmdUneVneVofWpgXpgXng]lnmz‚…“š «µ·ÄÎÐÜæèí÷ùôþÿõþýöÿüúÿúûÿùûþóøúíõöèñôãôýêôýèôüåóùßòöÛéìÍØ×¹ÅÄ¥±°’ŽregOMP;GK:FM=GOBKQG{{sŸš”ž¸ØÎÌßÓÓçÛÛóëéü÷ôðïêüüôÿÿöÿýóÿùïÿóêÿçÞÿ×ËØ“ƒ¸eS£J:´TF½WIµF;·@8ÈKEÇC>ÊC?ÌB?ÎC@ÎC>ÎC>ÍD>ÍB=ÑB<ÒC?ÎDAÅD?¸A=ª=8ž;5•<4Ž;3‰<2ƒ=3=2=1~<0=1=/~:/~:/~:/}9.|90{8/{8/{8/|<3{;2{;2z:1y:3x92w81u91n70l7/l7/j8/i7.i7.h6-g7-g7-g7-f7-f7-f7-f7-f7-f7-h70h6/g5.g5.g6/h70g6/f5.a2*e6.^2)\0'`4+a5,i=4uSJXG@E>6<5/95,;8/8:/57,36+69.5;/7:/69.69.58-57,36+28,19,28.19,19.19,19,19,.9+.9+.9+/:,0;+3>.6A17B2ex\umt’lf‰_RwKBh9KkVsCZwG]zJ^{K_|L_|LVsCNg@ÉD=ÈC<ÉB<ÑC?ÐE@ÌEAÂC=³=9¦;5œ;5•<6Œ<3‡=4…<5=4<3~<0=1=1~:/~:/~:/}9.|90{8/{8/{8/{;2{;2y:3x92w81v70v70s7/n70j8/j8/j8/j8/h8.h8.h8.g7-f7-f7-f7-d8-d8-d8-f7-g6/h70i81i81h70i81j;3l=5g80k<4b6-a5,oC:xLCtI@nMDC9056.45/8918;247.14+25,58-58-57,46+46+46+46)37)/7(.9)08+.9).9+.9)08)08)19*08)08+/7*08+19,3;.4<-9B1:C0;B0:A1:<.68*24&/3$29'IU?cu[m„gf„bWyTInE?d8Hg;Li;Nk=Nk=Li;Li;Mj
      UrDYvH[xJ]zL^{M\yKQn@G_;6B4+4/#)%gdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSgdSicSjcSjcSjbUlbVlbVmcWmdUmdUmdUleUmfVngWogZnh\oh^mjekormtzƒŠ¥®³ÃÌÑÕßáæîñôüþôýú÷ýùùþ÷úÿôüÿòüÿñüÿîýþðûøïþúñÿùïÿúíÿùéÿòßïàËÝηÁ²›¢—|ubb_NXZL]cWmwn|†}¦¬¢¾ÀµÚÕÏîäâüîîÿôôÿô÷þôõÿùùûúøûýøüÿúøÿõôüñ÷ýñÿÿñÿùèÿôãÿÌ»½p›QD©SFµSH²C:ÀJ@ÄH@ÇG>ÉF>ÈE=ÇD<ÆC;ÆC;ÍG>ÌG>ÇG>¼C;­>5Ÿ:2—:3‘>6Š=5†=4ƒ=5=4€<3;0;1;1~:/~:/~:1}90|90{8/{8/{8/z:1z:1x92w81v70u6/u6/q6.m80k90j8/j8/i9/i9/i9/h8.g7-f7-g7-f7-f7-f7-f7-f7-f5.j81m;4k:3j92j:0m>4oC8l@5oD;d<2c=2zVJ†dZyWMbLA>:13814927<54:0/5+25,9<336+25*24)03(13(25*46+47,.6),7)/7*-8*/7*/7*/7*/7*19,08+08-/7,/7,/7,08-08+7?09B14*00!''heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjdVjdVjdXldYlcZmeZmeXmfVg`NjeRnkXol]he\feasqr‚†Š“–ž¡«³¶ÃÈËØÝàêîïö÷ùùûúüþýþþüÿÿúýþöúýòùüñúýòûþóùúòúúòùùíüúëþüçù÷ÞéåÊÕÔ¶º¹›˜˜|qtY_dMbkXr}l„‚‘›´¹²ËÌÇãâÞòîë÷óòû÷öýùøüø÷ÿþüþþüþþüýÿúýÿúýÿúýÿúýÿúúü÷ÿÿúÿûöÿê娧 £`X›D=µNE¿MCÂF<ÄD9ÊE<ÎI@ÎKAËH@ÇG<ÆG8ÃH8½J8³H8¦E5šB4‘B5‹C5†B5„B6‚@4‚>3‚<2„:1†91†9191~:1|91{80z7/z7/w7.v6-w7.w7.w8/w8/v7.u6-q5+n3+l7/i81i81h70h70g6/g6/g6/f5.g6/i70i81h70g6/e4-e3,h3-j5/m80k90j:0i;.i=0kA3gB2jI:dH:v_O~k\ŠxjŒoRJ=79.4:04:039/39/39/28.28.17-17-36-06,25,/5+14+/5+/4-.5-/4-.5-/4-/4-/4-/4-05./4-/4-.3,.3,/4-/4-/6.1;23=26@58B79D67B45@03>-4?.DQ=WeN[kQPbHEX<@T8BW6Ic>Ke>Kf=Kf=JeOj?UpGYtK\vO]wP]wRWqNHb?;O6&1+&+.$),heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjcYkdZlc\md[meZmfVidQjhSmjWjk[gg_lll~„“š¨¯µ¸ÂÄÑÖÙâçêòóõûüþÿþÿÿþÿþýûÿþúÿÿúþÿùûüôøûòöüò÷ýó÷úñøúïøúí÷úéùûåòõÚßâÃÌЯ´¸—‘–vkqUYaI_kUtoŒ˜Š§œ¿Á¼ÓÓÑççåóóñ÷÷õûûùüüúûûùþþüþþüþþüþþüþþüþþüþþüûÿþõÿÿõÿÿþÿÿÿûúÿíêð¿ºÂ~uŸKA¯M@¹K>ÂL@ÅK>ÃE9¼=4¾?6ÃE9ÄF7ÃJ7½L:³J7¦F6™C2‘C6E7…C7‚B8A7>5‚<4ƒ:3†91„93~92}:2z:1z:1y90x8/v7.v7.u6-v7.t8.t8.t8.r6,o5*m4+l7/i81j81h70i70h70g6/g6/e3,e3,g5.h6/j81j81j81k92k60l71k90k;1k;/j>1j@0iD2gH6kP=gRAufSueŒ…s†ƒrKL<69.39/39/39/28.28.28.17-17-17-17-06,06,/5+/5+/5+/4./4./4./4./4./4./4./4.05//4..3-.3-.3-.3-/4./6/.80/:21=34@66B66B66B45B16C1CP>P]IR`IIW@AO6BP7EU:Jb@Jd?Ke@Ke>Ic6I5&1-',0$)-heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjcYkdZlc\md[meZmfVmhUkiTmjWjk[kkcwww‘’—§¬²¿ÆÌÒÜÞìñô÷üÿþÿÿþÿÿÿþÿÿþÿþýûÿþúÿÿúýþøúûóõøïñ÷ëñ÷ëô÷ìõùëöøêõøåõ÷áîîÔÛÛ¿ÉÊ«°±’“–yuy`kpZt{iˆŸ§œ®µ­ÍÏÊÞÞÜïïíøøöûûùþþüþþüýýûþþüþþüþþüþþüþþüþþüþþüýÿþûÿÿûÿÿÿÿÿÿûùÿúôÿ÷íýÑÆØž”L=¥RB©L;§@1·G;ÏYMÏUJ¼@4ÄD7ÆH:ÃK=¹I;ªB7?3—@7“E;‰@9„A9A8?6~>5}=4<4}=4z;4x<4w;3w;3u:2t91t91t91r90r90r90r90o9/n8.l6,k5+l7/j81l71j81k60i70i70h6/g5.g5.f5.g6/h70i81k:3k:3l;4j;3i:0h<1k?2jC4iD2fE2fI7lVAjYGujV†m‘Ž{€mEF658-28.28.28.17-17-17-06,17-17-17-06,06,/5+/5+/5+/4./4./4./4./4./4./4./4./4./4..3--2,-2,.3-/4..5.+5-+6.-9//;12>24@46B47D38E3?L:ER>CQ:;I28F->L3DT9J_@Jb@LdBKc?Ia=G`9F_8G`9RkDXpL]uS^vVZqTPgK=T8.A.&1-',0%*.heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjcYkdZlc\md[meZmfVniVljUlkWlm]pqi€‚ž¡¦¹¾ÄÄËÑÛåçõúýûÿÿüýÿüýÿþüýüûùÿþüÿÿûÿþùûüôõöîîñæéïãçíßíñâðôåñôãñôßòñÜêêÐØØ¼ÇÇ«²±•¡¡‰‘“}“€œž‘ª­¢¶»´ÀÅ¿ÜÜÚééçööôûûùýýûÿÿýÿÿýýýûþþüþþüþþüþþüþþüþþüþþüþþþûûýÿþÿÿþÿ÷òïüóìÿüóÿûíÿôäìñ¹p•P@¢O?¸XJ·M?µE9ÀG<ÁA6ÈE;ÅI?½G=¯@9¡<4š=6–A4e=1f>2hC3iE5fG3cG2cJ6hV@i\IskV…‚oŽzpq_9=,47,28.17-17-17-06,06,06,17-17-17-06,06,/5+/5+/5+.3-.3-.3-.3-.3-.3-.3-.3-.3-.3--2,-2,-2,-2,.3--4-*4,)4,*6,+7-.:.1=14@25A36C2:G5N4DX¿@7ÆC;ÅF?¿D=±>;¦:7ž:8™>;‘=;Š?<„@=}@=xA6s>6r=5r=5r=5p>5o=4n>4m=3l<2k;1j;1i:0i:0j:0n72p62p62m61m61l71i70i70l;4k:3h91e90e90e90e:1d<2fB6cA5cC4dD5dG5dI6bI3_I2^L6eV?jbMrmW„ƒo„‡r[`L3:(28,28.17-17-17-06,06,06,17-17-17-06,06,/5+/5+/5+.3-.3-.3-.3-.3-.3-.3-.3--2,-2,,1+,1+,1+,1+-2,,3,,6.+5-*4+*4++5,.8-0;-2=/2=-5@/6A05A-1=)1=)5A-8F/=O5@T8FY=H\@J]?I^=K^>K`?TgG[pQcvZauZYkSJ]G6G4&4%$-*$),"'*heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjcYkdZlc\md[meZlfVjgTkjUlnYorasvm…„Ÿ¤¨¸¿ÇÖßäí÷ùûÿÿûÿÿûüÿþÿÿÿþÿþýûÿÿûÿÿúüüôóõêëíâãçÙÝãÕÜãÑäéÓçìÕéíÖêìÔëëÓèæÏßÚÄÓθÓÎºÌÆ¶ËøÐÉÁ×ÒÎàÛØêæåðïíóòðùù÷ýýûýýûýýûÿÿýþþüüüúþþüþþüþþüþþüþþüþþüþþüÿýüÿûüÿøùÿþýþÿýùÿýôÿøïÿõ÷ÿöð÷çÿÿíÿîÛͧ”¤kX¢[GªWE­L;¹D:ÀD<ÀE>¼E?´A>ª=:¢:9š;9•=5o?5o?5o@6n?5m>4k<2h<1h<1h<1l<2o83q62p62p62m61l71j81i81h70g80e90e:1d<2e?4f@5dB6^B4aG8cL:dM;cM8`K6]K3]M4]Q9bX?mhRss[€ƒnv{eFO:4=*39-28.28.28.17-17-17-06,17-17-17-06,06,/5+/5+/5+-2,-2,-2,-2,-2,-2,-2,-2,-2,,1++0*+0*+0*+0*,1+,3,.5.,6.*4+*4+*4++5,-7,.9+-8*0;+4?/5@/4?.3?+3>-3@,7F/9K3@O8BT:GW¸J=¹I>¸I@´G@¯D>¥=:œ:7–=9>:ˆ?9€A:xA:tD:pF:pE5j>5n=6o83r73p62p62n72l71j81i81d8/d90c;1d>3d@4cA5cA5_C5ZE4_NnlUtv^|kcmU2>(6B.3;.39/39/39/28.28.28.17-17-17-17-06,06,/5+/5+/5+-2,-2,-2,-2,-2,-2,-2,-2,,1+,1++0**/)*/)+0*,1++2+-4-+5-*4,*4,+5,+5,,6+-7,,6+/:,2=/6A17B27B15@04?.2?-4C.:G3=L5AO8DT:JX?L\BTbI\kTcqZ^mXUbPDRA2>0#/%&/,&,,$**heVheVheVheVheVheVheVheVheVheVheVheVheVheVheVheVjdVjdVjcYkdZlc\md[lfZlfVolYmlWjlWgkZflbr{xŽ˜š¨±¸ÊÓØãìñøýÿ÷üÿúûÿþÿÿÿþÿúùõÿÿúýýõøøîðòåéëÝåéØãêØåíÖæìÒéíÒêíÒèèÎèæÏèãÏáÚÈØÐÃØÎÄÝÒÌêßÛøíëÿôöÿõùÿõûÿùüþüýÿÿýÿÿýþþüþþüÿÿýÿÿýýýûþþüþþüþþüþþüþþüþþüþþüÿþúÿýûÿýûýüúùýüøÿÿõÿÿóÿÿíýúóÿûûÿúÿÿôÿöæÿóßÿãÍ×­•©oY¨WD®Q@¬O>¯OA±OB­K@¤C<™<5•>7?6ˆ?8A7{B7uD6qE8qE8p?8q?8s>8q?8q?8q?8q?8p?8sB;qB:o@8m>6l=5j>5m>6o>7o83q73o83m82m82i81h91f:1f;2d>3d@4bB5`C5]A3\@2WB1TG4[S>f^Gi^HbX?ZS9ZS7\W:ZV;XW;kmUsw^u}fUaI&28D03;.4:04:039/39/39/28.28.17-17-17-06,06,/5+/5+/5+-2,-2,-2,-2,-2,-2,-2,-2,,1++0*+0**/)*/)+0*+0*,1++2+)3+*4,+5-+5,,6--7.-7,,6+.8-2<16A39D69D47B46A10;+2?-5B09F22=/x=/t?/sB3tD6r=5r=7t=8s>8u@:u@:t?9q?8sA:q@9q@9q@9p?8n?7o>7o>7k92m82l:3l;4l;4h<3g<3c=2c?3^>1dG9cG9T=-N9(M8'@1WQ;PN7KI0OK2]Y>ieJeaDVU7XX<]`CosZz€fdlU=I1-9#2>*4-1=)2>*9E/BN8IU?O[GVbN]hWYdTLWI/u@8s>8u>9u@:t?9o=6p>7sA:q?8p?8p?8n?7o>7m>6n=6m>6k<4l=5m>6k?6j?6gA6eA5bB5dG9[A2^G7^I8N=+F7$G8%>6!LL4GK2DG,DD*MM1\[?baC`aBYY=dgJsw^sy_X`I:D,/;%7C/6>16<26<26<25;15;15;15;15;15;15;14:04:039/39/39/27127127116016016005/05/.3-.3--2,-2,,1+,1++0*+0**1**1*)0))0))0)*1*+2*,3+.5--4,.5-07/4;39A6?F>BJ?;F8:E57B14?.3?+6B.)r>)s@+tD0vE4q?4n<3q<4tB9sA8o?5qA7xH>n>4m>4m>4k?4l=3j>3l=3j>3g?5gA6gA6gC7eC7cC6`C5^D5bK;UB1ZI7`S@RG3C;&E=(FA+AE,BH.AE*<@%?B%NN2_`AijKaaEnqTvzagmSJO94<%4=(=F38>28>48>48>47=37=37=36<28>48>47=37=37=36<26<26<25:449349349338238238227105/05//4..3--2,,1++0*+0*).().().().().(*/)+0*,1+160/4.,1+,1+/4.6;4=BK:4.8/-4--4-,3,gdUgdUheVheVheVheVifWifWifWifWifWifWifWifWifWifWkeWkeWlcZmd[md]mf\mg[jiWkmXimVjoYjs`hthm|wˆ˜˜¦³¹¿ÊÐÓÜãëðööûÿüýÿýÿþÿÿýÿþùþþöýýñúûí÷úçô÷âîóÜåíÕâèÎÛàÀ×Ú»ÖÖ¼Ù×ÂÝ×ÇÞ×ÍåÛÙìààøìðûðöÿõûÿùþÿúýÿûûÿûûÿýüÿþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüýÿüøÿþøÿþûÿþþþþÿüþÿúÿÿùÿÿøþÿúýÿùüÿùùÿýúÿÿøÿÿøûÿõüþðÿÿíÿüéÿñßÿðÝÿïÚñÒ½´z{R>tJ4uH3vI4zM8}P;yL7nA.e7'{M@sD:qB8sD:oC8g;0d8-g=1i?3i?3i?3g?3f>2f>2f>2e?2b@4bB5`C5_C5_C5[D4ZE4WD3XI6OB/\T?oiSc^HMK4IG0IK3>D*?H-@F*48>47=37=37=39?58>48>48>48>48>48>48>47<67<67<66;56;56;55:45:438238216005//4.-2,,1+,1++0*+0**/)*/)+0*,1+-2,-2,05/.3-+0*+0*-2.2718=9;B:@K=@M;@M;=J68E13@,1?(0>'4.:0,6..5.-4-gdUgdUgdUheVheVifWifWifWifWifWifWifWifWifWifWifWkeWldWlcZmd[md]mf\mg[jiWkmXinWiqZgs_drejyt…••£²·½ÈÎÒÛâêïõôùýûüÿýÿþÿÿýÿÿúÿÿøÿÿóþÿñûþë÷úåðõÞæîÖâèÌÙÜ¿ÕÕ¹ÒйÔѾÚÔÈàÙÑêàßôéíþóùÿ÷üÿûÿÿýÿÿþÿÿþüÿþúÿþúþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüýÿþúÿÿúÿÿûÿÿþþþÿýþÿüüÿûüÿûúÿúøÿù÷ÿú÷ÿýøÿÿûÿÿûýÿúýþùùôîÿþöÿýôÿüóÿûîÿ÷çûæÕéÒÀÏ´¡¶š…”uawVCjI6lI6rM;uP>mF7iB3gB2jE5nI9nJ:oK;oK;eA1cB1cB1cB1cB1cB1bC1`C3]F6\G6\G6ZG6ZG6WH5TG4RG3PH3NH2fdM~~frrZVX@JL4GM3A.:>-;>39?59?58>48>47=37=37=38>48>48>48>48>48>48>48>49>89>89>88=78=78=77<67<66;55:449338227105//4./4.-2.-2.,1-+0,+0,,1--2.-2.,1-,1-,1-,1-.210513764;4;G9=L9@O<@O:8F71?2-9-,6--4,,3+fcTfcTgdUheVheVifWjgXjgXifWifWifWifWifWifWifWifWldWldWlcZmd[md]mf\mg[jiWkmXinWiqZgs_bpcgxr‚””£²·ÀËÑÔÝäëðöõúþûüÿýÿþÿÿýÿÿúÿÿøÿÿôÿÿóÿÿïúýèò÷àçðÕâèÌ×Ú½ÑѵÍË´Î˺ÖÏÅÞ×Ñìâã÷îóÿöþÿúÿÿýÿÿþÿÿÿýþÿúþÿùþÿúþÿúþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþüþþþýþÿýþÿýþÿýÿþýÿüþÿúþÿùÿÿ÷ýýóýýõþýøþýùÿþüþþþÿýÿÿþÿþùÿÿüÿÿûüûöóÿøòÿýôÿþñÿýíÿúéÿòà÷äÓçÒ¿Ò»©¹ŸŽŸ„srb|]K}^LtUCaD2W:(Y<*[>,X=*`E2`E2`E2_F2`G3`G3`G3]H3\K7\M:\M:YL9XM9UM8RL6QL6NL5QQ9ikS|€gmqXSY?FL2>G,48>48>48>47=37=38>48>48>48>49?59?5:?9:?9:?9:?99>89>89>88=78=78=77<66;55:4493382382/40.3/-2.,1-+0,+0,+0,+0,+0,,1--10.21/32/32/32-4-3?17F3=L7@O:?N7M:MJ9BC3=@5;A7;A7;A7:@6:@6:@69?58>48>48>49?59?5:@6:@6:@6;@:;@:;@::?9:?99>89>89>8:?9:?99>89>88=78=77<67<6495273162/40-2.,1-+/.+/.,0/,0/-10.21.23.23-12+1-+9*/@-6H2;M7=O7A6>A6>A6=@7=@79?59?59?5:@6:@6:B7:B7:B7;@9;@9;@::?8:?99>79>89>7;@:;@9;@:;@9:?9:?8:?9:?98?87=94;4382160/4..3/.3/.21.21,2.,2.+2++2*,4))6%$6)=!2F+8L1;O6;M5;M5;M58J29K3;M5H&DK*FM+EL*PV4PT3KN/HK,TT8bbFccIZZ@[Y@\ZA][B][B[Y@XV=US:SQ8HF1GD1DA0A?0@>1>>2??5>@5;>59?59?59A69A48C58C58C5:B79A69@88@58?79A69@8:B7:A9:B79@8:B7;B:E=8B:8B:7A88@56>14O<>P::L6@R8EW=FY=DX=@T;5H2+<),6+,3++2*ZgM[hN\hP]iQbjSckTglXhkXghVghVifWifWkeWlfXmeZmgYmgYkhYkg[kg\jf]jf[hfZefVhiWglVfo\erajwnzЉœ«²ºÈÑÐÙàáéìò÷ûøþþùþúúÿøûþóùýïøùë÷øæõôâíìØéæÓåâÏÜ×ÄÒ˹ʿ­Á´¤¹­¡¼¯¦Á¶²ËÁÀÛÐÖæßæûóþý÷ÿþûÿÿþÿþýÿüýÿüýÿüýÿþþþþþþþþþþþþþþþþþþÿþüÿþüÿþüÿþüÿýúÿüùÿüùÿýúÿýùÿþúÿþýÿýüÿüýÿýþÿþÿÿþÿÿýþýûüÿþýÿþûÿüúÿøóøíçòåÝöèßûðêÿúýÿüÿÿýþÿÿýÿÿûýÿüýÿþüýÿýþÿýþÿÿýÿÿþüÿþõÿÿîÿþèÿÿäúöÝýûâäàÇ‹‡lRM0SN0QK+QK+UO/UO/TO1TO1SO2SO2QP4QP4QM2PO3PN5NQ6MO7JP6HM6EM5HQ6EN1BK.?I'BI(FM+JP,KQ-NR/PT1VZ7^bA_bCY\?TWWU>XV=YW>XV=XW;WV:XT9QK3OI3LG4ID1DA2B@3A?3>@5<=59?59?59A67B48C57D37D3:B79A69A68@58@59A69A6:B7:B7:B7:B7:B7;C874>63=40>-3C)9M*BY/Ga1Op;Ln;Li=Fa>BY?F;J@?I>>I9?G8>F7>D8=B;>E>9C;6@74B19I/BV3Pg=XrB^J[}JXuIMhECZ@9O:6G54E2XR6:@6:@69A67B47B46C26C2;C8:B79A69A69A69A6:B7;C8;C8:B7:B7;C8;C8=E:>F;=G<=G?>H=>I9?G8>F7>D8=B;=D=9C;6@74B19I/DX5Ri?[uEZ{FWyFTqEIdA=T:2H3/@.->+6H2@R8L_CReGSgKOcG@W=6I30:/07/-4,YgMZhN\hP^jRblTemVinZjo[mn\lm[mk\mj[nhZnhZoi]oi[liZkhYjfZieZie\ieZig[ghXghVchRajWerao|s{‹ŠŸ¦¢°¹ÁËÔÔÝäéñôòúüôúøñöðíðçèìÞâãÕÚÛÉÒÑ¿ÌɶÉıþ«¿¸¦¼³¢Ê¾®ÓŸÜÐÄæÙÑíâàöìíÿôúÿùÿÿ÷ÿÿúÿÿüÿþýÿýüÿûüþüþýþÿÿþþþþþþþþþþþþþþþþþþÿþüÿþüþýûþýûÿýúÿýúÿýúÿûøÿúöþùõÿýüÿûúýùúþúûþüýÿýþÿþÿÿýþÿüûÿýúÿüúÿøó÷ìæòåÝøêáÿôîÿúýÿüÿÿýþÿÿýÿÿûýÿúýÿþüýÿüýÿýþÿÿþÿÿÿýÿþõÿýìÿûãþúßÿüæÿÿéçâÌŒˆoRL2TO2TM0UN1TN.UO/VQ3VQ3UQ4SO2ON2NM1PL1NM1NL3KN3LN6KQ7KP9JR:LU:IR5JS6OY7SZ9T[9]c?fnG‚’c’¦sŸ±›ª’¡zˆ”pr{\\bFLP7KM5LK6KI4LJ5PK5TN8VP:WQ;VP:SN;QL9LI:IG:GE9CE:=>6:@6:@69A67B47B46C26C2;C8;C8:B79A69A6:B7;C8;C8;C8;C8;C8;C8F;=G<=G?=G<=H8>F7=E6=C7=B;:A:7A95?64B19I/BV3Ne;Uo?Tu@RtAPmAE`=9P6-C.+<*+<)1C-!Vx7}f~W~m!srZw zBt{G3L^(l_(SrEoyyv{%THk-)exCpKTF-j!-@f*B?R%e-&X)jCUCd1k00;yCfEN$o zd=8)q08>-bP*Z_vXlQ6@!E_K71_(VpgoBBhk%fno_X-auH#gr^Nnt*IaRF{_5xHyP zQb;r!%`2>+B9Bs*lt!a|e*{QNOADcgurn~Qqu|_d)c<>&696zUAPcZU3FHS*z<`u6 z;CU~A3jm;?1pfZr{|-tZ1&E58=33s9Knh9#i0XV60HFi|D4>+ki!%47pfY%N zQuWq7$pHT;QGd6!&c}Cj*P1#+Cq;vvm(6;a*OV#u`G0u>N#*%CGfHk!eQ059`s`{^ zQ#Xphd>^il<=I2E9KN9H5&qvvI0=x5K7akdua)B25|B+kQ+t%1`C zZG9ta`rQ@C*Va5ds@>1P`?+AWNJAg}u&H_5CoY!py$ zxetTR=7Qc-tDszoB7KeQ`9p6BKKL05&*=o~T4mX7i(Zi@dg*S#5vDpcOx`LgNO%MF zN>5OJ1;P+*HMvcklNxI(VV5DT>3P5%Mz!7NpMH*2t|3lm9+STxp98L!97qqliJBVG zk<$%`fBC6!Ax0+1hJeg_Cy!aT_EJCSwJPj8d*Q-eyK!PtAa8Szt?^>L`uNXF0Y<8= zGw87g!-bX9{nfK^hvGH40!fqWVz-KVI2IZpIIH`J!{aC zQrLyq#Gn8Q3Lxdh08#!&i$Dqhj1mN8;)5fpnE6rC>MR0M8mwr|3;BUB6bq!H_(h)s ztgMmb<)KHVq+q!J_^}8YG=3)6qL%z6ms1)yk9AnZI>u_%CLtDIEQ^zvf)LM4VeI}SFXr05WAg_jWjrl8*;;4lHiC3V&zsLEM+JP(EEn?wW+?7rL0>;W>j-yCE(W z3=wBII^QB&`H&iE%IKNXLivv0utEfzly{jyr!hVF+f;lhW0IMwS~DfMMD}GNi4MEf zH9qptof+#P7aNMCXTMB|WO8I4@s0Z=?tiT^)gF)V<_o%Jx&a|hk?MQJ`2mO@=ywkV zuoZ6uTYZ|T*9JY}jjRhqUZR|gYEs$cdo;k&d$BLXcDXw#TMrqp6sY+o4JhX`&qmST z_;YFwKgIC}siOY@a_-Fo%acUNC?as@LuTEXs{bTo!k!ioz>6)shTT8sHc zf8HW_P!TL1ND2>;4$B9B`mqan>I|;*R+%Q&RQEX0;MKFN&jEG;9T5vpnUS2ZX4)9b znJ;I0xXG{1P2R|On1ezbZm z=Ze0F@{La^U*2T@R5*zZ5q3#5QiLYd%55FfKT%9x6kU*m73Us$jj zaKAgfMb&#x;qu+#OxbVg0bcu7h%2{|j(5AIg%mK>4r(iz=YVe+KWAPwB9g=(r(-@P zqjNAT+|F{w$fJz5G%y#F{9M--j}pt~@Ru)}&q5xd9SLiq7;)o1PX4(D`V5E11(F`` zW{&;jTMnEo@R~Uw-idoR1h@-qRxbHx8FM8Rqgz!mLmH!*z9Af0g-!>Kb0_Q_Ov(n% zm|1b%(UU-~H%@CF7O{3N>GQDB?B zL#^n=pswP~&|tby|IZ1KoKB8g7G6fA7*?85<6v|Ska}yZ^)b^eW&@6x*Ohgjb{AXz}_lSsevZ&pF@%7e5q0`R}6t z%L@iaLN7@1`9`D_*Z&&;YH(~Bq8lv9bmCCFR2pJTJSLA+%Lx?xaZQ+p| zAZA!lEDEafq#-l6#JET!T19(8IkEFv_hn%^`&qZAJ-kr=z}ybbjWnzJQDdD%1LugS z#|g+(A%2K@F*roDq*dqE#3{=jtM_z6+c^M|5vC(FOOS*~Bx(*ssBlnS*upQi%<@y- z6tJ{cl&6-6Q}B}y!|d9cqU?4_-uR8&IS9Ob!JFUAzQiF+3+dtg`VO+%6Ox*v^3-hP z00B5E)9Ro_*@16nF6knZDs?8_^Z2&AMq3(oV@M?vE=#F9MCVfmrK$t1xMKIPM8DWf zoU5y&A%QE>oKvpcPadr%m$sFA^c>zGjw$85lX?!Qo2uJD^9zV4N9Xexpy(lis4CfC zakEHyX=`haBU*+x;Cl^&&#V;Ijjsj@?%=qz7Sq|R9k1upCcYs}3y5?FtCE`TBu5A; zkX{i3V*r93k8vV_Nz}TV+NPwh^$h}di`1!oQa_^7s?yG=l)uMDcPHcSRy1m_ z`~8Hj_FEVZW{{bz_=PhzxQN~w1~soRPcoz%$*)_yi7sl3$S-+d#Y|Qg&Q!y62cuh> z0aQ;&CJPo3wNmfPbxJp}vB4ONi1n9ZHpX>xor9VLF_v-7KQ=cXtz9W$wZV%L5g@dw zD2$MxwdSg`nOZYi@t`nRgm7-T%YGcWo=7}9H?Jq zE{ROx&nwk&q1V8~lKNkT2sa5AgBLYSofWj&Jl>n1wN6EjSA=0SH~VTz!rl+Cri2EX z?1>NZY1?_2BzN;Kvu%xvlP~^~Z{Fh)86b zU-W7IuX?z>*${j4K#yyE=I*PdX_-epnhkpmdFjmgGsPKWWEU81ckYCGUC4~Q!4oYkYK~VpNdY#eV#|AGp}I004A;E%9CPAA-x% zK0DSSZxZMR3I&qB$}1sg>J`4}jaXJ&(yOR*8Awz-eso`j2t*r$hNt(l-IO8Ll)awR zZ_k(rVJsB3vgTYq3t`PLNbjI&&r*-Un#4o&D6gt(0-i%HRD2X`N7c2sJKmnq6%zj2 zVFh6Su?!&9|E9!0mJz|{dtn(ne|yI7D1~CnmLViTuQu@~{F9#9>$e~Y6B0{Z@tEi< zw7AK4o2i0&&55dgELP(0959BHg>@B25W-+>C%6K}Y? zCFa1{fmP~P81)~W-0DIqX6*giDev-F(YCyZ;RoC|PN^FE<>fJD4C()HbS`M?0=(bLc0ERA8?59C zkTO#X%Ljs9J^saqqpMbzmTl~Kuxsj^o8(J&CGr%*Zuz3XUQa)tZrwVL?60J8zKGLN ze3NaGMiRc$!8?Os(6TnR z2qTk-#khk7cNhe9x<>Ct9?jups5X{Sba3isf&F064Y06>ev-`a(CU+|hBDnz792Jd z`xzPczE_(KypTGY6jLt0%lTHSqib=H(9Fm36&Lgl3R8a04YCgDeI2j=P=4)$c7!Qo z>Mqw4#^()o{Nb)HIuM3ZUpYN1XN{X(t7b1*^Qw17*;|yQXW}Xsv%yVt`k=%9) zhE*8Fex{UE4OT{po~UzH(+pvqaX0Hxvg%#=Nuo7wxi>MhbJqwGYcj<{^xd{%)M^?U9(E?`-s_h!GdQ zdMlNsX+Pfwze<+4#2X&w57_?2yl4LtW4GAUZc{pcjcdh7+dSLq)ymj(VDSJyx%s50pw`*0W z{6G$k#4Tjl$txcx*9!FWwVYhmG+f+gu9Z(4ajFCczYr9c_)e=o$28WQKDRu;s$@EZht6QyL4 z-|Ykbz7OX6i6bV?^n|0lw&WUQV@^V4gN4(xBfV-!y?LV0BiY$G7QAcOOv8`+1qB0z z_R)#gaJbIfq028^oo$NwXIJLpZ+T>l@Pf^OOFfyEFGzp3WY$+#EGI|UUqxM7&a`BZ zg412Uk2t%Yltvhs`Rg|4gy3dRxp`iXMee?KaBrtANNUUmUMcoo(u=d;9Kc3%Hm_G} z%X<*5QPB<49LiaZHkNL^8JCr&8>yE?No&XSB@x`vR5w-)y$3QO)>Lr>kID{;+Rbw*PAqI_S$ z*Sy=-5iHfMIwvPly6=EVmzBI9Y=aSv^nfUXPjUUX7B6lo7zQ^$tX1}8W&<R^Ck^ zY7s$OVXSu-gi{C=Uer8gtWlK#;7gq>b3EMQR$rli350iho&)0G>36h=-M1g|^pUON z$RdYB*I!#P@LYPp{uN7nPiWUeEeRGWgZvF1J~N@}2ECI}z_a82GNMl|)p$u=hJ6KV zm^uu7bQBY_v!Qh5W*`xBX{N~`8gpCADEPX5HR}WdF%?qZIp>fFSV{q~w$y1VZCkz3 zGA}&4ImT@ARLmLNOjWlKBk;;|7et++tsMF1W?+uAALH{d#TY%Sd4+gi875vsBoM2Z zuykS?H}5=JntNZHel|LD3XwL9+3J;E$Bxx5M`y)Fmjuy53M;JR1b=`#@?7TD$d&uc zmbQl578?_}A*f7OU!KCtDw;_GG)x4sA=U>Glz0)GI-6o|S6VKjezpen8p z7iThx<&QEMOOU=!#>qVhOc;D1pTI^fHn7EQZA^+ SFy0h4Vu|?xbo`-qKJz~|j?X{< literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/jpeglib/testorig.jpg b/src/dep/src/irrlicht/jpeglib/testorig.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9816a0c6231a7c5eaafd445368a9eeb1cffc63df GIT binary patch literal 5770 zcmbW(S5y;DmjLjD7OF@IQiAkel%{kP4J8sV5JE?av`~c5K@n7n^ePbPA&}6K-V}sT z6$Ap(MS2lLiZsRb|9yLQ&)KKly>n(BX70IXelrg!N z0e1kjG&CR@YFZEoL`O$U&&bZi$iTqJ#mdIa&dberm6sa=;TM(_;}?_`f|9_4@od6bEKn7r$5-13uU;$FH z0RQv=`2Oyb8u+gO{AU0uD5v}?P-#-n?}3J#cObo3loIJvk*M8(7l0; zqpPP6GeMf7%*-t;9UnS5ySTccef|6c0)v7>p1+8UijH|1o0^uM@hUSb8(V}c#+Q^5 zh-Gi;>KhuHnp;}mclVHb`}zk4$HvJMlb@%iXTB~iudJ@EZ)|S;*grTt`gweEdiIYC z2%!8o>+kq)*#B^`{B==KQBhKX{&4{*0{?bO7Ak51IU3g62#~!Go1lCIExUF~VQm+k zkb?0Z*a0(2&mpY%RpiG%w13I|cd%#wFWG;={@XPJV59{8y*x@5fEHkX6&-NqEJ3S? z<#s$i(D{LY#413eeOAVPAa+U0kWstlJphrN%u^#VXy|6n@KTl<_J$Q*uxOI8hlbqK zDP}!=!sKQ-&!OyG_4ppirXlO<(FiKvWV~|;@?o?ctY?&aGu)#B9wM@=mIcwLXC zX;3_2+-1L{U}YJV%VV+Ar(9mj9P+K3FD_oZ%sn9Zc?1GGNv^OIRS#2&?}_TF>e&s- zeEWVW!?2H0;x#eQl%iEN_sV_eY$03yrAB{J)^xZIVCD18ug0ZFoB38Vyi9z^i#SNJ zC+SgSIV@BD^;N;TjOtGZ3D){kqoHeKjVHA@lbgPpi(M(j8Vvd{F;j}SE=gr^WJ}BCLveC z3P&@zLLUF_Gv(C!3XdJ+j0t?C_|v$Va(nw;9`DC@bw8LY6`#POjhd~@tFq-7iz7YG zkTtU2MfEHTUq3JgCC5Kpq)>etsqf-}f0+U+8~IGVZ{9T=pKTVLS1P%n`nRoZ zt8pD|uMng_I{zEq4-VK}p%+1EpmlsZNsD?1{taw00G6d&dICme;5rQtLSl#_r&SYd6hX$**^2 zH*IEu^m?-&r^PP)(sh`8Q*Y<(R^}zSW;=|S$O~A5?{sZLJ%1-@m|!JaQpSUFKFvkb zRP-E4Hy+vC$C)lH*A_e%QX1Q^q_RwCap4keiOC9=YTSFgLWB6k{RPB1SXnHI)!7&( zt8@8qIRb@4xYr&jwzcWg53p2YELbv=nH;vT)@B7?Y1~JN5zkNj6ioR{`Y7JyT<1S0 zcjNuBnNcn(`=20wO1W-Drx;31XXH1v&)G4!Z~5(qsx^mYW|=Y~0rtQ10=e|&qX}S# z;fc6x5p6KDwkmcT-y9|NB)Jn8?~AN*nD4q^83u7x!6t}!wAXrd)S#4vuW4iMP4PE% zwE+(1IjLy9Px9eV6$ggnFO(Z-Q*j)v!mj&>$Fb{ZTO0p=Y+4guzb0}D)W)}ILL+`@ zvG}*DvB(EPPkBmSfuCkiVDX9Hi5jnx`tm0Ar6`dSSe zTe^G1UF=1*cY7FW6PU^g%DQt6Y5!?Ly9}3VG*(G%;>pb+0~tzw+B)4;9_^TlMg&f$ zi})%ePJ~P+Uiq-orP-jrEZ1Vv1->?;g(2wjub7I>t;642&%^b){6@UdLFqTF_>}HP zttdWbnQZtF^wP#B)!V%&y~4k@_0@BqdJbNnuJ8Hi*rm&U15*ZJvmFLL$pMR(4UIai z_2Pu=SPAkz-W!88Ji4 z=6=P}UY+>du6_5RSTz{+o+iAX=X?%1h|&pB^v0aP*fY`#`W4N5lwJ=gXsTi*&Pz}( z9}Iv51Ac6#B7N^VJW9~c4ElAur_q6PG0j{%ub9}s)POUa9?8nq-s&svCKA_G2wwiA z7r6!bc+8pU_$&UEMbv5!tta<=I_VA#si{19xo7EF_Itk7CaFBhbMEpsw+6F#nuSqb zBOwX)m+f$JpuA9%74O~NVhg(N z!);TRtT_sKZ}b+Fy~;rv7)I#__*ucjs{(_;!Is*CgSu2Jp(aJ9oMKqv$i8F(7=3C2a8fAqv3w@#8 z?@?>5Ldmi^T@gokWB}JN$Yb*P<_{>^*5Pi)E#ByN9WFzvIQD*Njpo9xO2fbbj@6G3 zg?4pjzFf3oRVaiVz0C5{^V-*wj4m1^W4Qa|^A{8zzc%9c)5KnX~U+JgGovhEM9a0rk{v4j7YErx-q^+CRPLrTSK6+U<}KWDn(Iep0~W4hy`HM$wM=!75?hj?5S zdAXw8JBB{QhC5lXL@gYxjl$~zOm3ULMpEsz&TI=Y$h83b=)Crd9m97X?QH$WMeSQ_ zZmet2gJ{rL?9NZ$n`;rPuU$zj&32M@FLHnbRaQLK3CL6cWHQInAb~Sbc?6v|NOGXC zsBNp#kkST1e zn^y$BOY;a%KnEmSHDxyOBOM=-pF}F#1S)o$W~iLsJyIXG;Lm!O%oAuF-z->%H>qE1 z*gfLJxBvYsi|zv;dFh+=Csm`Rb$0#1vvX!~#yPl_pXTb1<-Auz6fTWX-pq;(Xa+nB z;X~8hmh6lIQE_ASL?U0_sZD3~9Zz(tgEdLNDf@=G-mT8IV?Owimz_);$@r$6FE27@ zX!5QJuSt`Dr+AP-+a=V*Su$7~j0pA$Twb^KQ=*$IJuzzZF)4HL5aC>azN}cdDS+7s zTXy{Jw|rDmrc~iU!aP0p|TJ@wA3maZdy!cX&i z>)2Pwn*- zOT^H3>#@E5|B#QLEH;nTHEJaV0Yk?cVmLU;F3-Mc?-M zx!#$gDd8JJr^l;N8_+9TsWnl`roMS9|qwB^RiK`nman zsimw9eYql-%DMLYHOs|}2W{5PId=tkWIhUT3?}|PLk;)BF+43eeMk6GRLiO{+`6&l z{JPX})>XiU)cW?la*a8>im6Xy(%y}uO&RRR2%wi0fO=Qq4`8y&?KViTG*u^MsAcGC z2@c#XVUuq_#7y51@RDc#bY_xkg|6M0rzM!avCxnt4Q4IHK}trSX`Efuo9Bg=oUyp9 z&V<=-pr0!Bh_L52Z|0!^6@5I0VHv6dCa=^J!?^>UwCS}4dBbb^Ce!2p09bxe8$oP+ zQ^y3wSF?u!_*5(V^ahmAg4y>&@I7eZTzOeQEdMz!&j<~Isfgvdbw}L8IEktF%B3>O z=(ZN8|BA*IJCW`s45N?Ig)Ny=CL0R)oNExjFu6O2-?T<59i{|Y-|F?vZ~X!6CN@<1 z$T~TzH`#AmAtH09FZXn3kO_x6H)9^fqux2kU+mjHn0|V86kTF5hrS{=^PbLGE1YO> zg*)R9Ad|kmPGvp*!hiN8td|$aJY(Rn%;jX8C&WQ8s{!3>{nJiex+-J9~LKZ zmIl-t(6iO2G-C9M)JPYSP13hN#rEY1@o-!1-fNv&sDC992>AL?nIZ2miRw9}|3`!wct9?Gw??;jC^l4)Mo9asnXP;%90t*kP?|3D(S59YV_ZJfxdCU`*DVy1U zP~@MwK9yWub!i&$Rho6`)JOt*anY)Ib6M4LfrU2r`ftl?f(j@~^_E{ejvFDaOw`-M za>%(qh14>oce;+033>j=Ia8=qF&GdS`b8|Zfg#0;@7rv=gM}>VI4#XgAj2A< zteKH4Y`>7xL~ZyqK2>fY1f z6F@r?y@ifXMS6-UajC^ncAyJ_m1^Z*w<*=P*oqfBDa-S=>_TnsY@beun|WO+B9P1# zbm@ar)9P7r{3{(2Ei*LcZDXGF#dy?*>O|``@wxe&54^6eLa&|e{xC=z{9t5~*HEs} z(J^g7#peO}yq^Qv{U$YX!BtZ!9H>cKLrUF9TQW6fzmq=I4O-?{5nX_nmuAW4skXORozZcF{OUWbLROcn97_yI zm!L%NB|^;Cm_DE(mZHP>vKJi%?^>z*DM9_?2uW(3 zp;cNLPnee;G0$whk`GRy?866LDlh7&B8pVN9)MOWSmD#SAP33u6X7wLDch<764En` zOCo>O?1huAVA~_gAZ|5i?EXV02}s&ZEBt9Esx_6Xe!sEF{QO<#`j_!N0`X3Tkvr(M zi0kL`5z%3Z;saCzT=lzto4flIw}h_ar=6@TP4402N05-o;BCvy z7r{XqaHl5Au`9K!%dDodQEB>muEO-ALJ75WBmsK^XVKT#axRtFkNP|g$g@~l>Fc1e z7|)g9h?xK)by7j8gLT4cCzq1(G9n7{tn6fiS$)!fp=8WSaIn_DFUPcg1#-bO)1}Fn6j7fX51NCTRr;^`PxmHw!KtSeua$3zrJ_lWSZ( zZ#r(9f7azW1%>yP6X|s|tZt&uBT=f$qvW7YDL~Gbz(EGL@~ppxY?dq6T4Hx$C6r zd|~6eh=)dBHMp1w8s+`J;EQoP)HAL(=gsp{fd^veoliA0c91O1mvt=%D@C+S%9-Mb zx6i8$`#xmyr-OJ^Cw&v$7mh}vEm6d`R@PHKknir(w7GH{YcUR@W6&NOO-MF~dJckQu)LnE}U_{r;`I})_ z#TiaR$#`!ylhS8w4-?12_G(W-cm=K{!A9yAkxYrqFtUa5_}!M|h?dU|zm32t9{UxY zi#1;KXA>O{u0gy>9}xRbJ~H^e@^@17T~{1O(T5s)fEv8)P#;Bi(E~9^Pv8y`kebr9 zVoGXD?v2%4`dP75QJOCGYMml}U6*fkQ*K3GyRRmOZ@Ppsc6}|B>{ktPV9O|EqX#ng9Q(i%9Qn47NBI1q+ zKt&jNMeVq+VK9Cl6e5n7iA`KhB*%NV6vdi^ZHssX<@bX7Vx&)(zx{p1+rRDoonK3> zyH+rI;A7n7@n%pyBnJUycD&g#ZW|QFV59Ic5p^J!I<>uH-JJ2VYXt#?-}EOC8;|+1 zN?SCN)iCj@m~Sd^iEe``MX^QH{?-_3eMfdrKT3X~u~^Dsuv;8( e^;Dd4QS7i5y@D0wT$xcv%Tm0kNlEL^^nU=~nbB7O literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/jpeglib/testprog.jpg b/src/dep/src/irrlicht/jpeglib/testprog.jpg new file mode 100644 index 0000000000000000000000000000000000000000..920fee2e32b5a8ab0af796e010ee8a1add3eee63 GIT binary patch literal 5655 zcmb7{cQjmU+s0=`?^D!47`-!$(TOfvln|nKi8@;JPDG8P6J&IW9yPk?L{IeSHIir% zk>KN;^S$&#ty6@|`>s0_)UFDt%00;yCfHxQ5dJ&)qAjHQf zz{evbARr(jA|xiIBqJpuA*F-DC@2}>Om`UJ3=GU{0-Ve&e5?!%Tw>gOLP!(}#l$Hg zBQ7j0Ac7LUeF>0=h=`Pgl$MN)Rv5v65dMGHbq@eS2uK5L-~d?wAP5i#0=(`8&;tM< z9N_Ke{QoB^V#GdhuimXn;{b) zxA>^!0F~>|#=Atb8uQ%#4<8Ve*CP{t`&F6yws-GrC25R0RtHy(444airxDB*!+$yQ zs8Lcfuwya)&$wq?aiG(Wx5u+&x&G|)iW(T*!Is$@T%v3uQ7QV zSY6Q+{W7ml-j~yTEszX*G543_ z3pU59D;JtKdx2UzU8l3Z+NFHP#m)1K?r6Vro}89gY*lj;$+0~O5Lb;X8f9)zmYny5 zxXzRTd4;$oJlNoQ1AX_z>|_On(|XG4OW6or^s3rS2UqWcPwIRNW-Rt*E_2o4>$pX6IvCi#4zi)NLHf8f5&oNjCP44XnNE;8nZlJZj8y zIIj%9zhWWgr*=h8qL{|3ipB_H>7)kgPUQG^U)b)+NHtOk?g6heDISj_W>=2I`1s&> zXU?lYhVLxmjymIiUIE+4+~u$o0we1H6tEoy7jioPz#7oI@Mv4&c$`O|YH0$u8>{hv z0iYY>;o#ujIPC8Nf&dU4TriXwfy9Hc2#d%ounJL9p>DiKcw<)}9_T7A16Womz{E%* zoRp-(kbAO%JE)s4)+|@Go(UH*TGF)M*0hOMs!9-CUKNHF^_L3iyew8v<1zera}zj9 zod&q{Y6f8s=f2s!?>AiVMtt1i%}N^RRQ7(&Q&zs?%7P0D(xrw948Dw)S?ft+!a;PG zy7HFzU9oE^V5HIXmR-UETJ(hHS=vjQ%5&;_-+*Tb z)dlPlZJ(x0qxmZNpXahKvBGFuBT<&Id*7?IIpSqSbmW%cTV2yuJ0U zo*DXlL>;@lt9wDkP_jbfUDFLRLKfICysWy{9)0%tSd=Ai{ zHQtsC*ycgNv~7?iDGXg?i&-~ZvU9Pg2TSXbzFs*aaGGPB$BIC(^g5Xaxp{&!omvXM zJzA#_!t%JmU&ZQqbHbqs+ooF*J+9_GM&Q@=KFu8u_uk#HI+=(uy#`cSXJIy{^Zg=K zf3mx7RQM&lAo}+Coa~Kg=KbI#Z4!O`Qq%Gb3Wj%#gvR-ITR2Qzo)@0)6T8%zua3iD zm~M~X==+fsy1o@7Q6d7RO6RQJ4?4vC1w2sjZAGICq03PV#dETu z(5jbLxp90$dlJ1LA~dx{o<2P>Sg8awr|C;>dAUM#6;U@hGWuSrjmTd;NyMa=@7#qZ2(gnHuh7OKvDkU|(H&NT;>V z9>jK%1rDoaO=zRwIy~myZ0PGNhn@`BD0{Vx5WX(^$XI0J$J`==`twr2!{IETja)!h zgZfFvxrDpn6=@|y?B@DU%FmTXteI^@#Y6jOb)p<0Odd(Pc3l9^{BPP;sHC=Cge&QD z+m)uUwziZ!+6tp(*0Rozd24%lV=41PeHS^BDPq2L{fFCe{6slKIb>)j<&7v#!J=lGwIQ+~ zPVsAisW~;v2ZCBUNdc3^E54err3^0*hc*CjB1mAlA7la z^3*{S8$CSOp4WEN%acv9FW6ZpsBol1y2j zkOosgsF}h~nEoN$KYRla{2R4E02l&dMnHv-Eb_WmICoivtuY>9$^Q}#Uk>yeJVnFg zN}ON9bKoQD_Q9AJHNT~rmfr0g_3I&2y8KyOO&wDdrwxA&x&Lom^x?a7ygAJ3l1&|| zWq}^y`<4g0$EcB>vpuNeJkFnIT90bfP%6wR)r^W3O#h2`&6`%i&$uR`g0qAdQ>}p}4E`b*lFL~mVa1576iglnHr77n~22f>~ zoi_q3^QRfep4YsoQD#it_YsDd0lb}uLt>}lE)^_m(79e|U)baea}N~LnxDE`_xWK2 zdKW#T5UtuAM2d}kAdHPB{B&NGl~B_IclmV8t^()aJXNIb|7|x7@1GbV@|>^83f@{3 zEmodk8wy2G>xXgmqp_^2cfI?M3LtiJc=XnB$~obR?~xgYsBfk7P?o6jE94Yh*9wc( z3kEMiYbM)8u-({SZHZ1yl#yuVm>C<5I;JzY4DiT=IG<{>->ul|DE!cxCvSj1A(>tVq$Uy>U7nhtnY7Ej6Nus<^>{BMlP##&q`)vY zy!Q(lT%e((bR5L$m#};9W5e#mvAs`l`YhS6_<`Ts()tJjz3>V$HO?U<7Z0`-^!|X` z^-b3-t)o7h?iq)oOd)UAsXW8=)f+!7LfA(%ds1&!);fz1li+l!dR8z}ddTNKe)YZf4*yfsHGm2297AF(7tHtJz7@gFO4K!gnV>5$RPF{BtdQGT z*uD2V2!I?rCP ztBYn{#&Ff^hJ*-dt&a~i6`x8pCr0a%>cIk7vioXws#3k<+^2%V>yDmxW^&>%kGp$U z87Dwqyngo9HcO@TjM>)w8TE^ULj{#DdL9;CB`bs0N>1i*tuV zO`Hj{S5r^&=C2$3A{FbkbklV5EMvt54za2LK0!AQp<*oi{JZ>Wutif03@RipZ z-mWRtFY&?q!_?OYp3ht?4>2_7Y3dLwUZF}2>C1cj}>>(sPdmRFjM=GrOR}xOxAsp zlx)v6dN&Yu07EbFZ|Gy&&)`3vs4bNREa?K*mVZSAIBy}AK=~0oThjK zk#&nr1Xmjc8K!rR_wf$}xoo@=)`PI|zxbuvFkgK!H+$s--#P;X#J%k!{+TWSH(7EM zCE(jAnXK(*UOPPcZ=irrrH1=5Lm}#eapI%OI^|0!o85Fet$40dO*T7aqbyugB_Nk@ zkMSD^_w%-*in4g;450{55XV}$-g{aKr1=qmN8*B1IM%Xn6pQzRIZ7-TAwzRiFCrMM+5CtuF(A$UM1HR@ywx&-|gs9wG zP3tNtfttk|7?yUkPCX?)0qi?S63#lj^2CF5QR{2Y>yWcL6-E;qgpM`|^!wpbY&+{; zBxbbn5OiX`SW&rvoPJQIYMc8bih=Pp>bi^3rlsHHOD>d3K&bV+d-ptq_<}Cd56to8 z)d_-G7ro1rghrcQ@|RAdO#{)jN;7-UQ*d=uM@6~k%_0?z-f7jsC>Lt(-t#)l;Fhl5 zCuUWIP@1y(D5BBSnH#-Nc6)x}gs>9N#1@Dd`E`O}e47loCV{<+N+qq)kAFZcAH3g` zR<)`^W(c-4kaRPP2Y1nnzbiLl7N+q@q9Wrha}l6IdQVCJW0_ z#cqY@o*GC{f$c0DSq(yeamT+QLUX7Lio-C)29?M?V)UnZZHQwFK~`XxMO?JUKD_FP z@lJ1nlqGFcT5?UfQN?mUT(G_7sm6dV3nS)?rF||#XjuV>O#eGrM}I)aEY6KLr2*#{n4BAcvp+nOGQ2pnRSxj z2qpvLP`m~4k(AM91$N_@8T2Hzt{LOq*WF{j;W67n?DYc&P^*<64hUs zn_IokL(L3#0tX&KHo&Gqafs6I7td!I)VAs#0NOu7)2V+(mVA9~-)xlL{~&Nw`iw(p{8zlb#hs9CFYq;vGqJ%{<(K=O z^@464$F=e@WU1>VuE0{kTk5r(7F%AEC9r%YzR|shJo{i9rcA@M6Z9(Nu%Hq!QpQLl z6I1I=)ovp^lcjLj!Qr~`M$>s~eV;FFp7RPitYY*=1tvr9;u5Qj(mR;WNp`_}?S0*NZ!0O17jS5$qW4qOgdqc(E}HrWIl;#kEx#ljhbX~C zsF5pQ1Ii$E;zqw^G$J0cwP$(_Pm4b}xl>l{n=!JQ?H~xAq1vSpBXbRji@5qGIxCp; zTLGcJ8iU;&IZ@!sS}N*QA1sz<9}bJGA;PHO8k-c@8%b@6d17(T%qj7qUYsZ0?6z56+I?~sasnVb9`n?ZjVtZ3B7%oF~GNLhe#LwZ#q;};^oZisv30;4}CYxss%Jin` zJ}ZSZkL0KdZN}0x5OJ4Su%;$1BJvgNy`Pe@RVcB;2Gwk@0U%wNCx0E^V&GL8LmRKu z-sSM6qzFZ{UIIDm+n#|kOp)bT#;B*P(fM$jQr|k)hk>_=uK0@ZWl@L*4 zD2uZ*`|z;_)RsDT;*`4^IDXN**v3#jGDu;n$2hu2e_hm9F0NmR5z)R^LnX>9WdC4L U9#E?5!l?r;*e8trGk!h)KW4JmQUCw| literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/jpeglib/transupp.c b/src/dep/src/irrlicht/jpeglib/transupp.c new file mode 100644 index 0000000..53a9940 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/transupp.c @@ -0,0 +1,928 @@ +/* + * transupp.c + * + * Copyright (C) 1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains image transformation routines and other utility code + * used by the jpegtran sample application. These are NOT part of the core + * JPEG library. But we keep these routines separate from jpegtran.c to + * ease the task of maintaining jpegtran-like programs that have other user + * interfaces. + */ + +/* Although this file really shouldn't have access to the library internals, + * it's helpful to let it call jround_up() and jcopy_block_row(). + */ +#define JPEG_INTERNALS + +#include "jinclude.h" +#include "jpeglib.h" +#include "transupp.h" /* My own external interface */ + + +#if TRANSFORMS_SUPPORTED + +/* + * Lossless image transformation routines. These routines work on DCT + * coefficient arrays and thus do not require any lossy decompression + * or recompression of the image. + * Thanks to Guido Vollbeding for the initial design and code of this feature. + * + * Horizontal flipping is done in-place, using a single top-to-bottom + * pass through the virtual source array. It will thus be much the + * fastest option for images larger than main memory. + * + * The other routines require a set of destination virtual arrays, so they + * need twice as much memory as jpegtran normally does. The destination + * arrays are always written in normal scan order (top to bottom) because + * the virtual array manager expects this. The source arrays will be scanned + * in the corresponding order, which means multiple passes through the source + * arrays for most of the transforms. That could result in much thrashing + * if the image is larger than main memory. + * + * Some notes about the operating environment of the individual transform + * routines: + * 1. Both the source and destination virtual arrays are allocated from the + * source JPEG object, and therefore should be manipulated by calling the + * source's memory manager. + * 2. The destination's component count should be used. It may be smaller + * than the source's when forcing to grayscale. + * 3. Likewise the destination's sampling factors should be used. When + * forcing to grayscale the destination's sampling factors will be all 1, + * and we may as well take that as the effective iMCU size. + * 4. When "trim" is in effect, the destination's dimensions will be the + * trimmed values but the source's will be untrimmed. + * 5. All the routines assume that the source and destination buffers are + * padded out to a full iMCU boundary. This is true, although for the + * source buffer it is an undocumented property of jdcoefct.c. + * Notes 2,3,4 boil down to this: generally we should use the destination's + * dimensions and ignore the source's. + */ + + +LOCAL(void) +do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays) +/* Horizontal flip; done in-place, so no separate dest array is required */ +{ + JDIMENSION MCU_cols, comp_width, blk_x, blk_y; + int ci, k, offset_y; + JBLOCKARRAY buffer; + JCOEFPTR ptr1, ptr2; + JCOEF temp1, temp2; + jpeg_component_info *compptr; + + /* Horizontal mirroring of DCT blocks is accomplished by swapping + * pairs of blocks in-place. Within a DCT block, we perform horizontal + * mirroring by changing the signs of odd-numbered columns. + * Partial iMCUs at the right edge are left untouched. + */ + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + for (blk_y = 0; blk_y < compptr->height_in_blocks; + blk_y += compptr->v_samp_factor) { + buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { + ptr1 = buffer[offset_y][blk_x]; + ptr2 = buffer[offset_y][comp_width - blk_x - 1]; + /* this unrolled loop doesn't need to know which row it's on... */ + for (k = 0; k < DCTSIZE2; k += 2) { + temp1 = *ptr1; /* swap even column */ + temp2 = *ptr2; + *ptr1++ = temp2; + *ptr2++ = temp1; + temp1 = *ptr1; /* swap odd column with sign change */ + temp2 = *ptr2; + *ptr1++ = -temp2; + *ptr2++ = -temp1; + } + } + } + } + } +} + + +LOCAL(void) +do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Vertical flip */ +{ + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* We output into a separate array because we can't touch different + * rows of the source virtual array simultaneously. Otherwise, this + * is a pretty straightforward analog of horizontal flip. + * Within a DCT block, vertical mirroring is done by changing the signs + * of odd-numbered rows. + * Partial iMCUs at the bottom edge are copied verbatim. + */ + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge blocks will be copied verbatim. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + /* copy even row */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + /* copy odd row with sign change */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = - *src_ptr++; + } + } + } else { + /* Just copy row verbatim. */ + jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], + compptr->width_in_blocks); + } + } + } + } +} + + +LOCAL(void) +do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Transpose source into destination */ +{ + JDIMENSION dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Transposing pixels within a block just requires transposing the + * DCT coefficients. + * Partial iMCUs at the edges require no special treatment; we simply + * process all the available DCT blocks for every component. + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } +} + + +LOCAL(void) +do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 90 degree rotation is equivalent to + * 1. Transposing the image; + * 2. Horizontal mirroring. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) right edge properly. They just get transposed and + * not mirrored. + */ + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; + if (dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } else { + /* Edge blocks are transposed but not mirrored. */ + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } +} + + +LOCAL(void) +do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 270 degree rotation is equivalent to + * 1. Horizontal mirroring; + * 2. Transposing the image. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) bottom edge properly. They just get transposed and + * not mirrored. + */ + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + if (dst_blk_y < comp_height) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[offset_x] + [comp_height - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } + } else { + /* Edge blocks are transposed but not mirrored. */ + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } +} + + +LOCAL(void) +do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* 180 degree rotation is equivalent to + * 1. Vertical mirroring; + * 2. Horizontal mirroring. + * These two steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + if (dst_blk_y < comp_height) { + /* Row is within the vertically mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge rows are only mirrored horizontally. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + /* Process the blocks that can be mirrored both ways. */ + for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE; i += 2) { + /* For even row, negate every odd column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + /* For odd row, negate every even column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = - *src_ptr++; + *dst_ptr++ = *src_ptr++; + } + } + } + /* Any remaining right-edge blocks are only mirrored vertically. */ + for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = - *src_ptr++; + } + } + } else { + /* Remaining rows are just mirrored horizontally. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[offset_y]; + /* Process the blocks that can be mirrored. */ + for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE2; i += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + } + /* Any remaining right-edge blocks are only copied. */ + for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE2; i++) + *dst_ptr++ = *src_ptr++; + } + } + } + } + } +} + + +LOCAL(void) +do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jvirt_barray_ptr *dst_coef_arrays) +/* Transverse transpose is equivalent to + * 1. 180 degree rotation; + * 2. Transposition; + * or + * 1. Horizontal mirroring; + * 2. Transposition; + * 3. Horizontal mirroring. + * These steps are merged into a single processing routine. + */ +{ + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; + dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, + (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; + dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, + (JDIMENSION) compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + if (dst_blk_y < comp_height) { + src_ptr = src_buffer[offset_x] + [comp_height - dst_blk_y - offset_y - 1]; + if (dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + i++; + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } else { + /* Right-edge blocks are mirrored in y only */ + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + j++; + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } + } + } else { + src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; + if (dst_blk_x < comp_width) { + /* Bottom-edge blocks are mirrored in x only */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + } + } else { + /* At lower right corner, just transpose, no mirroring */ + dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; + } + } + } + } + } + } + } +} + + +/* Request any required workspace. + * + * We allocate the workspace virtual arrays from the source decompression + * object, so that all the arrays (both the original data and the workspace) + * will be taken into account while making memory management decisions. + * Hence, this routine must be called after jpeg_read_header (which reads + * the image dimensions) and before jpeg_read_coefficients (which realizes + * the source's virtual arrays). + */ + +GLOBAL(void) +jtransform_request_workspace (j_decompress_ptr srcinfo, + jpeg_transform_info *info) +{ + jvirt_barray_ptr *coef_arrays = NULL; + jpeg_component_info *compptr; + int ci; + + if (info->force_grayscale && + srcinfo->jpeg_color_space == JCS_YCbCr && + srcinfo->num_components == 3) { + /* We'll only process the first component */ + info->num_components = 1; + } else { + /* Process all the components */ + info->num_components = srcinfo->num_components; + } + + switch (info->transform) { + case JXFORM_NONE: + case JXFORM_FLIP_H: + /* Don't need a workspace array */ + break; + case JXFORM_FLIP_V: + case JXFORM_ROT_180: + /* Need workspace arrays having same dimensions as source image. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, + SIZEOF(jvirt_barray_ptr) * info->num_components); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } + break; + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + /* Need workspace arrays having transposed dimensions. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, + SIZEOF(jvirt_barray_ptr) * info->num_components); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (long) compptr->v_samp_factor), + (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (long) compptr->h_samp_factor), + (JDIMENSION) compptr->h_samp_factor); + } + break; + } + info->workspace_coef_arrays = coef_arrays; +} + + +/* Transpose destination image parameters */ + +LOCAL(void) +transpose_critical_parameters (j_compress_ptr dstinfo) +{ + int tblno, i, j, ci, itemp; + jpeg_component_info *compptr; + JQUANT_TBL *qtblptr; + JDIMENSION dtemp; + UINT16 qtemp; + + /* Transpose basic image dimensions */ + dtemp = dstinfo->image_width; + dstinfo->image_width = dstinfo->image_height; + dstinfo->image_height = dtemp; + + /* Transpose sampling factors */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + itemp = compptr->h_samp_factor; + compptr->h_samp_factor = compptr->v_samp_factor; + compptr->v_samp_factor = itemp; + } + + /* Transpose quantization tables */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + qtblptr = dstinfo->quant_tbl_ptrs[tblno]; + if (qtblptr != NULL) { + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < i; j++) { + qtemp = qtblptr->quantval[i*DCTSIZE+j]; + qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; + qtblptr->quantval[j*DCTSIZE+i] = qtemp; + } + } + } + } +} + + +/* Trim off any partial iMCUs on the indicated destination edge */ + +LOCAL(void) +trim_right_edge (j_compress_ptr dstinfo) +{ + int ci, max_h_samp_factor; + JDIMENSION MCU_cols; + + /* We have to compute max_h_samp_factor ourselves, + * because it hasn't been set yet in the destination + * (and we don't want to use the source's value). + */ + max_h_samp_factor = 1; + for (ci = 0; ci < dstinfo->num_components; ci++) { + int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; + max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); + } + MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); + if (MCU_cols > 0) /* can't trim to 0 pixels */ + dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); +} + +LOCAL(void) +trim_bottom_edge (j_compress_ptr dstinfo) +{ + int ci, max_v_samp_factor; + JDIMENSION MCU_rows; + + /* We have to compute max_v_samp_factor ourselves, + * because it hasn't been set yet in the destination + * (and we don't want to use the source's value). + */ + max_v_samp_factor = 1; + for (ci = 0; ci < dstinfo->num_components; ci++) { + int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; + max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); + } + MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); + if (MCU_rows > 0) /* can't trim to 0 pixels */ + dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); +} + + +/* Adjust output image parameters as needed. + * + * This must be called after jpeg_copy_critical_parameters() + * and before jpeg_write_coefficients(). + * + * The return value is the set of virtual coefficient arrays to be written + * (either the ones allocated by jtransform_request_workspace, or the + * original source data arrays). The caller will need to pass this value + * to jpeg_write_coefficients(). + */ + +GLOBAL(jvirt_barray_ptr *) +jtransform_adjust_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info) +{ + /* If force-to-grayscale is requested, adjust destination parameters */ + if (info->force_grayscale) { + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed + * properly. Among other things, the target h_samp_factor & v_samp_factor + * will get set to 1, which typically won't match the source. + * In fact we do this even if the source is already grayscale; that + * provides an easy way of coercing a grayscale JPEG with funny sampling + * factors to the customary 1,1. (Some decoders fail on other factors.) + */ + if ((dstinfo->jpeg_color_space == JCS_YCbCr && + dstinfo->num_components == 3) || + (dstinfo->jpeg_color_space == JCS_GRAYSCALE && + dstinfo->num_components == 1)) { + /* We have to preserve the source's quantization table number. */ + int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; + jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); + dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; + } else { + /* Sorry, can't do it */ + ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); + } + } + + /* Correct the destination's image dimensions etc if necessary */ + switch (info->transform) { + case JXFORM_NONE: + /* Nothing to do */ + break; + case JXFORM_FLIP_H: + if (info->trim) + trim_right_edge(dstinfo); + break; + case JXFORM_FLIP_V: + if (info->trim) + trim_bottom_edge(dstinfo); + break; + case JXFORM_TRANSPOSE: + transpose_critical_parameters(dstinfo); + /* transpose does NOT have to trim anything */ + break; + case JXFORM_TRANSVERSE: + transpose_critical_parameters(dstinfo); + if (info->trim) { + trim_right_edge(dstinfo); + trim_bottom_edge(dstinfo); + } + break; + case JXFORM_ROT_90: + transpose_critical_parameters(dstinfo); + if (info->trim) + trim_right_edge(dstinfo); + break; + case JXFORM_ROT_180: + if (info->trim) { + trim_right_edge(dstinfo); + trim_bottom_edge(dstinfo); + } + break; + case JXFORM_ROT_270: + transpose_critical_parameters(dstinfo); + if (info->trim) + trim_bottom_edge(dstinfo); + break; + } + + /* Return the appropriate output data set */ + if (info->workspace_coef_arrays != NULL) + return info->workspace_coef_arrays; + return src_coef_arrays; +} + + +/* Execute the actual transformation, if any. + * + * This must be called *after* jpeg_write_coefficients, because it depends + * on jpeg_write_coefficients to have computed subsidiary values such as + * the per-component width and height fields in the destination object. + * + * Note that some transformations will modify the source data arrays! + */ + +GLOBAL(void) +jtransform_execute_transformation (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info) +{ + jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; + + switch (info->transform) { + case JXFORM_NONE: + break; + case JXFORM_FLIP_H: + do_flip_h(srcinfo, dstinfo, src_coef_arrays); + break; + case JXFORM_FLIP_V: + do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSPOSE: + do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSVERSE: + do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_90: + do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_180: + do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_270: + do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + } +} + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* Setup decompression object to save desired markers in memory. + * This must be called before jpeg_read_header() to have the desired effect. + */ + +GLOBAL(void) +jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) +{ +#ifdef SAVE_MARKERS_SUPPORTED + int m; + + /* Save comments except under NONE option */ + if (option != JCOPYOPT_NONE) { + jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); + } + /* Save all types of APPn markers iff ALL option */ + if (option == JCOPYOPT_ALL) { + for (m = 0; m < 16; m++) + jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); + } +#endif /* SAVE_MARKERS_SUPPORTED */ +} + +/* Copy markers saved in the given source object to the destination object. + * This should be called just after jpeg_start_compress() or + * jpeg_write_coefficients(). + * Note that those routines will have written the SOI, and also the + * JFIF APP0 or Adobe APP14 markers if selected. + */ + +GLOBAL(void) +jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option) +{ + jpeg_saved_marker_ptr marker; + + /* In the current implementation, we don't actually need to examine the + * option flag here; we just copy everything that got saved. + * But to avoid confusion, we do not output JFIF and Adobe APP14 markers + * if the encoder library already wrote one. + */ + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + if (dstinfo->write_JFIF_header && + marker->marker == JPEG_APP0 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x4A && + GETJOCTET(marker->data[1]) == 0x46 && + GETJOCTET(marker->data[2]) == 0x49 && + GETJOCTET(marker->data[3]) == 0x46 && + GETJOCTET(marker->data[4]) == 0) + continue; /* reject duplicate JFIF */ + if (dstinfo->write_Adobe_marker && + marker->marker == JPEG_APP0+14 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x41 && + GETJOCTET(marker->data[1]) == 0x64 && + GETJOCTET(marker->data[2]) == 0x6F && + GETJOCTET(marker->data[3]) == 0x62 && + GETJOCTET(marker->data[4]) == 0x65) + continue; /* reject duplicate Adobe */ +#ifdef NEED_FAR_POINTERS + /* We could use jpeg_write_marker if the data weren't FAR... */ + { + unsigned int i; + jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); + for (i = 0; i < marker->data_length; i++) + jpeg_write_m_byte(dstinfo, marker->data[i]); + } +#else + jpeg_write_marker(dstinfo, marker->marker, + marker->data, marker->data_length); +#endif + } +} diff --git a/src/dep/src/irrlicht/jpeglib/transupp.h b/src/dep/src/irrlicht/jpeglib/transupp.h new file mode 100644 index 0000000..eb0b055 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/transupp.h @@ -0,0 +1,135 @@ +/* + * transupp.h + * + * Copyright (C) 1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for image transformation routines and + * other utility code used by the jpegtran sample application. These are + * NOT part of the core JPEG library. But we keep these routines separate + * from jpegtran.c to ease the task of maintaining jpegtran-like programs + * that have other user interfaces. + * + * NOTE: all the routines declared here have very specific requirements + * about when they are to be executed during the reading and writing of the + * source and destination files. See the comments in transupp.c, or see + * jpegtran.c for an example of correct usage. + */ + +/* If you happen not to want the image transform support, disable it here */ +#ifndef TRANSFORMS_SUPPORTED +#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ +#endif + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jtransform_request_workspace jTrRequest +#define jtransform_adjust_parameters jTrAdjust +#define jtransform_execute_transformation jTrExec +#define jcopy_markers_setup jCMrkSetup +#define jcopy_markers_execute jCMrkExec +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * Codes for supported types of image transformations. + */ + +typedef enum { + JXFORM_NONE, /* no transformation */ + JXFORM_FLIP_H, /* horizontal flip */ + JXFORM_FLIP_V, /* vertical flip */ + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ + JXFORM_ROT_90, /* 90-degree clockwise rotation */ + JXFORM_ROT_180, /* 180-degree rotation */ + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ +} JXFORM_CODE; + +/* + * Although rotating and flipping data expressed as DCT coefficients is not + * hard, there is an asymmetry in the JPEG format specification for images + * whose dimensions aren't multiples of the iMCU size. The right and bottom + * image edges are padded out to the next iMCU boundary with junk data; but + * no padding is possible at the top and left edges. If we were to flip + * the whole image including the pad data, then pad garbage would become + * visible at the top and/or left, and real pixels would disappear into the + * pad margins --- perhaps permanently, since encoders & decoders may not + * bother to preserve DCT blocks that appear to be completely outside the + * nominal image area. So, we have to exclude any partial iMCUs from the + * basic transformation. + * + * Transpose is the only transformation that can handle partial iMCUs at the + * right and bottom edges completely cleanly. flip_h can flip partial iMCUs + * at the bottom, but leaves any partial iMCUs at the right edge untouched. + * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. + * The other transforms are defined as combinations of these basic transforms + * and process edge blocks in a way that preserves the equivalence. + * + * The "trim" option causes untransformable partial iMCUs to be dropped; + * this is not strictly lossless, but it usually gives the best-looking + * result for odd-size images. Note that when this option is active, + * the expected mathematical equivalences between the transforms may not hold. + * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim + * followed by -rot 180 -trim trims both edges.) + * + * We also offer a "force to grayscale" option, which simply discards the + * chrominance channels of a YCbCr image. This is lossless in the sense that + * the luminance channel is preserved exactly. It's not the same kind of + * thing as the rotate/flip transformations, but it's convenient to handle it + * as part of this package, mainly because the transformation routines have to + * be aware of the option to know how many components to work on. + */ + +typedef struct { + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + boolean trim; /* if TRUE, trim partial MCUs as needed */ + boolean force_grayscale; /* if TRUE, convert color image to grayscale */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ +} jpeg_transform_info; + + +#if TRANSFORMS_SUPPORTED + +/* Request any required workspace */ +EXTERN(void) jtransform_request_workspace + JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); +/* Adjust output image parameters */ +EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Execute the actual transformation, if any */ +EXTERN(void) jtransform_execute_transformation + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* + * Support for copying optional markers from source to destination file. + */ + +typedef enum { + JCOPYOPT_NONE, /* copy no optional markers */ + JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ + JCOPYOPT_ALL /* copy all optional markers */ +} JCOPY_OPTION; + +#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ + +/* Setup decompression object to save desired markers in memory */ +EXTERN(void) jcopy_markers_setup + JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); +/* Copy markers saved in the given source object to the destination object */ +EXTERN(void) jcopy_markers_execute + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option)); diff --git a/src/dep/src/irrlicht/jpeglib/usage.doc b/src/dep/src/irrlicht/jpeglib/usage.doc new file mode 100644 index 0000000..4c1a1c2 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/usage.doc @@ -0,0 +1,562 @@ +USAGE instructions for the Independent JPEG Group's JPEG software +================================================================= + +This file describes usage of the JPEG conversion programs cjpeg and djpeg, +as well as the utility programs jpegtran, rdjpgcom and wrjpgcom. (See +the other documentation files if you wish to use the JPEG library within +your own programs.) + +If you are on a Unix machine you may prefer to read the Unix-style manual +pages in files cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1. + + +INTRODUCTION + +These programs implement JPEG image compression and decompression. JPEG +(pronounced "jay-peg") is a standardized compression method for full-color +and gray-scale images. JPEG is designed to handle "real-world" scenes, +for example scanned photographs. Cartoons, line drawings, and other +non-realistic images are not JPEG's strong suit; on that sort of material +you may get poor image quality and/or little compression. + +JPEG is lossy, meaning that the output image is not necessarily identical to +the input image. Hence you should not use JPEG if you have to have identical +output bits. However, on typical real-world images, very good compression +levels can be obtained with no visible change, and amazingly high compression +is possible if you can tolerate a low-quality image. You can trade off image +quality against file size by adjusting the compressor's "quality" setting. + + +GENERAL USAGE + +We provide two programs, cjpeg to compress an image file into JPEG format, +and djpeg to decompress a JPEG file back into a conventional image format. + +On Unix-like systems, you say: + cjpeg [switches] [imagefile] >jpegfile +or + djpeg [switches] [jpegfile] >imagefile +The programs read the specified input file, or standard input if none is +named. They always write to standard output (with trace/error messages to +standard error). These conventions are handy for piping images between +programs. + +On most non-Unix systems, you say: + cjpeg [switches] imagefile jpegfile +or + djpeg [switches] jpegfile imagefile +i.e., both the input and output files are named on the command line. This +style is a little more foolproof, and it loses no functionality if you don't +have pipes. (You can get this style on Unix too, if you prefer, by defining +TWO_FILE_COMMANDLINE when you compile the programs; see install.doc.) + +You can also say: + cjpeg [switches] -outfile jpegfile imagefile +or + djpeg [switches] -outfile imagefile jpegfile +This syntax works on all systems, so it is useful for scripts. + +The currently supported image file formats are: PPM (PBMPLUS color format), +PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster Toolkit +format). (RLE is supported only if the URT library is available.) +cjpeg recognizes the input image format automatically, with the exception +of some Targa-format files. You have to tell djpeg which format to generate. + +JPEG files are in the defacto standard JFIF file format. There are other, +less widely used JPEG-based file formats, but we don't support them. + +All switch names may be abbreviated; for example, -grayscale may be written +-gray or -gr. Most of the "basic" switches can be abbreviated to as little as +one letter. Upper and lower case are equivalent (-BMP is the same as -bmp). +British spellings are also accepted (e.g., -greyscale), though for brevity +these are not mentioned below. + + +CJPEG DETAILS + +The basic command line switches for cjpeg are: + + -quality N Scale quantization tables to adjust image quality. + Quality is 0 (worst) to 100 (best); default is 75. + (See below for more info.) + + -grayscale Create monochrome JPEG file from color input. + Be sure to use this switch when compressing a grayscale + BMP file, because cjpeg isn't bright enough to notice + whether a BMP file uses only shades of gray. By + saying -grayscale, you'll get a smaller JPEG file that + takes less time to process. + + -optimize Perform optimization of entropy encoding parameters. + Without this, default encoding parameters are used. + -optimize usually makes the JPEG file a little smaller, + but cjpeg runs somewhat slower and needs much more + memory. Image quality and speed of decompression are + unaffected by -optimize. + + -progressive Create progressive JPEG file (see below). + + -targa Input file is Targa format. Targa files that contain + an "identification" field will not be automatically + recognized by cjpeg; for such files you must specify + -targa to make cjpeg treat the input as Targa format. + For most Targa files, you won't need this switch. + +The -quality switch lets you trade off compressed file size against quality of +the reconstructed image: the higher the quality setting, the larger the JPEG +file, and the closer the output image will be to the original input. Normally +you want to use the lowest quality setting (smallest file) that decompresses +into something visually indistinguishable from the original image. For this +purpose the quality setting should be between 50 and 95; the default of 75 is +often about right. If you see defects at -quality 75, then go up 5 or 10 +counts at a time until you are happy with the output image. (The optimal +setting will vary from one image to another.) + +-quality 100 will generate a quantization table of all 1's, minimizing loss +in the quantization step (but there is still information loss in subsampling, +as well as roundoff error). This setting is mainly of interest for +experimental purposes. Quality values above about 95 are NOT recommended for +normal use; the compressed file size goes up dramatically for hardly any gain +in output image quality. + +In the other direction, quality values below 50 will produce very small files +of low image quality. Settings around 5 to 10 might be useful in preparing an +index of a large image library, for example. Try -quality 2 (or so) for some +amusing Cubist effects. (Note: quality values below about 25 generate 2-byte +quantization tables, which are considered optional in the JPEG standard. +cjpeg emits a warning message when you give such a quality value, because some +other JPEG programs may be unable to decode the resulting file. Use -baseline +if you need to ensure compatibility at low quality values.) + +The -progressive switch creates a "progressive JPEG" file. In this type of +JPEG file, the data is stored in multiple scans of increasing quality. If the +file is being transmitted over a slow communications link, the decoder can use +the first scan to display a low-quality image very quickly, and can then +improve the display with each subsequent scan. The final image is exactly +equivalent to a standard JPEG file of the same quality setting, and the total +file size is about the same --- often a little smaller. CAUTION: progressive +JPEG is not yet widely implemented, so many decoders will be unable to view a +progressive JPEG file at all. + +Switches for advanced users: + + -dct int Use integer DCT method (default). + -dct fast Use fast integer DCT (less accurate). + -dct float Use floating-point DCT method. + The float method is very slightly more accurate than + the int method, but is much slower unless your machine + has very fast floating-point hardware. Also note that + results of the floating-point method may vary slightly + across machines, while the integer methods should give + the same results everywhere. The fast integer method + is much less accurate than the other two. + + -restart N Emit a JPEG restart marker every N MCU rows, or every + N MCU blocks if "B" is attached to the number. + -restart 0 (the default) means no restart markers. + + -smooth N Smooth the input image to eliminate dithering noise. + N, ranging from 1 to 100, indicates the strength of + smoothing. 0 (the default) means no smoothing. + + -maxmemory N Set limit for amount of memory to use in processing + large images. Value is in thousands of bytes, or + millions of bytes if "M" is attached to the number. + For example, -max 4m selects 4000000 bytes. If more + space is needed, temporary files will be used. + + -verbose Enable debug printout. More -v's give more printout. + or -debug Also, version information is printed at startup. + +The -restart option inserts extra markers that allow a JPEG decoder to +resynchronize after a transmission error. Without restart markers, any damage +to a compressed file will usually ruin the image from the point of the error +to the end of the image; with restart markers, the damage is usually confined +to the portion of the image up to the next restart marker. Of course, the +restart markers occupy extra space. We recommend -restart 1 for images that +will be transmitted across unreliable networks such as Usenet. + +The -smooth option filters the input to eliminate fine-scale noise. This is +often useful when converting dithered images to JPEG: a moderate smoothing +factor of 10 to 50 gets rid of dithering patterns in the input file, resulting +in a smaller JPEG file and a better-looking image. Too large a smoothing +factor will visibly blur the image, however. + +Switches for wizards: + + -baseline Force baseline-compatible quantization tables to be + generated. This clamps quantization values to 8 bits + even at low quality settings. (This switch is poorly + named, since it does not ensure that the output is + actually baseline JPEG. For example, you can use + -baseline and -progressive together.) + + -qtables file Use the quantization tables given in the specified + text file. + + -qslots N[,...] Select which quantization table to use for each color + component. + + -sample HxV[,...] Set JPEG sampling factors for each color component. + + -scans file Use the scan script given in the specified text file. + +The "wizard" switches are intended for experimentation with JPEG. If you +don't know what you are doing, DON'T USE THEM. These switches are documented +further in the file wizard.doc. + + +DJPEG DETAILS + +The basic command line switches for djpeg are: + + -colors N Reduce image to at most N colors. This reduces the + or -quantize N number of colors used in the output image, so that it + can be displayed on a colormapped display or stored in + a colormapped file format. For example, if you have + an 8-bit display, you'd need to reduce to 256 or fewer + colors. (-colors is the recommended name, -quantize + is provided only for backwards compatibility.) + + -fast Select recommended processing options for fast, low + quality output. (The default options are chosen for + highest quality output.) Currently, this is equivalent + to "-dct fast -nosmooth -onepass -dither ordered". + + -grayscale Force gray-scale output even if JPEG file is color. + Useful for viewing on monochrome displays; also, + djpeg runs noticeably faster in this mode. + + -scale M/N Scale the output image by a factor M/N. Currently + the scale factor must be 1/1, 1/2, 1/4, or 1/8. + Scaling is handy if the image is larger than your + screen; also, djpeg runs much faster when scaling + down the output. + + -bmp Select BMP output format (Windows flavor). 8-bit + colormapped format is emitted if -colors or -grayscale + is specified, or if the JPEG file is gray-scale; + otherwise, 24-bit full-color format is emitted. + + -gif Select GIF output format. Since GIF does not support + more than 256 colors, -colors 256 is assumed (unless + you specify a smaller number of colors). If you + specify -fast, the default number of colors is 216. + + -os2 Select BMP output format (OS/2 1.x flavor). 8-bit + colormapped format is emitted if -colors or -grayscale + is specified, or if the JPEG file is gray-scale; + otherwise, 24-bit full-color format is emitted. + + -pnm Select PBMPLUS (PPM/PGM) output format (this is the + default format). PGM is emitted if the JPEG file is + gray-scale or if -grayscale is specified; otherwise + PPM is emitted. + + -rle Select RLE output format. (Requires URT library.) + + -targa Select Targa output format. Gray-scale format is + emitted if the JPEG file is gray-scale or if + -grayscale is specified; otherwise, colormapped format + is emitted if -colors is specified; otherwise, 24-bit + full-color format is emitted. + +Switches for advanced users: + + -dct int Use integer DCT method (default). + -dct fast Use fast integer DCT (less accurate). + -dct float Use floating-point DCT method. + The float method is very slightly more accurate than + the int method, but is much slower unless your machine + has very fast floating-point hardware. Also note that + results of the floating-point method may vary slightly + across machines, while the integer methods should give + the same results everywhere. The fast integer method + is much less accurate than the other two. + + -dither fs Use Floyd-Steinberg dithering in color quantization. + -dither ordered Use ordered dithering in color quantization. + -dither none Do not use dithering in color quantization. + By default, Floyd-Steinberg dithering is applied when + quantizing colors; this is slow but usually produces + the best results. Ordered dither is a compromise + between speed and quality; no dithering is fast but + usually looks awful. Note that these switches have + no effect unless color quantization is being done. + Ordered dither is only available in -onepass mode. + + -map FILE Quantize to the colors used in the specified image + file. This is useful for producing multiple files + with identical color maps, or for forcing a predefined + set of colors to be used. The FILE must be a GIF + or PPM file. This option overrides -colors and + -onepass. + + -nosmooth Use a faster, lower-quality upsampling routine. + + -onepass Use one-pass instead of two-pass color quantization. + The one-pass method is faster and needs less memory, + but it produces a lower-quality image. -onepass is + ignored unless you also say -colors N. Also, + the one-pass method is always used for gray-scale + output (the two-pass method is no improvement then). + + -maxmemory N Set limit for amount of memory to use in processing + large images. Value is in thousands of bytes, or + millions of bytes if "M" is attached to the number. + For example, -max 4m selects 4000000 bytes. If more + space is needed, temporary files will be used. + + -verbose Enable debug printout. More -v's give more printout. + or -debug Also, version information is printed at startup. + + +HINTS FOR CJPEG + +Color GIF files are not the ideal input for JPEG; JPEG is really intended for +compressing full-color (24-bit) images. In particular, don't try to convert +cartoons, line drawings, and other images that have only a few distinct +colors. GIF works great on these, JPEG does not. If you want to convert a +GIF to JPEG, you should experiment with cjpeg's -quality and -smooth options +to get a satisfactory conversion. -smooth 10 or so is often helpful. + +Avoid running an image through a series of JPEG compression/decompression +cycles. Image quality loss will accumulate; after ten or so cycles the image +may be noticeably worse than it was after one cycle. It's best to use a +lossless format while manipulating an image, then convert to JPEG format when +you are ready to file the image away. + +The -optimize option to cjpeg is worth using when you are making a "final" +version for posting or archiving. It's also a win when you are using low +quality settings to make very small JPEG files; the percentage improvement +is often a lot more than it is on larger files. (At present, -optimize +mode is always selected when generating progressive JPEG files.) + +GIF input files are no longer supported, to avoid the Unisys LZW patent. +Use a Unisys-licensed program if you need to read a GIF file. (Conversion +of GIF files to JPEG is usually a bad idea anyway.) + + +HINTS FOR DJPEG + +To get a quick preview of an image, use the -grayscale and/or -scale switches. +"-grayscale -scale 1/8" is the fastest case. + +Several options are available that trade off image quality to gain speed. +"-fast" turns on the recommended settings. + +"-dct fast" and/or "-nosmooth" gain speed at a small sacrifice in quality. +When producing a color-quantized image, "-onepass -dither ordered" is fast but +much lower quality than the default behavior. "-dither none" may give +acceptable results in two-pass mode, but is seldom tolerable in one-pass mode. + +If you are fortunate enough to have very fast floating point hardware, +"-dct float" may be even faster than "-dct fast". But on most machines +"-dct float" is slower than "-dct int"; in this case it is not worth using, +because its theoretical accuracy advantage is too small to be significant +in practice. + +Two-pass color quantization requires a good deal of memory; on MS-DOS machines +it may run out of memory even with -maxmemory 0. In that case you can still +decompress, with some loss of image quality, by specifying -onepass for +one-pass quantization. + +To avoid the Unisys LZW patent, djpeg produces uncompressed GIF files. These +are larger than they should be, but are readable by standard GIF decoders. + + +HINTS FOR BOTH PROGRAMS + +If more space is needed than will fit in the available main memory (as +determined by -maxmemory), temporary files will be used. (MS-DOS versions +will try to get extended or expanded memory first.) The temporary files are +often rather large: in typical cases they occupy three bytes per pixel, for +example 3*800*600 = 1.44Mb for an 800x600 image. If you don't have enough +free disk space, leave out -progressive and -optimize (for cjpeg) or specify +-onepass (for djpeg). + +On MS-DOS, the temporary files are created in the directory named by the TMP +or TEMP environment variable, or in the current directory if neither of those +exist. Amiga implementations put the temp files in the directory named by +JPEGTMP:, so be sure to assign JPEGTMP: to a disk partition with adequate free +space. + +The default memory usage limit (-maxmemory) is set when the software is +compiled. If you get an "insufficient memory" error, try specifying a smaller +-maxmemory value, even -maxmemory 0 to use the absolute minimum space. You +may want to recompile with a smaller default value if this happens often. + +On machines that have "environment" variables, you can define the environment +variable JPEGMEM to set the default memory limit. The value is specified as +described for the -maxmemory switch. JPEGMEM overrides the default value +specified when the program was compiled, and itself is overridden by an +explicit -maxmemory switch. + +On MS-DOS machines, -maxmemory is the amount of main (conventional) memory to +use. (Extended or expanded memory is also used if available.) Most +DOS-specific versions of this software do their own memory space estimation +and do not need you to specify -maxmemory. + + +JPEGTRAN + +jpegtran performs various useful transformations of JPEG files. +It can translate the coded representation from one variant of JPEG to another, +for example from baseline JPEG to progressive JPEG or vice versa. It can also +perform some rearrangements of the image data, for example turning an image +from landscape to portrait format by rotation. + +jpegtran works by rearranging the compressed data (DCT coefficients), without +ever fully decoding the image. Therefore, its transformations are lossless: +there is no image degradation at all, which would not be true if you used +djpeg followed by cjpeg to accomplish the same conversion. But by the same +token, jpegtran cannot perform lossy operations such as changing the image +quality. + +jpegtran uses a command line syntax similar to cjpeg or djpeg. +On Unix-like systems, you say: + jpegtran [switches] [inputfile] >outputfile +On most non-Unix systems, you say: + jpegtran [switches] inputfile outputfile +where both the input and output files are JPEG files. + +To specify the coded JPEG representation used in the output file, +jpegtran accepts a subset of the switches recognized by cjpeg: + -optimize Perform optimization of entropy encoding parameters. + -progressive Create progressive JPEG file. + -restart N Emit a JPEG restart marker every N MCU rows, or every + N MCU blocks if "B" is attached to the number. + -scans file Use the scan script given in the specified text file. +See the previous discussion of cjpeg for more details about these switches. +If you specify none of these switches, you get a plain baseline-JPEG output +file. The quality setting and so forth are determined by the input file. + +The image can be losslessly transformed by giving one of these switches: + -flip horizontal Mirror image horizontally (left-right). + -flip vertical Mirror image vertically (top-bottom). + -rotate 90 Rotate image 90 degrees clockwise. + -rotate 180 Rotate image 180 degrees. + -rotate 270 Rotate image 270 degrees clockwise (or 90 ccw). + -transpose Transpose image (across UL-to-LR axis). + -transverse Transverse transpose (across UR-to-LL axis). + +The transpose transformation has no restrictions regarding image dimensions. +The other transformations operate rather oddly if the image dimensions are not +a multiple of the iMCU size (usually 8 or 16 pixels), because they can only +transform complete blocks of DCT coefficient data in the desired way. + +jpegtran's default behavior when transforming an odd-size image is designed +to preserve exact reversibility and mathematical consistency of the +transformation set. As stated, transpose is able to flip the entire image +area. Horizontal mirroring leaves any partial iMCU column at the right edge +untouched, but is able to flip all rows of the image. Similarly, vertical +mirroring leaves any partial iMCU row at the bottom edge untouched, but is +able to flip all columns. The other transforms can be built up as sequences +of transpose and flip operations; for consistency, their actions on edge +pixels are defined to be the same as the end result of the corresponding +transpose-and-flip sequence. + +For practical use, you may prefer to discard any untransformable edge pixels +rather than having a strange-looking strip along the right and/or bottom edges +of a transformed image. To do this, add the -trim switch: + -trim Drop non-transformable edge blocks. +Obviously, a transformation with -trim is not reversible, so strictly speaking +jpegtran with this switch is not lossless. Also, the expected mathematical +equivalences between the transformations no longer hold. For example, +"-rot 270 -trim" trims only the bottom edge, but "-rot 90 -trim" followed by +"-rot 180 -trim" trims both edges. + +Another not-strictly-lossless transformation switch is: + -grayscale Force grayscale output. +This option discards the chrominance channels if the input image is YCbCr +(ie, a standard color JPEG), resulting in a grayscale JPEG file. The +luminance channel is preserved exactly, so this is a better method of reducing +to grayscale than decompression, conversion, and recompression. This switch +is particularly handy for fixing a monochrome picture that was mistakenly +encoded as a color JPEG. (In such a case, the space savings from getting rid +of the near-empty chroma channels won't be large; but the decoding time for +a grayscale JPEG is substantially less than that for a color JPEG.) + +jpegtran also recognizes these switches that control what to do with "extra" +markers, such as comment blocks: + -copy none Copy no extra markers from source file. This setting + suppresses all comments and other excess baggage + present in the source file. + -copy comments Copy only comment markers. This setting copies + comments from the source file, but discards + any other inessential data. + -copy all Copy all extra markers. This setting preserves + miscellaneous markers found in the source file, such + as JFIF thumbnails and Photoshop settings. In some + files these extra markers can be sizable. +The default behavior is -copy comments. (Note: in IJG releases v6 and v6a, +jpegtran always did the equivalent of -copy none.) + +Additional switches recognized by jpegtran are: + -outfile filename + -maxmemory N + -verbose + -debug +These work the same as in cjpeg or djpeg. + + +THE COMMENT UTILITIES + +The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file. +Although the standard doesn't actually define what COM blocks are for, they +are widely used to hold user-supplied text strings. This lets you add +annotations, titles, index terms, etc to your JPEG files, and later retrieve +them as text. COM blocks do not interfere with the image stored in the JPEG +file. The maximum size of a COM block is 64K, but you can have as many of +them as you like in one JPEG file. + +We provide two utility programs to display COM block contents and add COM +blocks to a JPEG file. + +rdjpgcom searches a JPEG file and prints the contents of any COM blocks on +standard output. The command line syntax is + rdjpgcom [-verbose] [inputfilename] +The switch "-verbose" (or just "-v") causes rdjpgcom to also display the JPEG +image dimensions. If you omit the input file name from the command line, +the JPEG file is read from standard input. (This may not work on some +operating systems, if binary data can't be read from stdin.) + +wrjpgcom adds a COM block, containing text you provide, to a JPEG file. +Ordinarily, the COM block is added after any existing COM blocks, but you +can delete the old COM blocks if you wish. wrjpgcom produces a new JPEG +file; it does not modify the input file. DO NOT try to overwrite the input +file by directing wrjpgcom's output back into it; on most systems this will +just destroy your file. + +The command line syntax for wrjpgcom is similar to cjpeg's. On Unix-like +systems, it is + wrjpgcom [switches] [inputfilename] +The output file is written to standard output. The input file comes from +the named file, or from standard input if no input file is named. + +On most non-Unix systems, the syntax is + wrjpgcom [switches] inputfilename outputfilename +where both input and output file names must be given explicitly. + +wrjpgcom understands three switches: + -replace Delete any existing COM blocks from the file. + -comment "Comment text" Supply new COM text on command line. + -cfile name Read text for new COM block from named file. +(Switch names can be abbreviated.) If you have only one line of comment text +to add, you can provide it on the command line with -comment. The comment +text must be surrounded with quotes so that it is treated as a single +argument. Longer comments can be read from a text file. + +If you give neither -comment nor -cfile, then wrjpgcom will read the comment +text from standard input. (In this case an input image file name MUST be +supplied, so that the source JPEG file comes from somewhere else.) You can +enter multiple lines, up to 64KB worth. Type an end-of-file indicator +(usually control-D or control-Z) to terminate the comment text entry. + +wrjpgcom will not add a COM block if the provided comment string is empty. +Therefore -replace -comment "" can be used to delete all COM blocks from a +file. + +These utility programs do not depend on the IJG JPEG library. In +particular, the source code for rdjpgcom is intended as an illustration of +the minimum amount of code required to parse a JPEG file header correctly. diff --git a/src/dep/src/irrlicht/jpeglib/wizard.doc b/src/dep/src/irrlicht/jpeglib/wizard.doc new file mode 100644 index 0000000..02418ba --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wizard.doc @@ -0,0 +1,211 @@ +Advanced usage instructions for the Independent JPEG Group's JPEG software +========================================================================== + +This file describes cjpeg's "switches for wizards". + +The "wizard" switches are intended for experimentation with JPEG by persons +who are reasonably knowledgeable about the JPEG standard. If you don't know +what you are doing, DON'T USE THESE SWITCHES. You'll likely produce files +with worse image quality and/or poorer compression than you'd get from the +default settings. Furthermore, these switches must be used with caution +when making files intended for general use, because not all JPEG decoders +will support unusual JPEG parameter settings. + + +Quantization Table Adjustment +----------------------------- + +Ordinarily, cjpeg starts with a default set of tables (the same ones given +as examples in the JPEG standard) and scales them up or down according to +the -quality setting. The details of the scaling algorithm can be found in +jcparam.c. At very low quality settings, some quantization table entries +can get scaled up to values exceeding 255. Although 2-byte quantization +values are supported by the IJG software, this feature is not in baseline +JPEG and is not supported by all implementations. If you need to ensure +wide compatibility of low-quality files, you can constrain the scaled +quantization values to no more than 255 by giving the -baseline switch. +Note that use of -baseline will result in poorer quality for the same file +size, since more bits than necessary are expended on higher AC coefficients. + +You can substitute a different set of quantization values by using the +-qtables switch: + + -qtables file Use the quantization tables given in the named file. + +The specified file should be a text file containing decimal quantization +values. The file should contain one to four tables, each of 64 elements. +The tables are implicitly numbered 0,1,etc. in order of appearance. Table +entries appear in normal array order (NOT in the zigzag order in which they +will be stored in the JPEG file). + +Quantization table files are free format, in that arbitrary whitespace can +appear between numbers. Also, comments can be included: a comment starts +with '#' and extends to the end of the line. Here is an example file that +duplicates the default quantization tables: + + # Quantization tables given in JPEG spec, section K.1 + + # This is table 0 (the luminance table): + 16 11 10 16 24 40 51 61 + 12 12 14 19 26 58 60 55 + 14 13 16 24 40 57 69 56 + 14 17 22 29 51 87 80 62 + 18 22 37 56 68 109 103 77 + 24 35 55 64 81 104 113 92 + 49 64 78 87 103 121 120 101 + 72 92 95 98 112 100 103 99 + + # This is table 1 (the chrominance table): + 17 18 24 47 99 99 99 99 + 18 21 26 66 99 99 99 99 + 24 26 56 99 99 99 99 99 + 47 66 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + +If the -qtables switch is used without -quality, then the specified tables +are used exactly as-is. If both -qtables and -quality are used, then the +tables taken from the file are scaled in the same fashion that the default +tables would be scaled for that quality setting. If -baseline appears, then +the quantization values are constrained to the range 1-255. + +By default, cjpeg will use quantization table 0 for luminance components and +table 1 for chrominance components. To override this choice, use the -qslots +switch: + + -qslots N[,...] Select which quantization table to use for + each color component. + +The -qslots switch specifies a quantization table number for each color +component, in the order in which the components appear in the JPEG SOF marker. +For example, to create a separate table for each of Y,Cb,Cr, you could +provide a -qtables file that defines three quantization tables and say +"-qslots 0,1,2". If -qslots gives fewer table numbers than there are color +components, then the last table number is repeated as necessary. + + +Sampling Factor Adjustment +-------------------------- + +By default, cjpeg uses 2:1 horizontal and vertical downsampling when +compressing YCbCr data, and no downsampling for all other color spaces. +You can override this default with the -sample switch: + + -sample HxV[,...] Set JPEG sampling factors for each color + component. + +The -sample switch specifies the JPEG sampling factors for each color +component, in the order in which they appear in the JPEG SOF marker. +If you specify fewer HxV pairs than there are components, the remaining +components are set to 1x1 sampling. For example, the default YCbCr setting +is equivalent to "-sample 2x2,1x1,1x1", which can be abbreviated to +"-sample 2x2". + +There are still some JPEG decoders in existence that support only 2x1 +sampling (also called 4:2:2 sampling). Compatibility with such decoders can +be achieved by specifying "-sample 2x1". This is not recommended unless +really necessary, since it increases file size and encoding/decoding time +with very little quality gain. + + +Multiple Scan / Progression Control +----------------------------------- + +By default, cjpeg emits a single-scan sequential JPEG file. The +-progressive switch generates a progressive JPEG file using a default series +of progression parameters. You can create multiple-scan sequential JPEG +files or progressive JPEG files with custom progression parameters by using +the -scans switch: + + -scans file Use the scan sequence given in the named file. + +The specified file should be a text file containing a "scan script". +The script specifies the contents and ordering of the scans to be emitted. +Each entry in the script defines one scan. A scan definition specifies +the components to be included in the scan, and for progressive JPEG it also +specifies the progression parameters Ss,Se,Ah,Al for the scan. Scan +definitions are separated by semicolons (';'). A semicolon after the last +scan definition is optional. + +Each scan definition contains one to four component indexes, optionally +followed by a colon (':') and the four progressive-JPEG parameters. The +component indexes denote which color component(s) are to be transmitted in +the scan. Components are numbered in the order in which they appear in the +JPEG SOF marker, with the first component being numbered 0. (Note that these +indexes are not the "component ID" codes assigned to the components, just +positional indexes.) + +The progression parameters for each scan are: + Ss Zigzag index of first coefficient included in scan + Se Zigzag index of last coefficient included in scan + Ah Zero for first scan of a coefficient, else Al of prior scan + Al Successive approximation low bit position for scan +If the progression parameters are omitted, the values 0,63,0,0 are used, +producing a sequential JPEG file. cjpeg automatically determines whether +the script represents a progressive or sequential file, by observing whether +Ss and Se values other than 0 and 63 appear. (The -progressive switch is +not needed to specify this; in fact, it is ignored when -scans appears.) +The scan script must meet the JPEG restrictions on progression sequences. +(cjpeg checks that the spec's requirements are obeyed.) + +Scan script files are free format, in that arbitrary whitespace can appear +between numbers and around punctuation. Also, comments can be included: a +comment starts with '#' and extends to the end of the line. For additional +legibility, commas or dashes can be placed between values. (Actually, any +single punctuation character other than ':' or ';' can be inserted.) For +example, the following two scan definitions are equivalent: + 0 1 2: 0 63 0 0; + 0,1,2 : 0-63, 0,0 ; + +Here is an example of a scan script that generates a partially interleaved +sequential JPEG file: + + 0; # Y only in first scan + 1 2; # Cb and Cr in second scan + +Here is an example of a progressive scan script using only spectral selection +(no successive approximation): + + # Interleaved DC scan for Y,Cb,Cr: + 0,1,2: 0-0, 0, 0 ; + # AC scans: + 0: 1-2, 0, 0 ; # First two Y AC coefficients + 0: 3-5, 0, 0 ; # Three more + 1: 1-63, 0, 0 ; # All AC coefficients for Cb + 2: 1-63, 0, 0 ; # All AC coefficients for Cr + 0: 6-9, 0, 0 ; # More Y coefficients + 0: 10-63, 0, 0 ; # Remaining Y coefficients + +Here is an example of a successive-approximation script. This is equivalent +to the default script used by "cjpeg -progressive" for YCbCr images: + + # Initial DC scan for Y,Cb,Cr (lowest bit not sent) + 0,1,2: 0-0, 0, 1 ; + # First AC scan: send first 5 Y AC coefficients, minus 2 lowest bits: + 0: 1-5, 0, 2 ; + # Send all Cr,Cb AC coefficients, minus lowest bit: + # (chroma data is usually too small to be worth subdividing further; + # but note we send Cr first since eye is least sensitive to Cb) + 2: 1-63, 0, 1 ; + 1: 1-63, 0, 1 ; + # Send remaining Y AC coefficients, minus 2 lowest bits: + 0: 6-63, 0, 2 ; + # Send next-to-lowest bit of all Y AC coefficients: + 0: 1-63, 2, 1 ; + # At this point we've sent all but the lowest bit of all coefficients. + # Send lowest bit of DC coefficients + 0,1,2: 0-0, 1, 0 ; + # Send lowest bit of AC coefficients + 2: 1-63, 1, 0 ; + 1: 1-63, 1, 0 ; + # Y AC lowest bit scan is last; it's usually the largest scan + 0: 1-63, 1, 0 ; + +It may be worth pointing out that this script is tuned for quality settings +of around 50 to 75. For lower quality settings, you'd probably want to use +a script with fewer stages of successive approximation (otherwise the +initial scans will be really bad). For higher quality settings, you might +want to use more stages of successive approximation (so that the initial +scans are not too large). diff --git a/src/dep/src/irrlicht/jpeglib/wrbmp.c b/src/dep/src/irrlicht/jpeglib/wrbmp.c new file mode 100644 index 0000000..2b8146e --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrbmp.c @@ -0,0 +1,442 @@ +/* + * wrbmp.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in Microsoft "BMP" + * format (MS Windows 3.x and OS/2 1.x flavors). + * Either 8-bit colormapped or 24-bit full-color format can be written. + * No compression is supported. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * This code contributed by James Arthur Boucher. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef BMP_SUPPORTED + + +/* + * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. + * This is not yet implemented. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * Since BMP stores scanlines bottom-to-top, we have to invert the image + * from JPEG's top-to-bottom order. To do this, we save the outgoing data + * in a virtual array during put_pixel_row calls, then actually emit the + * BMP file during finish_output. The virtual array contains one JSAMPLE per + * pixel if the output is grayscale or colormapped, three if it is full color. + */ + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + boolean is_os2; /* saves the OS2 format request flag */ + + jvirt_sarray_ptr whole_image; /* needed to reverse row order */ + JDIMENSION data_width; /* JSAMPLEs per row */ + JDIMENSION row_width; /* physical width of one row in the BMP file */ + int pad_bytes; /* number of padding bytes needed per row */ + JDIMENSION cur_output_row; /* next row# to write to virtual array */ +} bmp_dest_struct; + +typedef bmp_dest_struct * bmp_dest_ptr; + + +/* Forward declarations */ +LOCAL(void) write_colormap + JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest, + int map_colors, int map_entry_size)); + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* This version is for writing 24-bit pixels */ +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + int pad; + + /* Access next row in virtual array */ + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, + dest->cur_output_row, (JDIMENSION) 1, TRUE); + dest->cur_output_row++; + + /* Transfer data. Note destination values must be in BGR order + * (even though Microsoft's own documents say the opposite). + */ + inptr = dest->pub.buffer[0]; + outptr = image_ptr[0]; + for (col = cinfo->output_width; col > 0; col--) { + outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ + outptr[1] = *inptr++; + outptr[0] = *inptr++; + outptr += 3; + } + + /* Zero out the pad bytes. */ + pad = dest->pad_bytes; + while (--pad >= 0) + *outptr++ = 0; +} + +METHODDEF(void) +put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* This version is for grayscale OR quantized color output */ +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + JSAMPARRAY image_ptr; + register JSAMPROW inptr, outptr; + register JDIMENSION col; + int pad; + + /* Access next row in virtual array */ + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, + dest->cur_output_row, (JDIMENSION) 1, TRUE); + dest->cur_output_row++; + + /* Transfer data. */ + inptr = dest->pub.buffer[0]; + outptr = image_ptr[0]; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = *inptr++; /* can omit GETJSAMPLE() safely */ + } + + /* Zero out the pad bytes. */ + pad = dest->pad_bytes; + while (--pad >= 0) + *outptr++ = 0; +} + + +/* + * Startup: normally writes the file header. + * In this module we may as well postpone everything until finish_output. + */ + +METHODDEF(void) +start_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* no work here */ +} + + +/* + * Finish up at the end of the file. + * + * Here is where we really output the BMP file. + * + * First, routines to write the Windows and OS/2 variants of the file header. + */ + +LOCAL(void) +write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) +/* Write a Windows-style BMP file header, including colormap if needed */ +{ + char bmpfileheader[14]; + char bmpinfoheader[40]; +#define PUT_2B(array,offset,value) \ + (array[offset] = (char) ((value) & 0xFF), \ + array[offset+1] = (char) (((value) >> 8) & 0xFF)) +#define PUT_4B(array,offset,value) \ + (array[offset] = (char) ((value) & 0xFF), \ + array[offset+1] = (char) (((value) >> 8) & 0xFF), \ + array[offset+2] = (char) (((value) >> 16) & 0xFF), \ + array[offset+3] = (char) (((value) >> 24) & 0xFF)) + INT32 headersize, bfSize; + int bits_per_pixel, cmap_entries; + + /* Compute colormap size and total file size */ + if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* Colormapped RGB */ + bits_per_pixel = 8; + cmap_entries = 256; + } else { + /* Unquantized, full color RGB */ + bits_per_pixel = 24; + cmap_entries = 0; + } + } else { + /* Grayscale output. We need to fake a 256-entry colormap. */ + bits_per_pixel = 8; + cmap_entries = 256; + } + /* File size */ + headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ + bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; + + /* Set unused fields of header to 0 */ + MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); + MEMZERO(bmpinfoheader, SIZEOF(bmpinfoheader)); + + /* Fill the file header */ + bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ + bmpfileheader[1] = 0x4D; + PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ + /* we leave bfReserved1 & bfReserved2 = 0 */ + PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ + + /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */ + PUT_2B(bmpinfoheader, 0, 40); /* biSize */ + PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */ + PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */ + PUT_2B(bmpinfoheader, 12, 1); /* biPlanes - must be 1 */ + PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */ + /* we leave biCompression = 0, for none */ + /* we leave biSizeImage = 0; this is correct for uncompressed data */ + if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */ + PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */ + PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */ + } + PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */ + /* we leave biClrImportant = 0 */ + + if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) + ERREXIT(cinfo, JERR_FILE_WRITE); + if (JFWRITE(dest->pub.output_file, bmpinfoheader, 40) != (size_t) 40) + ERREXIT(cinfo, JERR_FILE_WRITE); + + if (cmap_entries > 0) + write_colormap(cinfo, dest, cmap_entries, 4); +} + + +LOCAL(void) +write_os2_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) +/* Write an OS2-style BMP file header, including colormap if needed */ +{ + char bmpfileheader[14]; + char bmpcoreheader[12]; + INT32 headersize, bfSize; + int bits_per_pixel, cmap_entries; + + /* Compute colormap size and total file size */ + if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* Colormapped RGB */ + bits_per_pixel = 8; + cmap_entries = 256; + } else { + /* Unquantized, full color RGB */ + bits_per_pixel = 24; + cmap_entries = 0; + } + } else { + /* Grayscale output. We need to fake a 256-entry colormap. */ + bits_per_pixel = 8; + cmap_entries = 256; + } + /* File size */ + headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ + bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; + + /* Set unused fields of header to 0 */ + MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); + MEMZERO(bmpcoreheader, SIZEOF(bmpcoreheader)); + + /* Fill the file header */ + bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ + bmpfileheader[1] = 0x4D; + PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ + /* we leave bfReserved1 & bfReserved2 = 0 */ + PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ + + /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */ + PUT_2B(bmpcoreheader, 0, 12); /* bcSize */ + PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */ + PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */ + PUT_2B(bmpcoreheader, 8, 1); /* bcPlanes - must be 1 */ + PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */ + + if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) + ERREXIT(cinfo, JERR_FILE_WRITE); + if (JFWRITE(dest->pub.output_file, bmpcoreheader, 12) != (size_t) 12) + ERREXIT(cinfo, JERR_FILE_WRITE); + + if (cmap_entries > 0) + write_colormap(cinfo, dest, cmap_entries, 3); +} + + +/* + * Write the colormap. + * Windows uses BGR0 map entries; OS/2 uses BGR entries. + */ + +LOCAL(void) +write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest, + int map_colors, int map_entry_size) +{ + JSAMPARRAY colormap = cinfo->colormap; + int num_colors = cinfo->actual_number_of_colors; + FILE * outfile = dest->pub.output_file; + int i; + + if (colormap != NULL) { + if (cinfo->out_color_components == 3) { + /* Normal case with RGB colormap */ + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(colormap[2][i]), outfile); + putc(GETJSAMPLE(colormap[1][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } else { + /* Grayscale colormap (only happens with grayscale quantization) */ + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(colormap[0][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + putc(GETJSAMPLE(colormap[0][i]), outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } + } else { + /* If no colormap, must be grayscale data. Generate a linear "map". */ + for (i = 0; i < 256; i++) { + putc(i, outfile); + putc(i, outfile); + putc(i, outfile); + if (map_entry_size == 4) + putc(0, outfile); + } + } + /* Pad colormap with zeros to ensure specified number of colormap entries */ + if (i > map_colors) + ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i); + for (; i < map_colors; i++) { + putc(0, outfile); + putc(0, outfile); + putc(0, outfile); + if (map_entry_size == 4) + putc(0, outfile); + } +} + + +METHODDEF(void) +finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; + register FILE * outfile = dest->pub.output_file; + JSAMPARRAY image_ptr; + register JSAMPROW data_ptr; + JDIMENSION row; + register JDIMENSION col; + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + + /* Write the header and colormap */ + if (dest->is_os2) + write_os2_header(cinfo, dest); + else + write_bmp_header(cinfo, dest); + + /* Write the file body from our virtual array */ + for (row = cinfo->output_height; row > 0; row--) { + if (progress != NULL) { + progress->pub.pass_counter = (long) (cinfo->output_height - row); + progress->pub.pass_limit = (long) cinfo->output_height; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } + image_ptr = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->whole_image, row-1, (JDIMENSION) 1, FALSE); + data_ptr = image_ptr[0]; + for (col = dest->row_width; col > 0; col--) { + putc(GETJSAMPLE(*data_ptr), outfile); + data_ptr++; + } + } + if (progress != NULL) + progress->completed_extra_passes++; + + /* Make sure we wrote the output file OK */ + fflush(outfile); + if (ferror(outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for BMP format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2) +{ + bmp_dest_ptr dest; + JDIMENSION row_width; + + /* Create module interface object, fill in method pointers */ + dest = (bmp_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(bmp_dest_struct)); + dest->pub.start_output = start_output_bmp; + dest->pub.finish_output = finish_output_bmp; + dest->is_os2 = is_os2; + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + dest->pub.put_pixel_rows = put_gray_rows; + } else if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) + dest->pub.put_pixel_rows = put_gray_rows; + else + dest->pub.put_pixel_rows = put_pixel_rows; + } else { + ERREXIT(cinfo, JERR_BMP_COLORSPACE); + } + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Determine width of rows in the BMP file (padded to 4-byte boundary). */ + row_width = cinfo->output_width * cinfo->output_components; + dest->data_width = row_width; + while ((row_width & 3) != 0) row_width++; + dest->row_width = row_width; + dest->pad_bytes = (int) (row_width - dest->data_width); + + /* Allocate space for inversion array, prepare for write pass */ + dest->whole_image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + row_width, cinfo->output_height, (JDIMENSION) 1); + dest->cur_output_row = 0; + if (cinfo->progress != NULL) { + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; + progress->total_extra_passes++; /* count file input as separate pass */ + } + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* BMP_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/wrgif.c b/src/dep/src/irrlicht/jpeglib/wrgif.c new file mode 100644 index 0000000..13f953b --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrgif.c @@ -0,0 +1,399 @@ +/* + * wrgif.c + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in GIF format. + * + ************************************************************************** + * NOTE: to avoid entanglements with Unisys' patent on LZW compression, * + * this code has been modified to output "uncompressed GIF" files. * + * There is no trace of the LZW algorithm in this file. * + ************************************************************************** + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + */ + +/* + * This code is loosely based on ppmtogif from the PBMPLUS distribution + * of Feb. 1991. That file contains the following copyright notice: + * Based on GIFENCODE by David Rowley . + * Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al. + * Copyright (C) 1989 by Jef Poskanzer. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. This software is provided "as is" without express or + * implied warranty. + * + * We are also required to state that + * "The Graphics Interchange Format(c) is the Copyright property of + * CompuServe Incorporated. GIF(sm) is a Service Mark property of + * CompuServe Incorporated." + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef GIF_SUPPORTED + + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + j_decompress_ptr cinfo; /* back link saves passing separate parm */ + + /* State for packing variable-width codes into a bitstream */ + int n_bits; /* current number of bits/code */ + int maxcode; /* maximum code, given n_bits */ + INT32 cur_accum; /* holds bits not yet output */ + int cur_bits; /* # of bits in cur_accum */ + + /* State for GIF code assignment */ + int ClearCode; /* clear code (doesn't change) */ + int EOFCode; /* EOF code (ditto) */ + int code_counter; /* counts output symbols */ + + /* GIF data packet construction buffer */ + int bytesinpkt; /* # of bytes in current packet */ + char packetbuf[256]; /* workspace for accumulating packet */ + +} gif_dest_struct; + +typedef gif_dest_struct * gif_dest_ptr; + +/* Largest value that will fit in N bits */ +#define MAXCODE(n_bits) ((1 << (n_bits)) - 1) + + +/* + * Routines to package finished data bytes into GIF data blocks. + * A data block consists of a count byte (1..255) and that many data bytes. + */ + +LOCAL(void) +flush_packet (gif_dest_ptr dinfo) +/* flush any accumulated data */ +{ + if (dinfo->bytesinpkt > 0) { /* never write zero-length packet */ + dinfo->packetbuf[0] = (char) dinfo->bytesinpkt++; + if (JFWRITE(dinfo->pub.output_file, dinfo->packetbuf, dinfo->bytesinpkt) + != (size_t) dinfo->bytesinpkt) + ERREXIT(dinfo->cinfo, JERR_FILE_WRITE); + dinfo->bytesinpkt = 0; + } +} + + +/* Add a character to current packet; flush to disk if necessary */ +#define CHAR_OUT(dinfo,c) \ + { (dinfo)->packetbuf[++(dinfo)->bytesinpkt] = (char) (c); \ + if ((dinfo)->bytesinpkt >= 255) \ + flush_packet(dinfo); \ + } + + +/* Routine to convert variable-width codes into a byte stream */ + +LOCAL(void) +output (gif_dest_ptr dinfo, int code) +/* Emit a code of n_bits bits */ +/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */ +{ + dinfo->cur_accum |= ((INT32) code) << dinfo->cur_bits; + dinfo->cur_bits += dinfo->n_bits; + + while (dinfo->cur_bits >= 8) { + CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF); + dinfo->cur_accum >>= 8; + dinfo->cur_bits -= 8; + } +} + + +/* The pseudo-compression algorithm. + * + * In this module we simply output each pixel value as a separate symbol; + * thus, no compression occurs. In fact, there is expansion of one bit per + * pixel, because we use a symbol width one bit wider than the pixel width. + * + * GIF ordinarily uses variable-width symbols, and the decoder will expect + * to ratchet up the symbol width after a fixed number of symbols. + * To simplify the logic and keep the expansion penalty down, we emit a + * GIF Clear code to reset the decoder just before the width would ratchet up. + * Thus, all the symbols in the output file will have the same bit width. + * Note that emitting the Clear codes at the right times is a mere matter of + * counting output symbols and is in no way dependent on the LZW patent. + * + * With a small basic pixel width (low color count), Clear codes will be + * needed very frequently, causing the file to expand even more. So this + * simplistic approach wouldn't work too well on bilevel images, for example. + * But for output of JPEG conversions the pixel width will usually be 8 bits + * (129 to 256 colors), so the overhead added by Clear symbols is only about + * one symbol in every 256. + */ + +LOCAL(void) +compress_init (gif_dest_ptr dinfo, int i_bits) +/* Initialize pseudo-compressor */ +{ + /* init all the state variables */ + dinfo->n_bits = i_bits; + dinfo->maxcode = MAXCODE(dinfo->n_bits); + dinfo->ClearCode = (1 << (i_bits - 1)); + dinfo->EOFCode = dinfo->ClearCode + 1; + dinfo->code_counter = dinfo->ClearCode + 2; + /* init output buffering vars */ + dinfo->bytesinpkt = 0; + dinfo->cur_accum = 0; + dinfo->cur_bits = 0; + /* GIF specifies an initial Clear code */ + output(dinfo, dinfo->ClearCode); +} + + +LOCAL(void) +compress_pixel (gif_dest_ptr dinfo, int c) +/* Accept and "compress" one pixel value. + * The given value must be less than n_bits wide. + */ +{ + /* Output the given pixel value as a symbol. */ + output(dinfo, c); + /* Issue Clear codes often enough to keep the reader from ratcheting up + * its symbol size. + */ + if (dinfo->code_counter < dinfo->maxcode) { + dinfo->code_counter++; + } else { + output(dinfo, dinfo->ClearCode); + dinfo->code_counter = dinfo->ClearCode + 2; /* reset the counter */ + } +} + + +LOCAL(void) +compress_term (gif_dest_ptr dinfo) +/* Clean up at end */ +{ + /* Send an EOF code */ + output(dinfo, dinfo->EOFCode); + /* Flush the bit-packing buffer */ + if (dinfo->cur_bits > 0) { + CHAR_OUT(dinfo, dinfo->cur_accum & 0xFF); + } + /* Flush the packet buffer */ + flush_packet(dinfo); +} + + +/* GIF header construction */ + + +LOCAL(void) +put_word (gif_dest_ptr dinfo, unsigned int w) +/* Emit a 16-bit word, LSB first */ +{ + putc(w & 0xFF, dinfo->pub.output_file); + putc((w >> 8) & 0xFF, dinfo->pub.output_file); +} + + +LOCAL(void) +put_3bytes (gif_dest_ptr dinfo, int val) +/* Emit 3 copies of same byte value --- handy subr for colormap construction */ +{ + putc(val, dinfo->pub.output_file); + putc(val, dinfo->pub.output_file); + putc(val, dinfo->pub.output_file); +} + + +LOCAL(void) +emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap) +/* Output the GIF file header, including color map */ +/* If colormap==NULL, synthesize a gray-scale colormap */ +{ + int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte; + int cshift = dinfo->cinfo->data_precision - 8; + int i; + + if (num_colors > 256) + ERREXIT1(dinfo->cinfo, JERR_TOO_MANY_COLORS, num_colors); + /* Compute bits/pixel and related values */ + BitsPerPixel = 1; + while (num_colors > (1 << BitsPerPixel)) + BitsPerPixel++; + ColorMapSize = 1 << BitsPerPixel; + if (BitsPerPixel <= 1) + InitCodeSize = 2; + else + InitCodeSize = BitsPerPixel; + /* + * Write the GIF header. + * Note that we generate a plain GIF87 header for maximum compatibility. + */ + putc('G', dinfo->pub.output_file); + putc('I', dinfo->pub.output_file); + putc('F', dinfo->pub.output_file); + putc('8', dinfo->pub.output_file); + putc('7', dinfo->pub.output_file); + putc('a', dinfo->pub.output_file); + /* Write the Logical Screen Descriptor */ + put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); + put_word(dinfo, (unsigned int) dinfo->cinfo->output_height); + FlagByte = 0x80; /* Yes, there is a global color table */ + FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */ + FlagByte |= (BitsPerPixel-1); /* size of global color table */ + putc(FlagByte, dinfo->pub.output_file); + putc(0, dinfo->pub.output_file); /* Background color index */ + putc(0, dinfo->pub.output_file); /* Reserved (aspect ratio in GIF89) */ + /* Write the Global Color Map */ + /* If the color map is more than 8 bits precision, */ + /* we reduce it to 8 bits by shifting */ + for (i=0; i < ColorMapSize; i++) { + if (i < num_colors) { + if (colormap != NULL) { + if (dinfo->cinfo->out_color_space == JCS_RGB) { + /* Normal case: RGB color map */ + putc(GETJSAMPLE(colormap[0][i]) >> cshift, dinfo->pub.output_file); + putc(GETJSAMPLE(colormap[1][i]) >> cshift, dinfo->pub.output_file); + putc(GETJSAMPLE(colormap[2][i]) >> cshift, dinfo->pub.output_file); + } else { + /* Grayscale "color map": possible if quantizing grayscale image */ + put_3bytes(dinfo, GETJSAMPLE(colormap[0][i]) >> cshift); + } + } else { + /* Create a gray-scale map of num_colors values, range 0..255 */ + put_3bytes(dinfo, (i * 255 + (num_colors-1)/2) / (num_colors-1)); + } + } else { + /* fill out the map to a power of 2 */ + put_3bytes(dinfo, 0); + } + } + /* Write image separator and Image Descriptor */ + putc(',', dinfo->pub.output_file); /* separator */ + put_word(dinfo, 0); /* left/top offset */ + put_word(dinfo, 0); + put_word(dinfo, (unsigned int) dinfo->cinfo->output_width); /* image size */ + put_word(dinfo, (unsigned int) dinfo->cinfo->output_height); + /* flag byte: not interlaced, no local color map */ + putc(0x00, dinfo->pub.output_file); + /* Write Initial Code Size byte */ + putc(InitCodeSize, dinfo->pub.output_file); + + /* Initialize for "compression" of image data */ + compress_init(dinfo, InitCodeSize+1); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + + if (cinfo->quantize_colors) + emit_header(dest, cinfo->actual_number_of_colors, cinfo->colormap); + else + emit_header(dest, 256, (JSAMPARRAY) NULL); +} + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + for (col = cinfo->output_width; col > 0; col--) { + compress_pixel(dest, GETJSAMPLE(*ptr++)); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + gif_dest_ptr dest = (gif_dest_ptr) dinfo; + + /* Flush "compression" mechanism */ + compress_term(dest); + /* Write a zero-length data block to end the series */ + putc(0, dest->pub.output_file); + /* Write the GIF terminator mark */ + putc(';', dest->pub.output_file); + /* Make sure we wrote the output file OK */ + fflush(dest->pub.output_file); + if (ferror(dest->pub.output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for GIF format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_gif (j_decompress_ptr cinfo) +{ + gif_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (gif_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(gif_dest_struct)); + dest->cinfo = cinfo; /* make back link for subroutines */ + dest->pub.start_output = start_output_gif; + dest->pub.put_pixel_rows = put_pixel_rows; + dest->pub.finish_output = finish_output_gif; + + if (cinfo->out_color_space != JCS_GRAYSCALE && + cinfo->out_color_space != JCS_RGB) + ERREXIT(cinfo, JERR_GIF_COLORSPACE); + + /* Force quantization if color or if > 8 bits input */ + if (cinfo->out_color_space != JCS_GRAYSCALE || cinfo->data_precision > 8) { + /* Force quantization to at most 256 colors */ + cinfo->quantize_colors = TRUE; + if (cinfo->desired_number_of_colors > 256) + cinfo->desired_number_of_colors = 256; + } + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + if (cinfo->output_components != 1) /* safety check: just one component? */ + ERREXIT(cinfo, JERR_GIF_BUG); + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* GIF_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/wrjpgcom.1 b/src/dep/src/irrlicht/jpeglib/wrjpgcom.1 new file mode 100644 index 0000000..44dad35 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrjpgcom.1 @@ -0,0 +1,103 @@ +.TH WRJPGCOM 1 "15 June 1995" +.SH NAME +wrjpgcom \- insert text comments into a JPEG file +.SH SYNOPSIS +.B wrjpgcom +[ +.B \-replace +] +[ +.BI \-comment " text" +] +[ +.BI \-cfile " name" +] +[ +.I filename +] +.LP +.SH DESCRIPTION +.LP +.B wrjpgcom +reads the named JPEG/JFIF file, or the standard input if no file is named, +and generates a new JPEG/JFIF file on standard output. A comment block is +added to the file. +.PP +The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file. +Although the standard doesn't actually define what COM blocks are for, they +are widely used to hold user-supplied text strings. This lets you add +annotations, titles, index terms, etc to your JPEG files, and later retrieve +them as text. COM blocks do not interfere with the image stored in the JPEG +file. The maximum size of a COM block is 64K, but you can have as many of +them as you like in one JPEG file. +.PP +.B wrjpgcom +adds a COM block, containing text you provide, to a JPEG file. +Ordinarily, the COM block is added after any existing COM blocks; but you +can delete the old COM blocks if you wish. +.SH OPTIONS +Switch names may be abbreviated, and are not case sensitive. +.TP +.B \-replace +Delete any existing COM blocks from the file. +.TP +.BI \-comment " text" +Supply text for new COM block on command line. +.TP +.BI \-cfile " name" +Read text for new COM block from named file. +.PP +If you have only one line of comment text to add, you can provide it on the +command line with +.BR \-comment . +The comment text must be surrounded with quotes so that it is treated as a +single argument. Longer comments can be read from a text file. +.PP +If you give neither +.B \-comment +nor +.BR \-cfile , +then +.B wrjpgcom +will read the comment text from standard input. (In this case an input image +file name MUST be supplied, so that the source JPEG file comes from somewhere +else.) You can enter multiple lines, up to 64KB worth. Type an end-of-file +indicator (usually control-D) to terminate the comment text entry. +.PP +.B wrjpgcom +will not add a COM block if the provided comment string is empty. Therefore +\fB\-replace \-comment ""\fR can be used to delete all COM blocks from a file. +.SH EXAMPLES +.LP +Add a short comment to in.jpg, producing out.jpg: +.IP +.B wrjpgcom \-c +\fI"View of my back yard" in.jpg +.B > +.I out.jpg +.PP +Attach a long comment previously stored in comment.txt: +.IP +.B wrjpgcom +.I in.jpg +.B < +.I comment.txt +.B > +.I out.jpg +.PP +or equivalently +.IP +.B wrjpgcom +.B -cfile +.I comment.txt +.B < +.I in.jpg +.B > +.I out.jpg +.SH SEE ALSO +.BR cjpeg (1), +.BR djpeg (1), +.BR jpegtran (1), +.BR rdjpgcom (1) +.SH AUTHOR +Independent JPEG Group diff --git a/src/dep/src/irrlicht/jpeglib/wrjpgcom.c b/src/dep/src/irrlicht/jpeglib/wrjpgcom.c new file mode 100644 index 0000000..7d10ee6 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrjpgcom.c @@ -0,0 +1,583 @@ +/* + * wrjpgcom.c + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a very simple stand-alone application that inserts + * user-supplied text as a COM (comment) marker in a JFIF file. + * This may be useful as an example of the minimum logic needed to parse + * JPEG markers. + */ + +#define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */ +#include "jinclude.h" /* get auto-config symbols, */ + +#ifndef HAVE_STDLIB_H /* should declare malloc() */ +extern void * malloc (); +#endif +#include /* to declare isupper(), tolower() */ +#ifdef USE_SETMODE +#include /* to declare setmode()'s parameter macros */ +/* If you have setmode() but not , just delete this line: */ +#include /* to declare setmode() */ +#endif + +#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ +#ifdef __MWERKS__ +#include /* Metrowerks needs this */ +#include /* ... and this */ +#endif +#ifdef THINK_C +#include /* Think declares it here */ +#endif +#endif + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define WRITE_BINARY "w" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define WRITE_BINARY "wb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define WRITE_BINARY "wb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif + +/* Reduce this value if your malloc() can't allocate blocks up to 64K. + * On DOS, compiling in large model is usually a better solution. + */ + +#ifndef MAX_COM_LENGTH +#define MAX_COM_LENGTH 65000L /* must be <= 65533 in any case */ +#endif + + +/* + * These macros are used to read the input file and write the output file. + * To reuse this code in another application, you might need to change these. + */ + +static FILE * infile; /* input JPEG file */ + +/* Return next input byte, or EOF if no more */ +#define NEXTBYTE() getc(infile) + +static FILE * outfile; /* output JPEG file */ + +/* Emit an output byte */ +#define PUTBYTE(x) putc((x), outfile) + + +/* Error exit handler */ +#define ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) + + +/* Read one byte, testing for EOF */ +static int +read_1_byte (void) +{ + int c; + + c = NEXTBYTE(); + if (c == EOF) + ERREXIT("Premature EOF in JPEG file"); + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static unsigned int +read_2_bytes (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + if (c1 == EOF) + ERREXIT("Premature EOF in JPEG file"); + c2 = NEXTBYTE(); + if (c2 == EOF) + ERREXIT("Premature EOF in JPEG file"); + return (((unsigned int) c1) << 8) + ((unsigned int) c2); +} + + +/* Routines to write data to output file */ + +static void +write_1_byte (int c) +{ + PUTBYTE(c); +} + +static void +write_2_bytes (unsigned int val) +{ + PUTBYTE((val >> 8) & 0xFF); + PUTBYTE(val & 0xFF); +} + +static void +write_marker (int marker) +{ + PUTBYTE(0xFF); + PUTBYTE(marker); +} + +static void +copy_rest_of_file (void) +{ + int c; + + while ((c = NEXTBYTE()) != EOF) + PUTBYTE(c); +} + + +/* + * JPEG markers consist of one or more 0xFF bytes, followed by a marker + * code byte (which is not an FF). Here are the marker codes of interest + * in this program. (See jdmarker.c for a more complete list.) + */ + +#define M_SOF0 0xC0 /* Start Of Frame N */ +#define M_SOF1 0xC1 /* N indicates which compression process */ +#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */ +#define M_EOI 0xD9 /* End Of Image (end of datastream) */ +#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ +#define M_COM 0xFE /* COMment */ + + +/* + * Find the next JPEG marker and return its marker code. + * We expect at least one FF byte, possibly more if the compressor used FFs + * to pad the file. (Padding FFs will NOT be replicated in the output file.) + * There could also be non-FF garbage between markers. The treatment of such + * garbage is unspecified; we choose to skip over it but emit a warning msg. + * NB: this routine must not be used after seeing SOS marker, since it will + * not deal correctly with FF/00 sequences in the compressed image data... + */ + +static int +next_marker (void) +{ + int c; + int discarded_bytes = 0; + + /* Find 0xFF byte; count and skip any non-FFs. */ + c = read_1_byte(); + while (c != 0xFF) { + discarded_bytes++; + c = read_1_byte(); + } + /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs + * are legal as pad bytes, so don't count them in discarded_bytes. + */ + do { + c = read_1_byte(); + } while (c == 0xFF); + + if (discarded_bytes != 0) { + fprintf(stderr, "Warning: garbage data found in JPEG file\n"); + } + + return c; +} + + +/* + * Read the initial marker, which should be SOI. + * For a JFIF file, the first two bytes of the file should be literally + * 0xFF M_SOI. To be more general, we could use next_marker, but if the + * input file weren't actually JPEG at all, next_marker might read the whole + * file and then return a misleading error message... + */ + +static int +first_marker (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + c2 = NEXTBYTE(); + if (c1 != 0xFF || c2 != M_SOI) + ERREXIT("Not a JPEG file"); + return c2; +} + + +/* + * Most types of marker are followed by a variable-length parameter segment. + * This routine skips over the parameters for any marker we don't otherwise + * want to process. + * Note that we MUST skip the parameter segment explicitly in order not to + * be fooled by 0xFF bytes that might appear within the parameter segment; + * such bytes do NOT introduce new markers. + */ + +static void +copy_variable (void) +/* Copy an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + write_2_bytes(length); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + write_1_byte(read_1_byte()); + length--; + } +} + +static void +skip_variable (void) +/* Skip over an unknown or uninteresting variable-length marker */ +{ + unsigned int length; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + if (length < 2) + ERREXIT("Erroneous JPEG marker length"); + length -= 2; + /* Skip over the remaining bytes */ + while (length > 0) { + (void) read_1_byte(); + length--; + } +} + + +/* + * Parse the marker stream until SOFn or EOI is seen; + * copy data to output, but discard COM markers unless keep_COM is true. + */ + +static int +scan_JPEG_header (int keep_COM) +{ + int marker; + + /* Expect SOI at start of file */ + if (first_marker() != M_SOI) + ERREXIT("Expected SOI marker first"); + write_marker(M_SOI); + + /* Scan miscellaneous markers until we reach SOFn. */ + for (;;) { + marker = next_marker(); + switch (marker) { + /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, + * treated as SOFn. C4 in particular is actually DHT. + */ + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + case M_SOF2: /* Progressive, Huffman */ + case M_SOF3: /* Lossless, Huffman */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_SOF9: /* Extended sequential, arithmetic */ + case M_SOF10: /* Progressive, arithmetic */ + case M_SOF11: /* Lossless, arithmetic */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ + return marker; + + case M_SOS: /* should not see compressed data before SOF */ + ERREXIT("SOS without prior SOFn"); + break; + + case M_EOI: /* in case it's a tables-only JPEG stream */ + return marker; + + case M_COM: /* Existing COM: conditionally discard */ + if (keep_COM) { + write_marker(marker); + copy_variable(); + } else { + skip_variable(); + } + break; + + default: /* Anything else just gets copied */ + write_marker(marker); + copy_variable(); /* we assume it has a parameter count... */ + break; + } + } /* end loop */ +} + + +/* Command line parsing code */ + +static const char * progname; /* program name for error messages */ + + +static void +usage (void) +/* complain about bad command line */ +{ + fprintf(stderr, "wrjpgcom inserts a textual comment in a JPEG file.\n"); + fprintf(stderr, "You can add to or replace any existing comment(s).\n"); + + fprintf(stderr, "Usage: %s [switches] ", progname); +#ifdef TWO_FILE_COMMANDLINE + fprintf(stderr, "inputfile outputfile\n"); +#else + fprintf(stderr, "[inputfile]\n"); +#endif + + fprintf(stderr, "Switches (names may be abbreviated):\n"); + fprintf(stderr, " -replace Delete any existing comments\n"); + fprintf(stderr, " -comment \"text\" Insert comment with given text\n"); + fprintf(stderr, " -cfile name Read comment from named file\n"); + fprintf(stderr, "Notice that you must put quotes around the comment text\n"); + fprintf(stderr, "when you use -comment.\n"); + fprintf(stderr, "If you do not give either -comment or -cfile on the command line,\n"); + fprintf(stderr, "then the comment text is read from standard input.\n"); + fprintf(stderr, "It can be multiple lines, up to %u characters total.\n", + (unsigned int) MAX_COM_LENGTH); +#ifndef TWO_FILE_COMMANDLINE + fprintf(stderr, "You must specify an input JPEG file name when supplying\n"); + fprintf(stderr, "comment text from standard input.\n"); +#endif + + exit(EXIT_FAILURE); +} + + +static int +keymatch (char * arg, const char * keyword, int minchars) +/* Case-insensitive matching of (possibly abbreviated) keyword switches. */ +/* keyword is the constant keyword (must be lower case already), */ +/* minchars is length of minimum legal abbreviation. */ +{ + register int ca, ck; + register int nmatched = 0; + + while ((ca = *arg++) != '\0') { + if ((ck = *keyword++) == '\0') + return 0; /* arg longer than keyword, no good */ + if (isupper(ca)) /* force arg to lcase (assume ck is already) */ + ca = tolower(ca); + if (ca != ck) + return 0; /* no good */ + nmatched++; /* count matched characters */ + } + /* reached end of argument; fail if it's too short for unique abbrev */ + if (nmatched < minchars) + return 0; + return 1; /* A-OK */ +} + + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + int argn; + char * arg; + int keep_COM = 1; + char * comment_arg = NULL; + FILE * comment_file = NULL; + unsigned int comment_length = 0; + int marker; + + /* On Mac, fetch a command line. */ +#ifdef USE_CCOMMAND + argc = ccommand(&argv); +#endif + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "wrjpgcom"; /* in case C library doesn't provide it */ + + /* Parse switches, if any */ + for (argn = 1; argn < argc; argn++) { + arg = argv[argn]; + if (arg[0] != '-') + break; /* not switch, must be file name */ + arg++; /* advance over '-' */ + if (keymatch(arg, "replace", 1)) { + keep_COM = 0; + } else if (keymatch(arg, "cfile", 2)) { + if (++argn >= argc) usage(); + if ((comment_file = fopen(argv[argn], "r")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else if (keymatch(arg, "comment", 1)) { + if (++argn >= argc) usage(); + comment_arg = argv[argn]; + /* If the comment text starts with '"', then we are probably running + * under MS-DOG and must parse out the quoted string ourselves. Sigh. + */ + if (comment_arg[0] == '"') { + comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); + if (comment_arg == NULL) + ERREXIT("Insufficient memory"); + strcpy(comment_arg, argv[argn]+1); + for (;;) { + comment_length = (unsigned int) strlen(comment_arg); + if (comment_length > 0 && comment_arg[comment_length-1] == '"') { + comment_arg[comment_length-1] = '\0'; /* zap terminating quote */ + break; + } + if (++argn >= argc) + ERREXIT("Missing ending quote mark"); + strcat(comment_arg, " "); + strcat(comment_arg, argv[argn]); + } + } + comment_length = (unsigned int) strlen(comment_arg); + } else + usage(); + } + + /* Cannot use both -comment and -cfile. */ + if (comment_arg != NULL && comment_file != NULL) + usage(); + /* If there is neither -comment nor -cfile, we will read the comment text + * from stdin; in this case there MUST be an input JPEG file name. + */ + if (comment_arg == NULL && comment_file == NULL && argn >= argc) + usage(); + + /* Open the input file. */ + if (argn < argc) { + if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); + exit(EXIT_FAILURE); + } + } else { + /* default input file is stdin */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdin), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdin\n", progname); + exit(EXIT_FAILURE); + } +#else + infile = stdin; +#endif + } + + /* Open the output file. */ +#ifdef TWO_FILE_COMMANDLINE + /* Must have explicit output file name */ + if (argn != argc-2) { + fprintf(stderr, "%s: must name one input and one output file\n", + progname); + usage(); + } + if ((outfile = fopen(argv[argn+1], WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[argn+1]); + exit(EXIT_FAILURE); + } +#else + /* Unix style: expect zero or one file name */ + if (argn < argc-1) { + fprintf(stderr, "%s: only one input file\n", progname); + usage(); + } + /* default output file is stdout */ +#ifdef USE_SETMODE /* need to hack file mode? */ + setmode(fileno(stdout), O_BINARY); +#endif +#ifdef USE_FDOPEN /* need to re-open in binary mode? */ + if ((outfile = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { + fprintf(stderr, "%s: can't open stdout\n", progname); + exit(EXIT_FAILURE); + } +#else + outfile = stdout; +#endif +#endif /* TWO_FILE_COMMANDLINE */ + + /* Collect comment text from comment_file or stdin, if necessary */ + if (comment_arg == NULL) { + FILE * src_file; + int c; + + comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); + if (comment_arg == NULL) + ERREXIT("Insufficient memory"); + comment_length = 0; + src_file = (comment_file != NULL ? comment_file : stdin); + while ((c = getc(src_file)) != EOF) { + if (comment_length >= (unsigned int) MAX_COM_LENGTH) { + fprintf(stderr, "Comment text may not exceed %u bytes\n", + (unsigned int) MAX_COM_LENGTH); + exit(EXIT_FAILURE); + } + comment_arg[comment_length++] = (char) c; + } + if (comment_file != NULL) + fclose(comment_file); + } + + /* Copy JPEG headers until SOFn marker; + * we will insert the new comment marker just before SOFn. + * This (a) causes the new comment to appear after, rather than before, + * existing comments; and (b) ensures that comments come after any JFIF + * or JFXX markers, as required by the JFIF specification. + */ + marker = scan_JPEG_header(keep_COM); + /* Insert the new COM marker, but only if nonempty text has been supplied */ + if (comment_length > 0) { + write_marker(M_COM); + write_2_bytes(comment_length + 2); + while (comment_length > 0) { + write_1_byte(*comment_arg++); + comment_length--; + } + } + /* Duplicate the remainder of the source file. + * Note that any COM markers occuring after SOF will not be touched. + */ + write_marker(marker); + copy_rest_of_file(); + + /* All done. */ + exit(EXIT_SUCCESS); + return 0; /* suppress no-return-value warnings */ +} diff --git a/src/dep/src/irrlicht/jpeglib/wrppm.c b/src/dep/src/irrlicht/jpeglib/wrppm.c new file mode 100644 index 0000000..cfd4160 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrppm.c @@ -0,0 +1,268 @@ +/* + * wrppm.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in PPM/PGM format. + * The extended 2-byte-per-sample raw PPM/PGM formats are supported. + * The PBMPLUS library is NOT required to compile this software + * (but it is highly useful as a set of PPM image manipulation programs). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef PPM_SUPPORTED + + +/* + * For 12-bit JPEG data, we either downscale the values to 8 bits + * (to write standard byte-per-sample PPM/PGM files), or output + * nonstandard word-per-sample PPM/PGM files. Downscaling is done + * if PPM_NORAWWORD is defined (this can be done in the Makefile + * or in jconfig.h). + * (When the core library supports data precision reduction, a cleaner + * implementation will be to ask for that instead.) + */ + +#if BITS_IN_JSAMPLE == 8 +#define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) (v) +#define BYTESPERSAMPLE 1 +#define PPM_MAXVAL 255 +#else +#ifdef PPM_NORAWWORD +#define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) ((v) >> (BITS_IN_JSAMPLE-8)) +#define BYTESPERSAMPLE 1 +#define PPM_MAXVAL 255 +#else +/* The word-per-sample format always puts the LSB first. */ +#define PUTPPMSAMPLE(ptr,v) \ + { register int val_ = v; \ + *ptr++ = (char) (val_ & 0xFF); \ + *ptr++ = (char) ((val_ >> 8) & 0xFF); \ + } +#define BYTESPERSAMPLE 2 +#define PPM_MAXVAL ((1<pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * This code is used when we have to copy the data and apply a pixel + * format translation. Typically this only happens in 12-bit mode. + */ + +METHODDEF(void) +copy_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register JSAMPROW ptr; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = dest->samples_per_row; col > 0; col--) { + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++)); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Write some pixel data when color quantization is in effect. + * We have to demap the color index values to straight data. + */ + +METHODDEF(void) +put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register int pixval; + register JSAMPROW ptr; + register JSAMPROW color_map0 = cinfo->colormap[0]; + register JSAMPROW color_map1 = cinfo->colormap[1]; + register JSAMPROW color_map2 = cinfo->colormap[2]; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + pixval = GETJSAMPLE(*ptr++); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval])); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval])); + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval])); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +METHODDEF(void) +put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + register char * bufferptr; + register JSAMPROW ptr; + register JSAMPROW color_map = cinfo->colormap[0]; + register JDIMENSION col; + + ptr = dest->pub.buffer[0]; + bufferptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)])); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; + + /* Emit file header */ + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + /* emit header for raw PGM format */ + fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n", + (long) cinfo->output_width, (long) cinfo->output_height, + PPM_MAXVAL); + break; + case JCS_RGB: + /* emit header for raw PPM format */ + fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n", + (long) cinfo->output_width, (long) cinfo->output_height, + PPM_MAXVAL); + break; + default: + ERREXIT(cinfo, JERR_PPM_COLORSPACE); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* Make sure we wrote the output file OK */ + fflush(dinfo->output_file); + if (ferror(dinfo->output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for PPM format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_ppm (j_decompress_ptr cinfo) +{ + ppm_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (ppm_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(ppm_dest_struct)); + dest->pub.start_output = start_output_ppm; + dest->pub.finish_output = finish_output_ppm; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Create physical I/O buffer. Note we make this near on a PC. */ + dest->samples_per_row = cinfo->output_width * cinfo->out_color_components; + dest->buffer_width = dest->samples_per_row * (BYTESPERSAMPLE * SIZEOF(char)); + dest->iobuffer = (char *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width); + + if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 || + SIZEOF(JSAMPLE) != SIZEOF(char)) { + /* When quantizing, we need an output buffer for colormap indexes + * that's separate from the physical I/O buffer. We also need a + * separate buffer if pixel format translation must take place. + */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width * cinfo->output_components, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + if (! cinfo->quantize_colors) + dest->pub.put_pixel_rows = copy_pixel_rows; + else if (cinfo->out_color_space == JCS_GRAYSCALE) + dest->pub.put_pixel_rows = put_demapped_gray; + else + dest->pub.put_pixel_rows = put_demapped_rgb; + } else { + /* We will fwrite() directly from decompressor output buffer. */ + /* Synthesize a JSAMPARRAY pointer structure */ + /* Cast here implies near->far pointer conversion on PCs */ + dest->pixrow = (JSAMPROW) dest->iobuffer; + dest->pub.buffer = & dest->pixrow; + dest->pub.buffer_height = 1; + dest->pub.put_pixel_rows = put_pixel_rows; + } + + return (djpeg_dest_ptr) dest; +} + +#endif /* PPM_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/wrrle.c b/src/dep/src/irrlicht/jpeglib/wrrle.c new file mode 100644 index 0000000..7a00c0d --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrrle.c @@ -0,0 +1,305 @@ +/* + * wrrle.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in RLE format. + * The Utah Raster Toolkit library is required (version 3.1 or later). + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * Based on code contributed by Mike Lijewski, + * with updates from Robert Hutchinson. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef RLE_SUPPORTED + +/* rle.h is provided by the Utah Raster Toolkit. */ + +#include + +/* + * We assume that JSAMPLE has the same representation as rle_pixel, + * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + + +/* + * Since RLE stores scanlines bottom-to-top, we have to invert the image + * from JPEG's top-to-bottom order. To do this, we save the outgoing data + * in a virtual array during put_pixel_row calls, then actually emit the + * RLE file during finish_output. + */ + + +/* + * For now, if we emit an RLE color map then it is always 256 entries long, + * though not all of the entries need be used. + */ + +#define CMAPBITS 8 +#define CMAPLENGTH (1<<(CMAPBITS)) + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + jvirt_sarray_ptr image; /* virtual array to store the output image */ + rle_map *colormap; /* RLE-style color map, or NULL if none */ + rle_pixel **rle_row; /* To pass rows to rle_putrow() */ + +} rle_dest_struct; + +typedef rle_dest_struct * rle_dest_ptr; + +/* Forward declarations */ +METHODDEF(void) rle_put_pixel_rows + JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied)); + + +/* + * Write the file header. + * + * In this module it's easier to wait till finish_output to write anything. + */ + +METHODDEF(void) +start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + size_t cmapsize; + int i, ci; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* + * Make sure the image can be stored in RLE format. + * + * - RLE stores image dimensions as *signed* 16 bit integers. JPEG + * uses unsigned, so we have to check the width. + * + * - Colorspace is expected to be grayscale or RGB. + * + * - The number of channels (components) is expected to be 1 (grayscale/ + * pseudocolor) or 3 (truecolor/directcolor). + * (could be 2 or 4 if using an alpha channel, but we aren't) + */ + + if (cinfo->output_width > 32767 || cinfo->output_height > 32767) + ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width, + cinfo->output_height); + + if (cinfo->out_color_space != JCS_GRAYSCALE && + cinfo->out_color_space != JCS_RGB) + ERREXIT(cinfo, JERR_RLE_COLORSPACE); + + if (cinfo->output_components != 1 && cinfo->output_components != 3) + ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components); + + /* Convert colormap, if any, to RLE format. */ + + dest->colormap = NULL; + + if (cinfo->quantize_colors) { + /* Allocate storage for RLE-style cmap, zero any extra entries */ + cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map); + dest->colormap = (rle_map *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize); + MEMZERO(dest->colormap, cmapsize); + + /* Save away data in RLE format --- note 8-bit left shift! */ + /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */ + for (ci = 0; ci < cinfo->out_color_components; ci++) { + for (i = 0; i < cinfo->actual_number_of_colors; i++) { + dest->colormap[ci * CMAPLENGTH + i] = + GETJSAMPLE(cinfo->colormap[ci][i]) << 8; + } + } + } + + /* Set the output buffer to the first row */ + dest->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE); + dest->pub.buffer_height = 1; + + dest->pub.put_pixel_rows = rle_put_pixel_rows; + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->total_extra_passes++; /* count file writing as separate pass */ + } +#endif +} + + +/* + * Write some pixel data. + * + * This routine just saves the data away in a virtual array. + */ + +METHODDEF(void) +rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + + if (cinfo->output_scanline < cinfo->output_height) { + dest->pub.buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + cinfo->output_scanline, (JDIMENSION) 1, TRUE); + } +} + +/* + * Finish up at the end of the file. + * + * Here is where we really output the RLE file. + */ + +METHODDEF(void) +finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + rle_dest_ptr dest = (rle_dest_ptr) dinfo; + rle_hdr header; /* Output file information */ + rle_pixel **rle_row, *red, *green, *blue; + JSAMPROW output_row; + char cmapcomment[80]; + int row, col; + int ci; +#ifdef PROGRESS_REPORT + cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; +#endif + + /* Initialize the header info */ + header = *rle_hdr_init(NULL); + header.rle_file = dest->pub.output_file; + header.xmin = 0; + header.xmax = cinfo->output_width - 1; + header.ymin = 0; + header.ymax = cinfo->output_height - 1; + header.alpha = 0; + header.ncolors = cinfo->output_components; + for (ci = 0; ci < cinfo->output_components; ci++) { + RLE_SET_BIT(header, ci); + } + if (cinfo->quantize_colors) { + header.ncmap = cinfo->out_color_components; + header.cmaplen = CMAPBITS; + header.cmap = dest->colormap; + /* Add a comment to the output image with the true colormap length. */ + sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors); + rle_putcom(cmapcomment, &header); + } + + /* Emit the RLE header and color map (if any) */ + rle_put_setup(&header); + + /* Now output the RLE data from our virtual array. + * We assume here that (a) rle_pixel is represented the same as JSAMPLE, + * and (b) we are not on a machine where FAR pointers differ from regular. + */ + +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_limit = cinfo->output_height; + progress->pub.pass_counter = 0; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + + if (cinfo->output_components == 1) { + for (row = cinfo->output_height-1; row >= 0; row--) { + rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + (JDIMENSION) row, (JDIMENSION) 1, FALSE); + rle_putrow(rle_row, (int) cinfo->output_width, &header); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } else { + for (row = cinfo->output_height-1; row >= 0; row--) { + rle_row = (rle_pixel **) dest->rle_row; + output_row = * (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, dest->image, + (JDIMENSION) row, (JDIMENSION) 1, FALSE); + red = rle_row[0]; + green = rle_row[1]; + blue = rle_row[2]; + for (col = cinfo->output_width; col > 0; col--) { + *red++ = GETJSAMPLE(*output_row++); + *green++ = GETJSAMPLE(*output_row++); + *blue++ = GETJSAMPLE(*output_row++); + } + rle_putrow(rle_row, (int) cinfo->output_width, &header); +#ifdef PROGRESS_REPORT + if (progress != NULL) { + progress->pub.pass_counter++; + (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); + } +#endif + } + } + +#ifdef PROGRESS_REPORT + if (progress != NULL) + progress->completed_extra_passes++; +#endif + + /* Emit file trailer */ + rle_puteof(&header); + fflush(dest->pub.output_file); + if (ferror(dest->pub.output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for RLE format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_rle (j_decompress_ptr cinfo) +{ + rle_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (rle_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(rle_dest_struct)); + dest->pub.start_output = start_output_rle; + dest->pub.finish_output = finish_output_rle; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Allocate a work array for output to the RLE library. */ + dest->rle_row = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->output_width, (JDIMENSION) cinfo->output_components); + + /* Allocate a virtual array to hold the image. */ + dest->image = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) (cinfo->output_width * cinfo->output_components), + cinfo->output_height, (JDIMENSION) 1); + + return (djpeg_dest_ptr) dest; +} + +#endif /* RLE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/jpeglib/wrtarga.c b/src/dep/src/irrlicht/jpeglib/wrtarga.c new file mode 100644 index 0000000..6566273 --- /dev/null +++ b/src/dep/src/irrlicht/jpeglib/wrtarga.c @@ -0,0 +1,253 @@ +/* + * wrtarga.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains routines to write output images in Targa format. + * + * These routines may need modification for non-Unix environments or + * specialized applications. As they stand, they assume output to + * an ordinary stdio stream. + * + * Based on code contributed by Lee Daniel Crocker. + */ + +#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ + +#ifdef TARGA_SUPPORTED + + +/* + * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. + * This is not yet implemented. + */ + +#if BITS_IN_JSAMPLE != 8 + Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ +#endif + +/* + * The output buffer needs to be writable by fwrite(). On PCs, we must + * allocate the buffer in near data space, because we are assuming small-data + * memory model, wherein fwrite() can't reach far memory. If you need to + * process very wide images on a PC, you might have to compile in large-memory + * model, or else replace fwrite() with a putc() loop --- which will be much + * slower. + */ + + +/* Private version of data destination object */ + +typedef struct { + struct djpeg_dest_struct pub; /* public fields */ + + char *iobuffer; /* physical I/O buffer */ + JDIMENSION buffer_width; /* width of one row */ +} tga_dest_struct; + +typedef tga_dest_struct * tga_dest_ptr; + + +LOCAL(void) +write_header (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, int num_colors) +/* Create and write a Targa header */ +{ + char targaheader[18]; + + /* Set unused fields of header to 0 */ + MEMZERO(targaheader, SIZEOF(targaheader)); + + if (num_colors > 0) { + targaheader[1] = 1; /* color map type 1 */ + targaheader[5] = (char) (num_colors & 0xFF); + targaheader[6] = (char) (num_colors >> 8); + targaheader[7] = 24; /* 24 bits per cmap entry */ + } + + targaheader[12] = (char) (cinfo->output_width & 0xFF); + targaheader[13] = (char) (cinfo->output_width >> 8); + targaheader[14] = (char) (cinfo->output_height & 0xFF); + targaheader[15] = (char) (cinfo->output_height >> 8); + targaheader[17] = 0x20; /* Top-down, non-interlaced */ + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + targaheader[2] = 3; /* image type = uncompressed gray-scale */ + targaheader[16] = 8; /* bits per pixel */ + } else { /* must be RGB */ + if (num_colors > 0) { + targaheader[2] = 1; /* image type = colormapped RGB */ + targaheader[16] = 8; + } else { + targaheader[2] = 2; /* image type = uncompressed RGB */ + targaheader[16] = 24; + } + } + + if (JFWRITE(dinfo->output_file, targaheader, 18) != (size_t) 18) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * Write some pixel data. + * In this module rows_supplied will always be 1. + */ + +METHODDEF(void) +put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* used for unquantized full-color output */ +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + outptr[0] = (char) GETJSAMPLE(inptr[2]); /* RGB to BGR order */ + outptr[1] = (char) GETJSAMPLE(inptr[1]); + outptr[2] = (char) GETJSAMPLE(inptr[0]); + inptr += 3, outptr += 3; + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + +METHODDEF(void) +put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +/* used for grayscale OR quantized color output */ +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = (char) GETJSAMPLE(*inptr++); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Write some demapped pixel data when color quantization is in effect. + * For Targa, this is only applied to grayscale data. + */ + +METHODDEF(void) +put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied) +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + register JSAMPROW inptr; + register char * outptr; + register JSAMPROW color_map0 = cinfo->colormap[0]; + register JDIMENSION col; + + inptr = dest->pub.buffer[0]; + outptr = dest->iobuffer; + for (col = cinfo->output_width; col > 0; col--) { + *outptr++ = (char) GETJSAMPLE(color_map0[GETJSAMPLE(*inptr++)]); + } + (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); +} + + +/* + * Startup: write the file header. + */ + +METHODDEF(void) +start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + tga_dest_ptr dest = (tga_dest_ptr) dinfo; + int num_colors, i; + FILE *outfile; + + if (cinfo->out_color_space == JCS_GRAYSCALE) { + /* Targa doesn't have a mapped grayscale format, so we will */ + /* demap quantized gray output. Never emit a colormap. */ + write_header(cinfo, dinfo, 0); + if (cinfo->quantize_colors) + dest->pub.put_pixel_rows = put_demapped_gray; + else + dest->pub.put_pixel_rows = put_gray_rows; + } else if (cinfo->out_color_space == JCS_RGB) { + if (cinfo->quantize_colors) { + /* We only support 8-bit colormap indexes, so only 256 colors */ + num_colors = cinfo->actual_number_of_colors; + if (num_colors > 256) + ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, num_colors); + write_header(cinfo, dinfo, num_colors); + /* Write the colormap. Note Targa uses BGR byte order */ + outfile = dest->pub.output_file; + for (i = 0; i < num_colors; i++) { + putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile); + putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile); + putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile); + } + dest->pub.put_pixel_rows = put_gray_rows; + } else { + write_header(cinfo, dinfo, 0); + dest->pub.put_pixel_rows = put_pixel_rows; + } + } else { + ERREXIT(cinfo, JERR_TGA_COLORSPACE); + } +} + + +/* + * Finish up at the end of the file. + */ + +METHODDEF(void) +finish_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) +{ + /* Make sure we wrote the output file OK */ + fflush(dinfo->output_file); + if (ferror(dinfo->output_file)) + ERREXIT(cinfo, JERR_FILE_WRITE); +} + + +/* + * The module selection routine for Targa format output. + */ + +GLOBAL(djpeg_dest_ptr) +jinit_write_targa (j_decompress_ptr cinfo) +{ + tga_dest_ptr dest; + + /* Create module interface object, fill in method pointers */ + dest = (tga_dest_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(tga_dest_struct)); + dest->pub.start_output = start_output_tga; + dest->pub.finish_output = finish_output_tga; + + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfo); + + /* Create I/O buffer. Note we make this near on a PC. */ + dest->buffer_width = cinfo->output_width * cinfo->output_components; + dest->iobuffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + (size_t) (dest->buffer_width * SIZEOF(char))); + + /* Create decompressor output buffer. */ + dest->pub.buffer = (*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1); + dest->pub.buffer_height = 1; + + return (djpeg_dest_ptr) dest; +} + +#endif /* TARGA_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/ANNOUNCE b/src/dep/src/irrlicht/libpng/ANNOUNCE new file mode 100644 index 0000000..561a5e2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/ANNOUNCE @@ -0,0 +1,49 @@ + +Libpng 1.2.18 - May 15, 2007 + +This is a public release of libpng, intended for use in production codes. + +Files available for download: + +Source files with LF line endings (for Unix/Linux) and with a +"configure" script + + libpng-1.2.18.tar.gz + libpng-1.2.18.tar.bz2 + +Source files with LF line endings (for Unix/Linux) without the +"configure" script + + libpng-1.2.18-no-config.tar.gz + libpng-1.2.18-no-config.tar.bz2 + +Source files with CRLF line endings (for Windows), without the +"configure" script + + lpng1218.zip + lpng1218.tar.bz2 + +Project files + + libpng-1.2.18-project-netware.zip + libpng-1.2.18-project-wince.zip + +Other information: + + libpng-1.2.18-README.txt + libpng-1.2.18-KNOWNBUGS.txt + libpng-1.2.18-LICENSE.txt + libpng-1.2.18-Y2K-compliance.txt + +Changes since the last public release (1.2.17): + +version 1.2.18 [May 15, 2007] + + Reverted the recent change to symbol-handling in configure script + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +Glenn R-P diff --git a/src/dep/src/irrlicht/libpng/CHANGES b/src/dep/src/irrlicht/libpng/CHANGES new file mode 100644 index 0000000..e3f4f68 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/CHANGES @@ -0,0 +1,1738 @@ + +CHANGES - changes for libpng + +version 0.2 + added reader into png.h + fixed small problems in stub file + +version 0.3 + added pull reader + split up pngwrite.c to several files + added pnglib.txt + added example.c + cleaned up writer, adding a few new transformations + fixed some bugs in writer + interfaced with zlib 0.5 + added K&R support + added check for 64 KB blocks for 16 bit machines + +version 0.4 + cleaned up code and commented code + simplified time handling into png_time + created png_color_16 and png_color_8 to handle color needs + cleaned up color type defines + fixed various bugs + made various names more consistent + interfaced with zlib 0.71 + cleaned up zTXt reader and writer (using zlib's Reset functions) + split transformations into pngrtran.c and pngwtran.c + +version 0.5 + interfaced with zlib 0.8 + fixed many reading and writing bugs + saved using 3 spaces instead of tabs + +version 0.6 + added png_large_malloc() and png_large_free() + added png_size_t + cleaned up some compiler warnings + added png_start_read_image() + +version 0.7 + cleaned up lots of bugs + finished dithering and other stuff + added test program + changed name from pnglib to libpng + +version 0.71 [June, 1995] + changed pngtest.png for zlib 0.93 + fixed error in libpng.txt and example.c + +version 0.8 + cleaned up some bugs + added png_set_filler() + split up pngstub.c into pngmem.c, pngio.c, and pngerror.c + added #define's to remove unwanted code + moved png_info_init() to png.c + added old_size into png_realloc() + added functions to manually set filtering and compression info + changed compression parameters based on image type + optimized filter selection code + added version info + changed external functions passing floats to doubles (k&r problems?) + put all the configurable stuff in pngconf.h + enabled png_set_shift to work with paletted images on read + added png_read_update_info() - updates info structure with + transformations + +version 0.81 [August, 1995] + incorporated Tim Wegner's medium model code (thanks, Tim) + +version 0.82 [September, 1995] + [unspecified changes] + +version 0.85 [December, 1995] + added more medium model code (almost everything's a far) + added i/o, error, and memory callback functions + fixed some bugs (16 bit, 4 bit interlaced, etc.) + added first run progressive reader (barely tested) + +version 0.86 [January, 1996] + fixed bugs + improved documentation + +version 0.87 [January, 1996] + fixed medium model bugs + fixed other bugs introduced in 0.85 and 0.86 + added some minor documentation + +version 0.88 [January, 1996] + fixed progressive bugs + replaced tabs with spaces + cleaned up documentation + added callbacks for read/write and warning/error functions + +version 0.89 [July, 1996] + added new initialization API to make libpng work better with shared libs + we now have png_create_read_struct(), png_create_write_struct(), + png_create_info_struct(), png_destroy_read_struct(), and + png_destroy_write_struct() instead of the separate calls to + malloc and png_read_init(), png_info_init(), and png_write_init() + changed warning/error callback functions to fix bug - this means you + should use the new initialization API if you were using the old + png_set_message_fn() calls, and that the old API no longer exists + so that people are aware that they need to change their code + changed filter selection API to allow selection of multiple filters + since it didn't work in previous versions of libpng anyways + optimized filter selection code + fixed png_set_background() to allow using an arbitrary RGB color for + paletted images + fixed gamma and background correction for paletted images, so + png_correct_palette is not needed unless you are correcting an + external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED + in pngconf.h) - if nobody uses this, it may disappear in the future. + fixed bug with Borland 64K memory allocation (Alexander Lehmann) + fixed bug in interlace handling (Smarasderagd, I think) + added more error checking for writing and image to reduce invalid files + separated read and write functions so that they won't both be linked + into a binary when only reading or writing functionality is used + new pngtest image also has interlacing and zTXt + updated documentation to reflect new API + +version 0.90 [January, 1997] + made CRC errors/warnings on critical and ancillary chunks configurable + libpng will use the zlib CRC routines by (compile-time) default + changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) + added external C++ wrapper statements to png.h (Gilles Dauphin) + allow PNG file to be read when some or all of file signature has already + been read from the beginning of the stream. ****This affects the size + of info_struct and invalidates all programs that use a shared libpng**** + fixed png_filler() declarations + fixed? background color conversions + fixed order of error function pointers to match documentation + current chunk name is now available in png_struct to reduce the number + of nearly identical error messages (will simplify multi-lingual + support when available) + try to get ready for unknown-chunk callback functions: + - previously read critical chunks are flagged, so the chunk handling + routines can determine if the chunk is in the right place + - all chunk handling routines have the same prototypes, so we will + be able to handle all chunks via a callback mechanism + try to fix Linux "setjmp" buffer size problems + removed png_large_malloc, png_large_free, and png_realloc functions. + +version 0.95 [March, 1997] + fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never + fixed bug in PNG file signature compares when start != 0 + changed parameter type of png_set_filler(...filler...) from png_byte + to png_uint_32 + added test for MACOS to ensure that both math.h and fp.h are not #included + added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) + added "packswap" transformation, which changes the endianness of + packed-pixel bytes (Kevin Bracey) + added "strip_alpha" transformation, which removes the alpha channel of + input images without using it (not necessarily a good idea) + added "swap_alpha" transformation, which puts the alpha channel in front + of the color bytes instead of after + removed all implicit variable tests which assume NULL == 0 (I think) + changed several variables to "png_size_t" to show 16/32-bit limitations + added new pCAL chunk read/write support + added experimental filter selection weighting (Greg Roelofs) + removed old png_set_rgbx() and png_set_xrgb() functions that have been + obsolete for about 2 years now (use png_set_filler() instead) + added macros to read 16- and 32-bit ints directly from buffer, to be + used only on those systems that support it (namely PowerPC and 680x0) + With some testing, this may become the default for MACOS/PPC systems. + only calculate CRC on data if we are going to use it + added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? + added macros for simple libpng debugging output selectable at compile time + removed PNG_READ_END_MODE in progressive reader (Smarasderagd) + more description of info_struct in libpng.txt and png.h + more instructions in example.c + more chunk types tested in pngtest.c + renamed pngrcb.c to pngset.c, and all png_read_ functions to be + png_set_. We now have corresponding png_get_ + functions in pngget.c to get information in info_ptr. This isolates + the application from the internal organization of png_info_struct + (good for shared library implementations). + +version 0.96 [May, 1997] + fixed serious bug with < 8bpp images introduced in 0.95 + fixed 256-color transparency bug (Greg Roelofs) + fixed up documentation (Greg Roelofs, Laszlo Nyul) + fixed "error" in pngconf.h for Linux setjmp() behaviour + fixed DOS medium model support (Tim Wegner) + fixed png_check_keyword() for case with error in static string text + added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) + added typecasts to quiet compiler errors + added more debugging info + +version 0.97 [January, 1998] + removed PNG_USE_OWN_CRC capability + relocated png_set_crc_action from pngrutil.c to pngrtran.c + fixed typecasts of "new_key", etc. (Andreas Dilger) + added RFC 1152 [sic] date support + fixed bug in gamma handling of 4-bit grayscale + added 2-bit grayscale gamma handling (Glenn R-P) + added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) + minor corrections in libpng.txt + added simple sRGB support (Glenn R-P) + easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; + all configurable options can be selected from command-line instead + of having to edit pngconf.h (Glenn R-P) + fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) + added more conditions for png_do_background, to avoid changing + black pixels to background when a background is supplied and + no pixels are transparent + repaired PNG_NO_STDIO behaviour + tested NODIV support and made it default behaviour (Greg Roelofs) + added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) + regularized version numbering scheme and bumped shared-library major + version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs) + +version 0.98 [January, 1998] + cleaned up some typos in libpng.txt and in code documentation + fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) + cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c + changed recommendation about file_gamma for PC images to .51 from .45, + in example.c and libpng.txt, added comments to distinguish between + screen_gamma, viewing_gamma, and display_gamma. + changed all references to RFC1152 to read RFC1123 and changed the + PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED + added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) + changed srgb_intent from png_byte to int to avoid compiler bugs + +version 0.99 [January 30, 1998] + free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) + fixed a longstanding "packswap" bug in pngtrans.c + fixed some inconsistencies in pngconf.h that prevented compiling with + PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined + fixed some typos and made other minor rearrangement of libpng.txt (Andreas) + changed recommendation about file_gamma for PC images to .50 from .51 in + example.c and libpng.txt, and changed file_gamma for sRGB images to .45 + added a number of functions to access information from the png structure + png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) + added TARGET_MACOS similar to zlib-1.0.8 + define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined + added type casting to all png_malloc() function calls +version 0.99a [January 31, 1998] + Added type casts and parentheses to all returns that return a value.(Tim W.) +version 0.99b [February 4, 1998] + Added type cast png_uint_32 on malloc function calls where needed. + Changed type of num_hist from png_uint_32 to int (same as num_palette). + Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. + Renamed makefile.elf to makefile.lnx. +version 0.99c [February 7, 1998] + More type casting. Removed erroneous overflow test in pngmem.c. + Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. + Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. +version 0.99d [February 11, 1998] + Renamed "far_to_near()" "png_far_to_near()" + Revised libpng.3 + Version 99c "buffered" operations didn't work as intended. Replaced them + with png_memcpy_check() and png_memset_check(). + Added many "if (png_ptr == NULL) return" to quell compiler warnings about + unused png_ptr, mostly in pngget.c and pngset.c. + Check for overlength tRNS chunk present when indexed-color PLTE is read. + Cleaned up spelling errors in libpng.3/libpng.txt + Corrected a problem with png_get_tRNS() which returned undefined trans array +version 0.99e [February 28, 1998] + Corrected png_get_tRNS() again. + Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". + Touched up example.c to make more of it compileable, although the entire + file still can't be compiled (Willem van Schaik) + Fixed a bug in png_do_shift() (Bryan Tsai) + Added a space in png.h prototype for png_write_chunk_start() + Replaced pngtest.png with one created with zlib 1.1.1 + Changed pngtest to report PASS even when file size is different (Jean-loup G.) + Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) +version 0.99f [March 5, 1998] + Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) + Moved makefiles into a "scripts" directory, and added INSTALL instruction file + Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) + Added pointers to "note on libpng versions" in makefile.lnx and README + Added row callback feature when reading and writing nonprogressive rows + and added a test of this feature in pngtest.c + Added user transform callbacks, with test of the feature in pngtest.c +version 0.99g [March 6, 1998, morning] + Minor changes to pngtest.c to suppress compiler warnings. + Removed "beta" language from documentation. +version 0.99h [March 6, 1998, evening] + Minor changes to previous minor changes to pngtest.c + Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED + and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro + Added user transform capability + +version 1.00 [March 7, 1998] + Changed several typedefs in pngrutil.c + Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) + replaced "while(1)" with "for(;;)" + added PNGARG() to prototypes in pngtest.c and removed some prototypes + updated some of the makefiles (Tom Lane) + changed some typedefs (s_start, etc.) in pngrutil.c + fixed dimensions of "short_months" array in pngwrite.c + Replaced ansi2knr.c with the one from jpeg-v6 + +version 1.0.0 [March 8, 1998] + Changed name from 1.00 to 1.0.0 (Adam Costello) + Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) +version 1.0.0a [March 9, 1998] + Fixed three bugs in pngrtran.c to make gamma+background handling consistent + (Greg Roelofs) + Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz + for major, minor, and bugfix releases. This is 10001. (Adam Costello, + Tom Lane) + Make months range from 1-12 in png_convert_to_rfc1123 +version 1.0.0b [March 13, 1998] + Quieted compiler complaints about two empty "for" loops in pngrutil.c + Minor changes to makefile.s2x + Removed #ifdef/#endif around a png_free() in pngread.c + +version 1.0.1 [March 14, 1998] + Changed makefile.s2x to reduce security risk of using a relative pathname + Fixed some typos in the documentation (Greg). + Fixed a problem with value of "channels" returned by png_read_update_info() +version 1.0.1a [April 21, 1998] + Optimized Paeth calculations by replacing abs() function calls with intrinsics + plus other loop optimizations. Improves avg decoding speed by about 20%. + Commented out i386istic "align" compiler flags in makefile.lnx. + Reduced the default warning level in some makefiles, to make them consistent. + Removed references to IJG and JPEG in the ansi2knr.c copyright statement. + Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. + Added grayscale and 16-bit capability to png_do_read_filler(). + Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes + too large when writing an image with bit_depth < 8 (Bob Dellaca). + Corrected some bugs in the experimental weighted filtering heuristics. + Moved a misplaced pngrutil code block that truncates tRNS if it has more + than num_palette entries -- test was done before num_palette was defined. + Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). + Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen). +version 1.0.1b [May 2, 1998] + Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). + Relocated the png_composite macros from pngrtran.c to png.h (Greg). + Added makefile.sco (contributed by Mike Hopkirk). + Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. + Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. + More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert). + More work on loop optimization which may help when compiled with C++ compilers. + Added warnings when people try to use transforms they've defined out. + Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. + Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) +version 1.0.1c [May 11, 1998] + Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for + filler bytes should have been 0xff instead of 0xf. + Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. + Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED + out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h + Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, + for consistency, in pngconf.h + Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier + to remove unwanted capabilities via the compile line + Made some corrections to grammar (which, it's) in documentation (Greg). + Corrected example.c, use of row_pointers in png_write_image(). +version 1.0.1d [May 24, 1998] + Corrected several statements that used side effects illegally in pngrutil.c + and pngtrans.c, that were introduced in version 1.0.1b + Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) + More corrections to example.c, use of row_pointers in png_write_image() + and png_read_rows(). + Added pngdll.mak and pngdef.pas to scripts directory, contributed by + Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 + Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) + Changed several loops from count-down to count-up, for consistency. +version 1.0.1e [June 6, 1998] + Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and + added warnings when people try to set png_read_fn and png_write_fn in + the same structure. + Added a test such that png_do_gamma will be done when num_trans==0 + for truecolor images that have defined a background. This corrects an + error that was introduced in libpng-0.90 that can cause gamma processing + to be skipped. + Added tests in png.h to include "trans" and "trans_values" in structures + when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. + Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() + Moved png_convert_to_rfc_1123() from pngwrite.c to png.c + Added capability for user-provided malloc_fn() and free_fn() functions, + and revised pngtest.c to demonstrate their use, replacing the + PNGTEST_DEBUG_MEM feature. + Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). + +version 1.0.2 [June 14, 1998] + Fixed two bugs in makefile.bor . +version 1.0.2a [December 30, 1998] + Replaced and extended code that was removed from png_set_filler() in 1.0.1a. + Fixed a bug in png_do_filler() that made it fail to write filler bytes in + the left-most pixel of each row (Kevin Bracey). + Changed "static pngcharp tIME_string" to "static char tIME_string[30]" + in pngtest.c (Duncan Simpson). + Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk + even when no tIME chunk was present in the source file. + Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. + Fixed a problem in png_read_push_finish_row(), which would not skip some + passes that it should skip, for images that are less than 3 pixels high. + Interchanged the order of calls to png_do_swap() and png_do_shift() + in pngwtran.c (John Cromer). + Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . + Changed "bad adaptive filter type" from error to warning in pngrutil.c . + Fixed a documentation error about default filtering with 8-bit indexed-color. + Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO + (L. Peter Deutsch). + Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. + Added png_get_copyright() and png_get_header_version() functions. + Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c + Added information about debugging in libpng.txt and libpng.3 . + Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco. + Removed lines after Dynamic Dependencies" in makefile.aco . + Revised makefile.dec to make a shared library (Jeremie Petit). + Removed trailing blanks from all files. +version 1.0.2a [January 6, 1999] + Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h + Added "if" tests to silence complaints about unused png_ptr in png.h and png.c + Changed "check_if_png" function in example.c to return true (nonzero) if PNG. + Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() + which is obsolete. + +version 1.0.3 [January 14, 1999] + Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) + Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. +version 1.0.3a [August 12, 1999] + Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning + if an attempt is made to read an interlaced image when it's not supported. + Added check if png_ptr->trans is defined before freeing it in pngread.c + Modified the Y2K statement to include versions back to version 0.71 + Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c + Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) + Replaced leading blanks with tab characters in makefile.hux + Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. + Changed (float)red and (float)green to (double)red, (double)green + in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. + Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). + Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). + Updated documentation to refer to the PNG-1.2 specification. + Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c + in makefile.knr, INSTALL, and README (L. Peter Deutsch) + Fixed bugs in calculation of the length of rowbytes when adding alpha + channels to 16-bit images, in pngrtran.c (Chris Nokleberg) + Added function png_set_user_transform_info() to store user_transform_ptr, + user_depth, and user_channels into the png_struct, and a function + png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) + Added function png_set_empty_plte_permitted() to make libpng useable + in MNG applications. + Corrected the typedef for png_free_ptr in png.h (Jesse Jones). + Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be + consistent with PNG-1.2, and allow variance of 500 before complaining. + Added assembler code contributed by Intel in file pngvcrd.c and modified + makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant) + Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. + Added some aliases for png_set_expand() in pngrtran.c, namely + png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() + (Greg Roelofs, in "PNG: The Definitive Guide"). + Added makefile.beo for BEOS on X86, contributed by Sander Stok. +version 1.0.3b [August 26, 1999] + Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h + Changed leading blanks to tabs in all makefiles. + Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. + Made alternate versions of png_set_expand() in pngrtran.c, namely + png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha + (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. + Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h + Revised calculation of num_blocks in pngmem.c to avoid a potentially + negative shift distance, whose results are undefined in the C language. + Added a check in pngset.c to prevent writing multiple tIME chunks. + Added a check in pngwrite.c to detect invalid small window_bits sizes. +version 1.0.3d [September 4, 1999] + Fixed type casting of igamma in pngrutil.c + Added new png_expand functions to scripts/pngdef.pas and pngos2.def + Added a demo read_user_transform_fn that examines the row filters in pngtest.c + +version 1.0.4 [September 24, 1999] + Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined + Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h + Made several minor corrections to pngtest.c + Renamed the makefiles with longer but more user friendly extensions. + Copied the PNG copyright and license to a separate LICENSE file. + Revised documentation, png.h, and example.c to remove reference to + "viewing_gamma" which no longer appears in the PNG specification. + Revised pngvcrd.c to use MMX code for interlacing only on the final pass. + Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a + Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX + assembler code) and makefile.vcwin32 (doesn't). + Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) + Added a copy of pngnow.png to the distribution. +version 1.0.4a [September 25, 1999] + Increase max_pixel_depth in pngrutil.c if a user transform needs it. + Changed several division operations to right-shifts in pngvcrd.c +version 1.0.4b [September 30, 1999] + Added parentheses in line 3732 of pngvcrd.c + Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 +version 1.0.4c [October 1, 1999] + Added a "png_check_version" function in png.c and pngtest.c that will generate + a helpful compiler error if an old png.h is found in the search path. + Changed type of png_user_transform_depth|channels from int to png_byte. +version 1.0.4d [October 6, 1999] + Changed 0.45 to 0.45455 in png_set_sRGB() + Removed unused PLTE entries from pngnow.png + Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. +version 1.0.4e [October 10, 1999] + Fixed sign error in pngvcrd.c (Greg Roelofs) + Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) +version 1.0.4f [October 15, 1999] + Surrounded example.c code with #if 0 .. #endif to prevent people from + inadvertently trying to compile it. + Changed png_get_header_version() from a function to a macro in png.h + Added type casting mostly in pngrtran.c and pngwtran.c + Removed some pointless "ptr = NULL" in pngmem.c + Added a "contrib" directory containing the source code from Greg's book. + +version 1.0.5 [October 15, 1999] + Minor editing of the INSTALL and README files. +version 1.0.5a [October 23, 1999] + Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) + Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) + Further optimization and bugfix of pngvcrd.c + Revised pngset.c so that it does not allocate or free memory in the user's + text_ptr structure. Instead, it makes its own copy. + Created separate write_end_info_struct in pngtest.c for a more severe test. + Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. +version 1.0.5b [November 23, 1999] + Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and + PNG_FLAG_WROTE_tIME from flags to mode. + Added png_write_info_before_PLTE() function. + Fixed some typecasting in contrib/gregbook/*.c + Updated scripts/makevms.com and added makevms.com to contrib/gregbook + and contrib/pngminus (Martin Zinser) +version 1.0.5c [November 26, 1999] + Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr. + Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to + accommodate making DLL's: Moved usr_png_ver from global variable to function + png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and + eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays + into pngtypes.h. Eliminated use of global png_pass arrays. Declared the + png_CHNK and png_pass arrays to be "const". Made the global arrays + available to applications (although none are used in libpng itself) when + PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. + Removed some extraneous "-I" from contrib/pngminus/makefile.std + Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. + Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 +version 1.0.5d [November 29, 1999] + Add type cast (png_const_charp) two places in png.c + Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. + Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available + to applications a macro "PNG_USE_LOCAL_ARRAYS". + #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined. + Added PNG_EXPORT_VAR macro to accommodate making DLL's. +version 1.0.5e [November 30, 1999] + Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text + structure; refactored the inflate/deflate support to make adding new chunks + 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_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). + 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 + write tEXt or zTXt chunks. If you want your application to be able to + run with older versions of libpng, use + + #ifdef PNG_iTXt_SUPPORTED + png_text[i].lang = NULL; + #endif + + Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned + offsets (Eric S. Raymond). + Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into + PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED + macros, leaving the separate macros also available. + Removed comments on #endifs at the end of many short, non-nested #if-blocks. +version 1.0.5f [December 6, 1999] + Changed makefile.solaris to issue a warning about potential problems when + the ucb "ld" is in the path ahead of the ccs "ld". + Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. + Added sCAL chunk support (Eric S. Raymond). +version 1.0.5g [December 7, 1999] + Fixed "png_free_spallettes" typo in png.h + Added code to handle new chunks in pngpread.c + Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block + Added "translated_key" to png_text structure and png_write_iTXt(). + Added code in pngwrite.c to work around a newly discovered zlib bug. +version 1.0.5h [December 10, 1999] + NOTE: regarding the note for version 1.0.5e, the following must also + be included in your code: + png_text[i].translated_key = NULL; + Unknown chunk handling is now supported. + Option to eliminate all floating point support was added. Some new + fixed-point functions such as png_set_gAMA_fixed() were added. + Expanded tabs and removed trailing blanks in source files. +version 1.0.5i [December 13, 1999] + Added some type casts to silence compiler warnings. + Renamed "png_free_spalette" to "png_free_spalettes" for consistency. + Removed leading blanks from a #define in pngvcrd.c + Added some parameters to the new png_set_keep_unknown_chunks() function. + Added a test for up->location != 0 in the first instance of writing + unknown chunks in pngwrite.c + Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to + prevent recursion. + Added png_free_hIST() function. + Various patches to fix bugs in the sCAL and integer cHRM processing, + and to add some convenience macros for use with sCAL. +version 1.0.5j [December 21, 1999] + Changed "unit" parameter of png_write_sCAL from png_byte to int, to work + around buggy compilers. + Added new type "png_fixed_point" for integers that hold float*100000 values + Restored backward compatibility of tEXt/zTXt chunk processing: + Restored the first four members of png_text to the same order as v.1.0.5d. + Added members "lang_key" and "itxt_length" to png_text struct. Set + text_length=0 when "text" contains iTXt data. Use the "compression" + member to distinguish among tEXt/zTXt/iTXt types. Added + PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. + The "Note" above, about backward incompatibility of libpng-1.0.5e, no + longer applies. + Fixed png_read|write_iTXt() to read|write parameters in the right order, + and to write the iTXt chunk after IDAT if it appears in the end_ptr. + Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) + Reversed the order of trying to write floating-point and fixed-point gAMA. +version 1.0.5k [December 27, 1999] + Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" + Added png_handle_as_unknown() function (Glenn) + Added png_free_chunk_list() function and chunk_list and num_chunk_list members + of png_ptr. + Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. + Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings + about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) + Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). + Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. + Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). +version 1.0.5l [January 1, 2000] + Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() + for setting a callback function to handle unknown chunks and for + retrieving the associated user pointer (Glenn). +version 1.0.5m [January 7, 2000] + Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). +version 1.0.5n [January 9, 2000] + Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its + own memory for info_ptr->palette. This makes it safe for the calling + application to free its copy of the palette any time after it calls + png_set_PLTE(). +version 1.0.5o [January 20, 2000] + Cosmetic changes only (removed some trailing blanks and TABs) +version 1.0.5p [January 31, 2000] + Renamed pngdll.mak to makefile.bd32 + Cosmetic changes in pngtest.c +version 1.0.5q [February 5, 2000] + Relocated the makefile.solaris warning about PATH problems. + Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) + Revised makefile.gcmmx + Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros +version 1.0.5r [February 7, 2000] + Removed superfluous prototype for png_get_itxt from png.h + Fixed a bug in pngrtran.c that improperly expanded the background color. + Return *num_text=0 from png_get_text() when appropriate, and fix documentation + of png_get_text() in libpng.txt/libpng.3. +version 1.0.5s [February 18, 2000] + Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the + new error handler that's planned for the next libpng release, and changed + example.c, pngtest.c, and contrib programs to use this macro. + Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) + Fixed a bug in png_read_png() that caused it to fail to expand some images + that it should have expanded. + Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions + in pngget.c + Changed the allocation of palette, history, and trans arrays back to + the version 1.0.5 method (linking instead of copying) which restores + backward compatibility with version 1.0.5. Added some remarks about + that in example.c. Added "free_me" member to info_ptr and png_ptr + and added png_free_data() function. + Updated makefile.linux and makefile.gccmmx to make directories conditionally. + Made cosmetic changes to pngasmrd.h + Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). + Modified png_read_png() to allocate info_ptr->row_pointers only if it + hasn't already been allocated. +version 1.0.5t [March 4, 2000] + Changed png_jmp_env() migration aiding macro to png_jmpbuf(). + Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c + Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when + PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b + Files in contrib/gregbook were revised to use png_jmpbuf() and to select + a 24-bit visual if one is available, and to allow abbreviated options. + Files in contrib/pngminus were revised to use the png_jmpbuf() macro. + Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s +version 1.0.5u [March 5, 2000] + Simplified the code that detects old png.h in png.c and pngtest.c + Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) + Increased precision of rgb_to_gray calculations from 8 to 15 bits and + added png_set_rgb_to_gray_fixed() function. + Added makefile.bc32 (32-bit Borland C++, C mode) +version 1.0.5v [March 11, 2000] + Added some parentheses to the png_jmpbuf macro definition. + Updated references to the zlib home page, which has moved to freesoftware.com. + Corrected bugs in documentation regarding png_read_row() and png_write_row(). + Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. + Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, + revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) + +version 1.0.6 [March 20, 2000] + Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c + Added makefile.sggcc (SGI IRIX with gcc) +version 1.0.6d [April 7, 2000] + Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO + Added data_length parameter to png_decompress_chunk() function + Revised documentation to remove reference to abandoned png_free_chnk functions + Fixed an error in png_rgb_to_gray_fixed() + Revised example.c, usage of png_destroy_write_struct(). + Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file + Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c + Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). +version 1.0.6e [April 9, 2000] + Added png_data_freer() function. + In the code that checks for over-length tRNS chunks, added check of + info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) + Minor revisions of libpng.txt/libpng.3. + Check for existing data and free it if the free_me flag is set, in png_set_*() + and png_handle_*(). + Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED + is defined. + Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c + and mentioned the purposes of the two macros in libpng.txt/libpng.3. +version 1.0.6f [April 14, 2000] + Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. + Add checks in png_set_text() for NULL members of the input text structure. + Revised libpng.txt/libpng.3. + Removed superfluous prototype for png_set_itxt from png.h + Removed "else" from pngread.c, after png_error(), and changed "0" to "length". + Changed several png_errors about malformed ancillary chunks to png_warnings. +version 1.0.6g [April 24, 2000] + Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. + Relocated paragraph about png_set_background() in libpng.3/libpng.txt + and other revisions (Matthias Benckmann) + Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and + png_ptr members to restore binary compatibility with libpng-1.0.5 + (breaks compatibility with libpng-1.0.6). +version 1.0.6h [April 24, 2000] + Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds + libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) + This is a temporary change for test purposes. +version 1.0.6i [May 2, 2000] + Rearranged some members at the end of png_info and png_struct, to put + unknown_chunks_num and free_me within the original size of the png_structs + and free_me, png_read_user_fn, and png_free_fn within the original png_info, + because some old applications allocate the structs directly instead of + using png_create_*(). + Added documentation of user memory functions in libpng.txt/libpng.3 + Modified png_read_png so that it will use user_allocated row_pointers + if present, unless free_me directs that it be freed, and added description + of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. + Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version + 1.00) members of png_struct and png_info, to regain binary compatibility + when you define this macro. Capabilities lost in this event + are user transforms (new in version 1.0.0),the user transform pointer + (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, + the high-level interface, and unknown chunks support (all new in 1.0.6). + This was necessary because of old applications that allocate the structs + directly as authors were instructed to do in libpng-0.88 and earlier, + instead of using png_create_*(). + Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which + can be used to detect codes that directly allocate the structs, and + code to check these modes in png_read_init() and png_write_init() and + generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED + was not defined. + Added makefile.intel and updated makefile.watcom (Pawel Mrochen) +version 1.0.6j [May 3, 2000] + Overloaded png_read_init() and png_write_init() with macros that convert + calls to png_read_init_2() or png_write_init_2() that check the version + and structure sizes. +version 1.0.7beta11 [May 7, 2000] + Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes + which are no longer used. + 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 + is defined. + Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory + overrun when old applications fill the info_ptr->text structure directly. + Added PNGAPI macro, and added it to the definitions of all exported functions. + Relocated version macro definitions ahead of the includes of zlib.h and + pngconf.h in png.h. +version 1.0.7beta12 [May 12, 2000] + Revised pngset.c to avoid a problem with expanding the png_debug macro. + Deleted some extraneous defines from pngconf.h + Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. + Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. + Added png_access_version_number() function. + Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). + Expanded libpng.3/libpng.txt information about png_data_freer(). +version 1.0.7beta14 [May 17, 2000] (beta13 was not published) + Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as + warnings instead of errors, as pngrutil.c does. + Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() + will actually write IDATs. + Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. + Make png_free_data() ignore its final parameter except when freeing data + that can have multiple instances (text, sPLT, unknowns). + Fixed a new bug in png_set_rows(). + Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. + Added png_set_invalid() function. + Fixed incorrect illustrations of png_destroy_write_struct() in example.c. +version 1.0.7beta15 [May 30, 2000] + Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce + fewer error messages. + Rearranged checks for Z_OK to check the most likely path first in pngpread.c + and pngwutil.c. + Added checks in pngtest.c for png_create_*() returning NULL, and mentioned + in libpng.txt/libpng.3 the need for applications to check this. + Changed names of png_default_*() functions in pngtest to pngtest_*(). + Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. + Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c + Set each pointer to NULL after freeing it in png_free_data(). + Worked around a problem in pngconf.h; AIX's strings.h defines an "index" + macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos) + Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). +version 1.0.7beta16 [June 4, 2000] + Revised the workaround of AIX string.h "index" bug. + Added a check for overlength PLTE chunk in pngrutil.c. + Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer + indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. + Added a warning in png_decompress_chunk() when it runs out of data, e.g. + when it tries to read an erroneous PhotoShop iCCP chunk. + Added PNG_USE_DLL macro. + Revised the copyright/disclaimer/license notice. + Added contrib/msvctest directory +version 1.0.7rc1 [June 9, 2000] + Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) + Added contrib/visupng directory (Willem van Schaik) +version 1.0.7beta18 [June 23, 2000] + Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ + and do not redefine PNGAPI if it is passed in via a compiler directive. + Revised visupng/PngFile.c to remove returns from within the Try block. + Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. + Updated contrib/visupng/cexcept.h to version 1.0.0. + Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. +version 1.0.7rc2 [June 28, 2000] + Updated license to include disclaimers required by UCITA. + Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. + +version 1.0.7 [July 1, 2000] + Revised the definition of "trans_values" in libpng.3/libpng.txt +version 1.0.8beta1 [July 8, 2000] + Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. + Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and + pngwutil.c. + Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. + Removed unused "#include " from png.c + Added WindowsCE support. + Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. +version 1.0.8beta2 [July 10, 2000] + Added project files to the wince directory and made further revisions + of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. +version 1.0.8beta3 [July 11, 2000] + Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() + for indexed-color input files to avoid potential double-freeing trans array + under some unusual conditions; problem was introduced in version 1.0.6f. + Further revisions to pngtest.c and files in the wince subdirectory. +version 1.0.8beta4 [July 14, 2000] + Added the files pngbar.png and pngbar.jpg to the distribution. + Added makefile.cygwin, and cygwin support in pngconf.h + Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) +version 1.0.8rc1 [July 16, 2000] + Revised png_debug() macros and statements to eliminate compiler warnings. + +version 1.0.8 [July 24, 2000] + Added png_flush() in pngwrite.c, after png_write_IEND(). + Updated makefile.hpux to build a shared library. +version 1.0.9beta1 [November 10, 2000] + Fixed typo in scripts/makefile.hpux + Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) + Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser) + Changed "cdrom.com" in documentation to "libpng.org" + Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). + Changed type of "params" from voidp to png_voidp in png_read|write_png(). + Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. + Revised the 3 instances of WRITEFILE in pngtest.c. + Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. + Updated png.rc in dll/msvc project + Revised makefile.dec to define and use LIBPATH and INCPATH + Increased size of global png_libpng_ver[] array from 12 to 18 chars. + Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. + Removed duplicate png_crc_finish() from png_handle_bKGD() function. + Added a warning when application calls png_read_update_info() multiple times. + Revised makefile.cygwin + Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. + Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). +version 1.0.9beta2 [November 19, 2000] + Renamed the "dll" subdirectory "projects". + Added borland project files to "projects" subdirectory. + Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. + Add error message in png_set_compression_buffer_size() when malloc fails. +version 1.0.9beta3 [November 23, 2000] + Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. + Removed the png_flush() in pngwrite.c that crashes some applications + that don't set png_output_flush_fn. + Added makefile.macosx and makefile.aix to scripts directory. +version 1.0.9beta4 [December 1, 2000] + Change png_chunk_warning to png_warning in png_check_keyword(). + Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). +version 1.0.9beta5 [December 15, 2000] + Added support for filter method 64 (for PNG datastreams embedded in MNG). +version 1.0.9beta6 [December 18, 2000] + Revised png_set_filter() to accept filter method 64 when appropriate. + Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to + help prevent applications from using MNG features in PNG datastreams. + Added png_permit_mng_features() function. + Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". +version 1.0.9rc1 [December 23, 2000] + Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c + Fixed error handling of unknown compression type in png_decompress_chunk(). + In pngconf.h, define __cdecl when _MSC_VER is defined. +version 1.0.9beta7 [December 28, 2000] + Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. + Revised memory management in png_set_hIST and png_handle_hIST in a backward + compatible manner. PLTE and tRNS were revised similarly. + Revised the iCCP chunk reader to ignore trailing garbage. +version 1.0.9beta8 [January 12, 2001] + Moved pngasmrd.h into pngconf.h. + Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. +version 1.0.9beta9 [January 15, 2001] + Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to + wince and msvc project module definition files. + Minor revision of makefile.cygwin. + Fixed bug with progressive reading of narrow interlaced images in pngpread.c +version 1.0.9beta10 [January 16, 2001] + Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. + Fixed "png_mmx_supported" typo in project definition files. +version 1.0.9beta11 [January 19, 2001] + Updated makefile.sgi to make shared library. + Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED + by default, for the benefit of DLL forward compatibility. These will + be re-enabled in version 1.2.0. +version 1.0.9rc2 [January 22, 2001] + Revised cygwin support. + +version 1.0.9 [January 31, 2001] + Added check of cygwin's ALL_STATIC in pngconf.h + Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. +version 1.0.10beta1 [March 14, 2001] + Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. + Reformatted libpng.3 to eliminate bad line breaks. + Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c + Added prototype for png_mmx_support() near the top of pnggccrd.c + Moved some error checking from png_handle_IHDR to png_set_IHDR. + Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. + Revised png_mmx_support() function in pnggccrd.c + Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c + Fixed memory leak in contrib/visupng/PngFile.c + Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) + Added warnings when retrieving or setting gamma=0. + Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). +version 1.0.10rc1 [March 23, 2001] + Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, + and png_strlen. + Revised png_mmx_supported() function in pnggccrd.c to return proper value. + Fixed bug in progressive reading (pngpread.c) with small images (height < 8). + +version 1.0.10 [March 30, 2001] + Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin + Added beos project files (Chris Herborth) +version 1.0.11beta1 [April 3, 2001] + Added type casts on several png_malloc() calls (Dimitri Papadapoulos). + Removed a no-longer needed AIX work-around from pngconf.h + Changed several "//" single-line comments to C-style in pnggccrd.c +version 1.0.11beta2 [April 11, 2001] + Removed PNGAPI from several functions whose prototypes did not have PNGAPI. + Updated scripts/pngos2.def +version 1.0.11beta3 [April 14, 2001] + Added checking the results of many instances of png_malloc() for NULL +version 1.0.11beta4 [April 20, 2001] + Undid the changes from version 1.0.11beta3. Added a check for NULL return + from user's malloc_fn(). + Removed some useless type casts of the NULL pointer. + Added makefile.netbsd + +version 1.0.11 [April 27, 2001] + Revised makefile.netbsd +version 1.0.12beta1 [May 14, 2001] + Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) + Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h + Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. + Eliminated the png_error about apps using png_read|write_init(). Instead, + libpng will reallocate the png_struct and info_struct if they are too small. + This retains future binary compatibility for old applications written for + libpng-0.88 and earlier. +version 1.2.0beta1 [May 6, 2001] + Bumped DLLNUM to 2. + Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED + by default. + Added runtime selection of MMX features. + Added png_set_strip_error_numbers function and related macros. +version 1.2.0beta2 [May 7, 2001] + Finished merging 1.2.0beta1 with version 1.0.11 + Added a check for attempts to read or write PLTE in grayscale PNG datastreams. +version 1.2.0beta3 [May 17, 2001] + Enabled user memory function by default. + Modified png_create_struct so it passes user mem_ptr to user memory allocator. + Increased png_mng_features flag from png_byte to png_uint_32. + Bumped shared-library (so-number) and dll-number to 3. +version 1.2.0beta4 [June 23, 2001] + Check for missing profile length field in iCCP chunk and free chunk_data + in case of truncated iCCP chunk. + Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc + Bumped dll-number from 2 to 3 in makefile.cygwin + Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly + if user attempts to run it on an 8-bit display. + Updated contrib/gregbook + Use png_malloc instead of png_zalloc to allocate palette in pngset.c + Updated makefile.ibmc + Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes + of png_write_oFFS width and height from png_uint_32 to png_int_32. + Updated example.c + Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c +version 1.2.0beta5 [August 8, 2001] + Revised contrib/gregbook + Revised makefile.gcmmx + Revised pnggccrd.c to conditionally compile some thread-unsafe code only + when PNG_THREAD_UNSAFE_OK is defined. + Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with + value exceeding 2^bit_depth-1 + Revised makefile.sgi and makefile.sggcc + Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c + Removed restriction that do_invert_mono only operate on 1-bit opaque files + +version 1.2.0 [September 1, 2001] + Changed a png_warning() to png_debug() in pnggccrd.c + Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). +version 1.2.1beta1 [October 19, 2001] + Revised makefile.std in contrib/pngminus + Include background_1 in png_struct regardless of gamma support. + Revised makefile.netbsd and makefile.macosx, added makefile.darwin. + Revised example.c to provide more details about using row_callback(). +version 1.2.1beta2 [October 25, 2001] + Added type cast to each NULL appearing in a function call, except for + WINCE functions. + Added makefile.so9. +version 1.2.1beta3 [October 27, 2001] + Removed type casts from all NULLs. + Simplified png_create_struct_2(). +version 1.2.1beta4 [November 7, 2001] + Revised png_create_info_struct() and png_creat_struct_2(). + Added error message if png_write_info() was omitted. + Type cast NULLs appearing in function calls when _NO_PROTO or + PNG_TYPECAST_NULL is defined. +version 1.2.1rc1 [November 24, 2001] + Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL + is defined. + Changed typecast of "size" argument to png_size_t in pngmem.c calls to + the user malloc_fn, to agree with the prototype in png.h + Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) + Updated makefile.sgi to recognize LIBPATH and INCPATH. + Updated various makefiles so "make clean" does not remove previous major + version of the shared library. +version 1.2.1rc2 [December 4, 2001] + Always allocate 256-entry internal palette, hist, and trans arrays, to + avoid out-of-bounds memory reference caused by invalid PNG datastreams. + Added a check for prefix_length > data_length in iCCP chunk handler. + +version 1.2.1 [December 7, 2001] + None. +version 1.2.2beta1 [February 22, 2002] + Fixed a bug with reading the length of iCCP profiles (Larry Reeves). + Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate + libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h + Revised makefile.darwin to remove "-undefined suppress" option. + Added checks for gamma and chromaticity values over 21474.83, which exceed + the limit for PNG unsigned 32-bit integers when encoded. + Revised calls to png_create_read_struct() and png_create_write_struct() + for simpler debugging. + Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) +version 1.2.2beta2 [February 23, 2002] + Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. + Check for invalid image dimensions in png_get_IHDR. + Added missing "fi;" in the install target of the SGI makefiles. + Added install-static to all makefiles that make shared libraries. + Always do gamma compensation when image is partially transparent. +version 1.2.2beta3 [March 7, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later. + Modified shared-library makefiles to install pkgconfig/libpngNN.pc. + Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown + Removed unused png_write_destroy_info prototype from png.h + Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case + Added install-shared target to all makefiles that make shared libraries. + Stopped a double free of palette, hist, and trans when not using free_me. + Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. +version 1.2.2beta4 [March 8, 2002] + Compute background.gray and background_1.gray even when color_type is RGB + in case image gets reduced to gray later (Jason Summers). + Relocated a misplaced /bin/rm in the "install-shared" makefile targets + Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. +version 1.2.2beta5 [March 26, 2002] + Added missing PNGAPI to several function definitions. + Check for invalid bit_depth or color_type in png_get_IHDR(), and + check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). + Revised iTXt support to accept NULL for lang and lang_key. + Compute gamma for color components of background even when color_type is gray. + Changed "()" to "{}" in scripts/libpng.pc.in. + Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN + Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so +version 1.2.2beta6 [March 31, 2002] +version 1.0.13beta1 [March 31, 2002] + Prevent png_zalloc() from trying to memset memory that it failed to acquire. + Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). + Ensure that the right function (user or default) is used to free the + png_struct after an error in png_create_read_struct_2(). +version 1.2.2rc1 [April 7, 2002] +version 1.0.13rc1 [April 7, 2002] + Save the ebx register in pnggccrd.c (Sami Farin) + Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). + Updated makefiles to put headers in include/libpng and remove old include/*.h. + +version 1.2.2 [April 15, 2002] +version 1.0.13 [April 15, 2002] + Revised description of png_set_filter() in libpng.3/libpng.txt. + Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd +version 1.0.13patch01 [April 17, 2002] +version 1.2.2patch01 [April 17, 2002] + Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc + Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install + Added install: target to makefile.32sunu and makefile.64sunu +version 1.0.13patch03 [April 18, 2002] +version 1.2.2patch03 [April 18, 2002] + Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng + subdirectory to libpngNN subdirectory without the full pathname. + Moved generation of libpng.pc from "install" to "all" in 15 makefiles. +version 1.2.3rc1 [April 28, 2002] + Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). + Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) + Fixed bug with $prefix, should be $(prefix) in makefile.hpux. + Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin + Added a link from libpngNN.pc to libpng.pc in 15 makefiles. + Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. + Revised makefile.darwin to make relative links without full pathname. + Added setjmp() at the end of png_create_*_struct_2() in case user forgets + to put one in their application. + Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and + removed them from module definition files. +version 1.2.3rc2 [May 1, 2002] + Fixed bug in reporting number of channels in pngget.c and pngset.c, + that was introduced in version 1.2.2beta5. + Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), + png_default_flush(), and png_push_fill_buffer() and included them in + module definition files. + Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. +version 1.2.3rc3 [May 1, 2002] + Revised prototype for png_default_flush() + Remove old libpng.pc and libpngNN.pc before installing new ones. +version 1.2.3rc4 [May 2, 2002] + Typos in *.def files (png_default_read|write -> png_default_read|write_data) + In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc + Added libpng-config and libpngNN-config and modified makefiles to install them. + Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles + Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp +version 1.2.3rc5 [May 11, 2002] + Changed "error" and "message" in prototypes to "error_message" and + "warning_message" to avoid namespace conflict. + Revised 15 makefiles to build libpng-config from libpng-config-*.in + Once more restored png_zalloc and png_zfree to regular nonexported form. + Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer + to nonexported form, but with PNGAPI, and removed them from module def files. +version 1.2.3rc6 [May 14, 2002] + Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c + Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. + Removed leftover libpng-config "sed" script from four makefiles. + Revised libpng-config creating script in 16 makefiles. + +version 1.2.3 [May 22, 2002] + Revised libpng-config target in makefile.cygwin. + Removed description of png_set_mem_fn() from documentation. + Revised makefile.freebsd. + Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). + Revised projects/msvc/README.txt + Changed -lpng to -lpngNN in LDFLAGS in several makefiles. +version 1.2.4beta1 [May 24, 2002] + Added libpng.pc and libpng-config to "all:" target in 16 makefiles. + Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) + Added missing "\" before closing double quote in makefile.gcmmx. + Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() + functions. +version 1.2.4beta2 [June 25, 2002] + Plugged memory leak of png_ptr->current_text (Matt Holgate). + Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) + Added -soname to the loader flags in makefile.dec, makefile.sgi, and + makefile.sggcc. + Added "test-installed" target to makefile.linux, makefile.gcmmx, + makefile.sgi, and makefile.sggcc. +version 1.2.4beta3 [June 28, 2002] + Plugged memory leak of row_buf in pngtest.c when there is a png_error(). + Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. + Added "test-installed" target to makefile.32sunu, makefile.64sunu, + makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, + makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. +version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] + Added "test-installed" target to makefile.cygwin and makefile.sco. + Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. + +version 1.2.4 and 1.0.14 [July 8, 2002] + Changed png_warning() to png_error() when width is too large to process. +version 1.2.4patch01 [July 20, 2002] + Revised makefile.cygwin to use DLL number 12 instead of 13. +version 1.2.5beta1 [August 6, 2002] + Added code to contrib/gregbook/readpng2.c to ignore unused chunks. + Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) + Removed some stray *.o files from contrib/gregbook. + Changed png_error() to png_warning() about "Too much data" in pngpread.c + and about "Extra compressed data" in pngrutil.c. + Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). + Updated makefile.hpgcc + Updated png.c and pnggccrd.c handling of return from png_mmx_support() +version 1.2.5beta2 [August 15, 2002] + Only issue png_warning() about "Too much data" in pngpread.c when avail_in + is nonzero. + Updated makefiles to install a separate libpng.so.3 with its own rpath. +version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] + Revised makefiles to not remove previous minor versions of shared libraries. +version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] + Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared + library loader directive. + Added missing "$OBJSDLL" line to makefile.gcmmx. + Added missing "; fi" to makefile.32sunu. +version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] + Revised libpng-config script. + +version 1.2.5 and 1.0.15 [October 3, 2002] + Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, + and makefile.aix. + Relocated two misplaced PNGAPI lines in pngtest.c +version 1.2.6beta1 [October 22, 2002] + Commented out warning about uninitialized mmx_support in pnggccrd.c. + Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. + Relocated two more misplaced PNGAPI lines in pngtest.c + Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, + introduced in version 1.0.2. + Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. +version 1.2.6beta2 [November 1, 2002] + Added libpng-config "--ldopts" output. + Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" + in makefiles. +version 1.2.6beta3 [July 18, 2004] + Reverted makefile changes from version 1.2.6beta2 and some of the changes + from version 1.2.6beta1; these will be postponed until version 1.2.7. + Version 1.2.6 is going to be a simple bugfix release. + Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. + Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. + Added "#!/bin/sh" at the top of configure, for recognition of the + 'x' flag under Cygwin (Cosmin). + Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). + Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). + Fixed the special memory handler for Borland C under DOS, in pngmem.c + (Cosmin). + Removed some spurious assignments in pngrutil.c (Cosmin). + Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings + on 16-bit platforms (Cosmin). + Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). + Used proper type png_fixed_point, to avoid problems on 16-bit platforms, + in png_handle_sRGB() (Cosmin). + Added compression_type to png_struct, and optimized the window size + inside the deflate stream (Cosmin). + Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). + Fixed handling of unknown chunks that come after IDAT (Cosmin). + Allowed png_error() and png_warning() to work even if png_ptr == NULL + (Cosmin). + Replaced row_info->rowbytes with row_bytes in png_write_find_filter() + (Cosmin). + Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). + Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded + values in png.c (Simon-Pierre, Cosmin). + Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). + Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc + (Simon-Pierre). + Moved the definition of PNG_HEADER_VERSION_STRING near the definitions + of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). + Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). + Updated scripts/makefile.vc(a)win32 (Cosmin). + Updated the MSVC project (Simon-Pierre, Cosmin). + Updated the Borland C++ Builder project (Cosmin). + Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). + Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). + Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). + Added extra guard around inclusion of Turbo C memory headers, in pngconf.h + (Cosmin). + Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to + projects/cbuilder5/ (Cosmin). + Moved projects/visualc6/png32ms.def to scripts/pngw32.def, + and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). + Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). + Changed line endings to DOS style in cbuilder5 and visualc6 files, even + in the tar.* distributions (Cosmin). + Updated contrib/visupng/VisualPng.dsp (Cosmin). + Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). + Added a separate distribution with "configure" and supporting files (Junichi). +version 1.2.6beta4 [July 28, 2004] + Added user ability to change png_size_t via a PNG_SIZE_T macro. + Added png_sizeof() and png_convert_size() functions. + Added PNG_SIZE_MAX (maximum value of a png_size_t variable. + Added check in png_malloc_default() for (size_t)size != (png_uint_32)size + which would indicate an overflow. + Changed sPLT failure action from png_error to png_warning and abandon chunk. + Changed sCAL and iCCP failures from png_error to png_warning and abandon. + Added png_get_uint_31(png_ptr, buf) function. + Added PNG_UINT_32_MAX macro. + Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. + Made png_zalloc() issue a png_warning and return NULL on potential + overflow. + Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x + Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. + Revised Borland portion of png_malloc() to return NULL or issue + png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. + Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove + sequential read support. + Added some "#if PNG_WRITE_SUPPORTED" blocks. + #ifdef'ed out some redundancy in png_malloc_default(). + Use png_malloc instead of png_zalloc to allocate the pallete. +version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] + Fixed buffer overflow vulnerability in png_handle_tRNS() + Fixed integer arithmetic overflow vulnerability in png_read_png(). + Fixed some harmless bugs in png_handle_sBIT, etc, that would cause + duplicate chunk types to go undetected. + Fixed some timestamps in the -config version + Rearranged order of processing of color types in png_handle_tRNS(). + Added ROWBYTES macro to calculate rowbytes without integer overflow. + Updated makefile.darwin and removed makefile.macosx from scripts directory. + Imposed default one million column, one-million row limits on the image + dimensions, and added png_set_user_limits() function to override them. + Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. + Fixed wrong cast of returns from png_get_user_width|height_max(). + Changed some "keep the compiler happy" from empty statements to returns, + Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution +version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] + Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. + Revised pngtest's png_debug_malloc() to use png_malloc() instead of + png_malloc_default() which is not supposed to be exported. + Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in + pngpread.c. Bug was introduced in 1.2.6rc1. + Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. + Fixed old bug in RGB to Gray transformation. + Fixed problem with 64-bit compilers by casting arguments to abs() + to png_int_32. + Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). + Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) + Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. + Added code to update the row_info->colortype in png_do_read_filler() (MSB). +version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] + Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid + trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. + Revised documentation of png_set_keep_unknown_chunks(). + Check handle_as_unknown status in pngpread.c, as in pngread.c previously. + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h + Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c +version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] + Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of + "pinfo" was out of place). +version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] + Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED + section of png.h where they were inadvertently placed in version rc3. + +version 1.2.6 and 1.0.16 [August 15, 2004] + Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. +version 1.2.7beta1 [August 26, 2004] + Removed unused pngasmrd.h file. + Removed references to uu.net for archived files. Added references to + PNG Spec (second edition) and the PNG ISO/IEC Standard. + Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. + Fixed bug with "optimized window size" in the IDAT datastream, that + causes libpng to write PNG files with incorrect zlib header bytes. +version 1.2.7beta2 [August 28, 2004] + Fixed bug with sCAL chunk and big-endian machines (David Munro). + Undid new code added in 1.2.6rc2 to update the color_type in + png_set_filler(). + Added png_set_add_alpha() that updates color type. +version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] + Revised png_set_strip_filler() to not remove alpha if color_type has alpha. + +version 1.2.7 and 1.0.17 [September 12, 2004] + Added makefile.hp64 + Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin +version 1.2.8beta1 [November 1, 2004] + Fixed bug in png_text_compress() that would fail to complete a large block. + Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during + strip alpha operation in png_do_strip_filler(). + Added PNG_1_2_X definition in pngconf.h + #ifdef out png_info_init in png.c and png_read_init in pngread.c (as of 1.3.0) +version 1.2.8beta2 [November 2, 2004] + Reduce color_type to a nonalpha type after strip alpha operation in + png_do_strip_filler(). +version 1.2.8beta3 [November 3, 2004] + Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM +version 1.2.8beta4 [November 12, 2004] + Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). + Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). + Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection + of data type in deflate (Cosmin). + Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. +version 1.2.8beta5 [November 20, 2004] + Use png_ptr->flags instead of png_ptr->transformations to pass + PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI + compatibility. + Revised handling of SPECIALBUILD, PRIVATEBUILD, + PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. +version 1.2.8rc1 [November 24, 2004] + Moved handling of BUILD macros from pngconf.h to png.h + Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently + omitted from beta5. + Revised scripts/pngw32.rc + Despammed mailing addresses by masking "@" with "at". + Inadvertently installed a supposedly faster test version of pngrutil.c +version 1.2.8rc2 [November 26, 2004] + Added two missing "\" in png.h + Change tests in pngread.c and pngpread.c to + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); +version 1.2.8rc3 [November 28, 2004] + Reverted pngrutil.c to version libpng-1.2.8beta5. + Added scripts/makefile.elf with supporting code in pngconf.h for symbol + versioning (John Bowler). +version 1.2.8rc4 [November 29, 2004] + Added projects/visualc7 (Simon-pierre). +version 1.2.8rc5 [November 29, 2004] + Fixed new typo in scripts/pngw32.rc + +version 1.2.8 [December 3, 2004] + Removed projects/visualc7, added projects/visualc71. + +version 1.2.9beta1 [February 21, 2006] + + Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints + Revised man page and libpng.txt to make it clear that one should not call + png_read_end or png_write_end after png_read_png or png_write_png. + Updated references to png-mng-implement mailing list. + Fixed an incorrect typecast in pngrutil.c + Added PNG_NO_READ_SUPPORTED conditional for making a write-only library. + Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional. + Optimized alpha-inversion loops in pngwtran.c + Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c + Make sure num_trans is <= 256 before copying data in png_set_tRNS(). + Make sure num_palette is <= 256 before copying data in png_set_PLTE(). + Interchanged order of write_swap_alpha and write_invert_alpha transforms. + Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin). + Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin). + Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin). + Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16, + png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin). + Added type cast (png_byte) in png_write_sCAL() (Cosmin). + Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin). + Default iTXt support was inadvertently enabled. + +version 1.2.9beta2 [February 21, 2006] + + Check for png_rgb_to_gray and png_gray_to_rgb read transformations before + checking for png_read_dither in pngrtran.c + Revised checking of chromaticity limits to accommodate extended RGB + colorspace (John Denker). + Changed line endings in some of the project files to CRLF, even in the + "Unix" tar distributions (Cosmin). + Made png_get_int_32 and png_save_int_32 always available (Cosmin). + Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def + with the newly exported functions. + Eliminated distributions without the "configure" script. + Updated INSTALL instructions. + +version 1.2.9beta3 [February 24, 2006] + + Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp + Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler) + Removed reference to pngasmrd.h from Makefile.am + Renamed CHANGES to ChangeLog. + Renamed LICENSE to COPYING. + Renamed ANNOUNCE to NEWS. + Created AUTHORS file. + +version 1.2.9beta4 [March 3, 2006] + + Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac + Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING. + Removed newline from the end of some error and warning messages. + Removed test for sqrt() from configure.ac and configure. + Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix). + Disabled default iTXt support that was inadvertently enabled in + libpng-1.2.9beta1. + Added "OS2" to list of systems that don't need underscores, in pnggccrd.c + Removed libpng version and date from *.c files. + +version 1.2.9beta5 [March 4, 2006] + Removed trailing blanks from source files. + Put version and date of latest change in each source file, and changed + copyright year accordingly. + More cleanup of configure.ac, Makefile.ac, and associated scripts. + Restored scripts/makefile.elf which was inadvertently deleted. + +version 1.2.9beta6 [March 6, 2006] + Fixed typo (18) in configuration files. + +version 1.2.9beta7 [March 7, 2006] + Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am + Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s() + in png.h. + Updated makefile.elf as suggested by debian. + Made cosmetic changes to some makefiles, adding LN_SF and other macros. + Made some makefiles accept "exec_prefix". + +version 1.2.9beta8 [March 9, 2006] + Fixed some "#if defined (..." which should be "#if defined(..." + Bug introduced in libpng-1.2.8. + Fixed inconsistency in definition of png_default_read_data() + Restored blank that was lost from makefile.sggcc "clean" target in beta7. + Revised calculation of "current" and "major" for irix in ltmain.sh + Changed "mkdir" to "MKDIR_P" in some makefiles. + Separated PNG_EXPAND and PNG_EXPAND_tRNS. + Added png_set_expand_gray_1_2_4_to_8() and deprecated + png_set_gray_1_2_4_to_8() which also expands tRNS to alpha. + +version 1.2.9beta9 [March 10, 2006] + Include "config.h" in pngconf.h when available. + Added some checks for NULL png_ptr or NULL info_ptr (timeless) + +version 1.2.9beta10 [March 20, 2006] + Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin) + Made pnggccrd.c PIC-compliant (Christian Aichinger). + Added makefile.mingw (Wolfgang Glas). + Revised pngconf.h MMX checking. + +version 1.2.9beta11 [March 22, 2006] + Fixed out-of-order declaration in pngwrite.c that was introduced in beta9 + Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros. + +version 1.2.9rc1 [March 31, 2006] + Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin). + Removed nonsensical assertion check from pngtest.c (Cosmin). + +version 1.2.9 [April 14, 2006] + Revised makefile.beos and added "none" selector in ltmain.sh + +version 1.2.10beta1 [April 15, 2006] + Renamed "config.h" to "png_conf.h" and revised Makefile.am to add + -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h + to include png_conf.h only when PNG_BUILDING_LIBPNG is defined. + +version 1.2.10beta2 [April 15, 2006] + Manually updated Makefile.in and configure. Changed png_conf.h.in + back to config.h. + +version 1.2.10beta3 [April 15, 2006] + Change png_conf.h back to config.h in pngconf.h. + +version 1.2.10beta4 [April 16, 2006] + Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*. + +version 1.2.10beta5 [April 16, 2006] + Added a configure check for compiling assembler code in pnggccrd.c + +version 1.2.10beta6 [April 17, 2006] + Revised the configure check for pnggccrd.c + Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@ + Added @LIBPNG_DEFINES@ to arguments when building libpng.sym + +version 1.2.10beta7 [April 18, 2006] + Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles. + +version 1.2.10rc1 [April 19, 2006] + Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD + Fixed "LN_FS" typo in makefile.sco and makefile.solaris. + +version 1.2.10rc2 [April 20, 2006] + Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE + in configure.ac and configure + Made the configure warning about versioned symbols less arrogant. + +version 1.2.10rc3 [April 21, 2006] + Added a note in libpng.txt that png_set_sig_bytes(8) can be used when + writing an embedded PNG without the 8-byte signature. + Revised makefiles and configure to avoid making links to libpng.so.* + +version 1.2.10 [April 23, 2006] + Reverted configure to "rc2" state. + +version 1.2.11beta1 [May 31, 2006] + scripts/libpng.pc.in contained "configure" style version info and would + not work with makefiles. + The shared-library makefiles were linking to libpng.so.0 instead of + libpng.so.3 compatibility as the library. + +version 1.2.11beta2 [June 2, 2006] + Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb) + +version 1.2.11beta3 [June 5, 2006] + Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin). + Removed the accidental leftover Makefile.in~ (Cosmin). + Avoided potential buffer overflow and optimized buffer in + png_write_sCAL(), png_write_sCAL_s() (Cosmin). + Removed the include directories and libraries from CFLAGS and LDFLAGS + in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin). + +version 1.2.11beta4 [June 6, 2006] + Allow zero-length IDAT chunks after the entire zlib datastream, but not + after another intervening chunk type. + +version 1.0.19rc1, 1.2.11rc1 [June 13, 2006] + Deleted extraneous square brackets from [config.h] in configure.ac + +version 1.0.19rc2, 1.2.11rc2 [June 14, 2006] + Added prototypes for PNG_INCH_CONVERSIONS functions to png.h + Revised INSTALL and autogen.sh + Fixed typo in several makefiles (-W1 should be -Wl) + Added typedef for png_int_32 and png_uint_32 on 64-bit systems. + +version 1.0.19rc3, 1.2.11rc3 [June 15, 2006] + Removed the new typedefs for 64-bit systems (delay until version 1.4.0) + Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid + reading out of bounds. + +version 1.0.19rc4, 1.2.11rc4 [June 15, 2006] + Really removed the new typedefs for 64-bit systems. + +version 1.0.19rc5, 1.2.11rc5 [June 22, 2006] + Removed png_sig_bytes entry from scripts/pngw32.def + +version 1.0.19, 1.2.11 [June 26, 2006] + None. + +version 1.0.20, 1.2.12 [June 27, 2006] + Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid + buffer overflow. + +version 1.2.13beta1 [October 2, 2006] + Removed AC_FUNC_MALLOC from configure.ac + Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h + Change "logical" to "bitwise" throughout documentation. + Detect and fix attempt to write wrong iCCP profile length. + +version 1.0.21, 1.2.13 [November 14, 2006] + Fix potential buffer overflow in sPLT chunk handler. + Fix Makefile.am to not try to link to noexistent files. + Check all exported functions for NULL png_ptr. + +version 1.2.14beta1 [November 17, 2006] + Relocated three misplaced tests for NULL png_ptr. + Built Makefile.in with automake-1.9.6 instead of 1.9.2. + Build configure with autoconf-2.60 instead of 2.59 + +version 1.2.14beta2 [November 17, 2006] + Added some typecasts in png_zalloc(). + +version 1.2.14rc1 [November 20, 2006] + Changed "strtod" to "png_strtod" in pngrutil.c + +version 1.0.22, 1.2.14 [November 27, 2006] + Added missing "$(srcdir)" in Makefile.am and Makefile.in + +version 1.2.15beta1 [December 3, 2006] + Generated configure with autoconf-2.61 instead of 2.60 + Revised configure.ac to update libpng.pc and libpng-config. + +version 1.2.15beta2 [December 3, 2006] + Always export MMX asm functions, just stubs if not building pnggccrd.c + +version 1.2.15beta3 [December 4, 2006] + Add "png_bytep" typecast to profile while calculating length in pngwutil.c + +version 1.2.15beta4 [December 7, 2006] + Added scripts/CMakeLists.txt + Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta + +version 1.2.15beta5 [December 7, 2006] + Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c + Revised scripts/CMakeLists.txt + +version 1.2.15beta6 [December 13, 2006] + Revised scripts/CMakeLists.txt and configure.ac + +version 1.2.15rc1 [December 18, 2006] + Revised scripts/CMakeLists.txt + +version 1.2.15rc2 [December 21, 2006] + Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. + Added scripts/makefile.nommx + +version 1.2.15rc3 [December 25, 2006] + Fixed shared library numbering error that was intruduced in 1.2.15beta6. + +version 1.2.15rc4 [December 27, 2006] + Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set. + +version 1.2.15rc5 [December 31, 2006] + Revised handling of rgb_to_gray. + +version 1.2.15 [January 5, 2007] + Added some (unsigned long) typecasts in pngtest.c to avoid printing errors. + +version 1.2.16beta1 [January 6, 2007] + Fix bugs in makefile.nommx + +version 1.2.16beta2 [January 16, 2007] + Revised scripts/CMakeLists.txt + +version 1.2.16 [January 31, 2007] + No changes. + +version 1.2.17beta1 [March 6, 2007] + Revised scripts/CMakeLists.txt to install both shared and static libraries. + Deleted a redundant line from pngset.c. + +version 1.2.17beta2 [April 26, 2007] + Relocated misplaced test for png_ptr == NULL in pngpread.c + Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN + flags. + Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_* + Added pngerror() when write_IHDR fails in deflateInit2(). + Added "const" to some array declarations. + Mention examples of libpng usage in the libpng*.txt and libpng.3 documents. + +version 1.2.17rc1 [May 4, 2007] + No changes. + +version 1.2.17rc2 [May 8, 2007] + Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications + calling set_unknown_chunk_location() need them. + Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in + png_set_expand_gray_1_2_4_to_8(). + Added png_ptr->unknown_chunk to hold working unknown chunk data, so it + can be free'ed in case of error. Revised unknown chunk handling in + pngrutil.c and pngpread.c to use this structure. + +version 1.2.17rc3 [May 8, 2007] + Revised symbol-handling in configure script. + +version 1.2.17rc4 [May 10, 2007] + Revised unknown chunk handling to avoid storing unknown critical chunks. + +version 1.0.25 [May 15, 2007] +version 1.2.17 [May 15, 2007] + Added "png_ptr->num_trans=0" before error return in png_handle_tRNS, + to eliminate a vulnerability (CVE-2007-2554, CERT VU#684664) + +version 1.0.26 [May 15, 2007] +version 1.2.18 [May 15, 2007] + Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) +or to glennrp at users.sourceforge.net + +Glenn R-P diff --git a/src/dep/src/irrlicht/libpng/INSTALL b/src/dep/src/irrlicht/libpng/INSTALL new file mode 100644 index 0000000..cd0583c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/INSTALL @@ -0,0 +1,206 @@ + +Installing libpng version 1.2.18 - May 15, 2007 + +On Unix/Linux and similar systems, you can simply type + + ./configure [--prefix=/path] + make check + make install + +and ignore the rest of this document. + +If configure does not work on your system and you have a reasonably +up-to-date set of tools, running ./autogen.sh before running ./configure +may fix the problem. You can also run the individual commands in +autogen.sh with the --force option, if supported by your version of +the tools. If you run 'libtoolize --force', though, this will replace +the distributed, patched, version of ltmain.sh with an unpatched version +and your shared library builds may fail to produce libraries with the +correct version numbers. + +Instead, you can use one of the custom-built makefiles in the +"scripts" directory + + cp scripts/makefile.system makefile + make test + make install + +Or you can use one of the "projects" in the "projects" directory. + +If you want to use "cmake" (see www.cmake.org), copy CMakeLists.txt +from the "scripts" directory to this directory and type + + cmake . [-DPNG_MMX=YES] -DCMAKE_INSTALL_PREFIX=/path + make + make install + +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. zlib can be placed in another directory, +at the same level as libpng. + +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. + +You can rename the directories that you downloaded (they +might be called "libpng-1.2.18" or "lpng109" and "zlib-1.2.1" +or "zlib121") 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 + contrib + gregbook + pngminus + pngsuite + visupng + projects + beos + c5builder (Borland) + visualc6 (msvc) + netware.txt + wince.txt + scripts + makefile.* + 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. + +If you are building libpng with MSVC, you can enter the +libpng projects\visualc6 directory and follow the instructions in +projects\visualc6\README.txt. + +You can build libpng for WindowsCE by downloading and installing +the projects\wince directory as instructed in the projects\wince.txt file, and +then following the instructions in the README* files. Similarly, you can +build libpng for Netware or Beos as instructed in projects\netware.txt +or projects\beos. + +Else 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. + +The files that are presently available in the scripts directory +include + + CMakeLists.txt => "cmake" script + makefile.std => Generic UNIX makefile (cc, creates static libpng.a) + makefile.elf => Linux/ELF makefile symbol versioning, + gcc, creates libpng12.so.0.1.2.18) + makefile.linux => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.18) + makefile.gcmmx => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.18, + uses assembler code tuned for Intel MMX platform) + makefile.nommx => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.18 + does not use Intel MMX assembler code) + makefile.gcc => Generic makefile (gcc, creates static libpng.a) + makefile.knr => Archaic UNIX Makefile that converts files with + ansi2knr (Requires ansi2knr.c from + ftp://ftp.cs.wisc.edu/ghost) + makefile.aix => AIX/gcc makefile + makefile.cygwin => Cygwin/gcc makefile + makefile.darwin => Darwin makefile, can use on MacosX + makefile.dec => DEC Alpha UNIX makefile + makefile.freebsd => FreeBSD makefile + makefile.hpgcc => HPUX makefile using gcc + makefile.hpux => HPUX (10.20 and 11.00) makefile + makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64-bit + makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static) + makefile.intel => Intel C/C++ version 4.0 and later + libpng.icc => Project file for IBM VisualAge/C++ version 4.0 or later + makefile.netbsd => NetBSD/cc makefile, uses PNGGCCRD, makes libpng.so. + makefile.ne12bsd => NetBSD/cc makefile, uses PNGGCCRD, + makes libpng12.so + makefile.openbsd => OpenBSD makefile + makefile.sgi => Silicon Graphics IRIX makefile (cc, creates static lib) + makefile.sggcc => Silicon Graphics (gcc, + creates libpng12.so.0.1.2.18) + makefile.sunos => Sun makefile + makefile.solaris => Solaris 2.X makefile (gcc, + creates libpng12.so.0.1.2.18) + makefile.so9 => Solaris 9 makefile (gcc, + creates libpng12.so.0.1.2.18) + makefile.32sunu => Sun Ultra 32-bit makefile + makefile.64sunu => Sun Ultra 64-bit makefile + makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc + makefile.mips => MIPS makefile + makefile.acorn => Acorn makefile + makefile.amiga => Amiga makefile + smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler + (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc) + makefile.atari => Atari makefile + makefile.beos => BEOS makefile for X86 + makefile.bor => Borland makefile (uses bcc) + makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode) + makefile.tc3 => Turbo C 3.0 makefile + makefile.dj2 => DJGPP 2 makefile + makefile.msc => Microsoft C makefile + makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and later (uses + assembler code tuned for Intel MMX platform) + makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does + not use assembler code) + makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def) + pngos2.def => OS/2 module definition file used by makefile.os2 + makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model + makevms.com => VMS build script + descrip.mms => VMS makefile for MMS or MMK + SCOPTIONS.ppc => Used with smakefile.ppc + +Copy the file (or files) that you need from the +scripts directory into this directory, for example + + MSDOS example: copy scripts\makefile.msc makefile + UNIX example: cp scripts/makefile.std makefile + +Read the makefile to see if you need to change any source or +target directories to match your preferences. + +Then read pngconf.h 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". + +If you encounter a compiler error message complaining about the +lines + __png.h__ already includes setjmp.h; + __dont__ include it again.; +This means you have compiled another module that includes setjmp.h, +which is hazardous because the two modules might not include exactly +the same setjmp.h. If you are sure that you know what you are doing +and that they are exactly the same, then you can comment out or +delete the two lines. Better yet, use the cexcept interface +instead, as demonstrated in contrib/visupng of the libpng distribution. + +Further information can be found in the README and libpng.txt +files, in the individual makefiles, in png.h, and the manual pages +libpng.3 and png.5. diff --git a/src/dep/src/irrlicht/libpng/KNOWNBUG b/src/dep/src/irrlicht/libpng/KNOWNBUG new file mode 100644 index 0000000..975f67a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/KNOWNBUG @@ -0,0 +1,28 @@ + +Known bugs in libpng version 1.2.18 + +1. April 22, 2001: pnggccrd.c has been reported to crash on NetBSD when + reading interlaced PNG files, when assembler code is enabled but running + on a non-MMX i386 platform. + + STATUS: Under investigation. The change to pnggccrd.c in libpng-1.2.1 + fixed a problem under FreeBSD but not the problem with NetBSD, which + still fails as of libpng-1.2.2rc1. + +2. February 23, 2006: The custom makefiles don't build libpng with -lz. + + STATUS: This is a subject of debate. The change will probably be made + as a part of a major overhaul of the makefiles in libpng version 1.3.0. + +3. February 24, 2006: The Makefile generated by the "configure" script + fails to install symbolic links + libpng12.so => libpng12.so.0.1.2.9betaN + that are generated by the custom makefiles. + + STATUS: For now, system library builders should use the custom makefiles. + +4. March 2007: Building 1.2.16 with PNG_ASSEMBLER_CODE_SUPPORTED; + PNG_MMX_CODE_SUPPORTED results in multiple definitions of png_combine_row, + png_do_read_interlace, and png_read_filter_row + + STATUS: Investigating. diff --git a/src/dep/src/irrlicht/libpng/LICENSE b/src/dep/src/irrlicht/libpng/LICENSE new file mode 100644 index 0000000..09bcaf9 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/LICENSE @@ -0,0 +1,109 @@ + +This copy of the libpng notices is provided for your convenience. In case of +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: + +If you modify libpng you may insert additional notices immediately following +this sentence. + +libpng versions 1.2.6, August 15, 2004, through 1.2.18, May 15, 2007, are +Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.2.5 +with the following individual added to the list of Contributing Authors + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +May 15, 2007 diff --git a/src/dep/src/irrlicht/libpng/README b/src/dep/src/irrlicht/libpng/README new file mode 100644 index 0000000..1316076 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/README @@ -0,0 +1,263 @@ +README for libpng version 1.2.18 - May 15, 2007 (shared library 12.0) +See the note about version numbers near the top of png.h + +See INSTALL for instructions on how to install libpng. + +Libpng comes in several distribution formats. Get libpng-*.tar.gz +or libpng-*.tar.bz2 if you want UNIX-style line endings in the text +files, or lpng*.zip if you want DOS-style line endings. + +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 +extensive use and testing since mid-1995. By late 1997 it had +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 +libraries with versions < 1.0. Version 1.0.0 was released in +March 1998. + +**** +Note that some of the changes to the png_info structure render this +version of the library binary incompatible with libpng-0.89 or +earlier versions if you are using a shared library. The type of the +"filler" parameter for png_set_filler() has changed from png_byte to +png_uint_32, which will affect shared-library applications that use +this function. + +To avoid problems with changes to the internals of png_info_struct, +new APIs have been made available in 0.95 to avoid direct application +access to info_ptr. These functions are the png_set_ and +png_get_ functions. These functions should be used when +accessing/storing the info_struct data, rather than manipulating it +directly, to avoid such problems in the future. + +It is important to note that the APIs do not make current programs +that access the info struct directly incompatible with the new +library. However, it is strongly suggested that new programs use +the new APIs (as shown in example.c and pngtest.c), and older programs +be converted to the new format, to facilitate upgrades in the future. +**** + +Additions since 0.90 include the ability to compile libpng as a +Windows DLL, and new APIs for accessing data in the info struct. +Experimental functions include the ability to set weighting and cost +factors for row filter selection, direct reads of integers from buffers +on big-endian processors that support misaligned data access, faster +methods of doing alpha composition, and more accurate 16->8 bit color +conversion. + +The additions since 0.89 include the ability to read from a PNG stream +which has had some (or all) of the signature bytes read by the calling +application. This also allows the reading of embedded PNG streams that +do not have the PNG file signature. As well, it is now possible to set +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 +critical or an ancillary chunk. + +The changes made to the library, and bugs fixed are based on discussions +on the PNG-implement mailing list +and not on material submitted privately to Guy, Andreas, or Glenn. They will +forward any good suggestions to the list. + +For a detailed description on using libpng, read libpng.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 +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 +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 +some images. You will definitely need zlib 1.0.4 or later if you are +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. +ftp://ftp.info-zip.org/pub/infozip/zlib + +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 +these at http://www.libpng.org/pub/png/documents/ + +This code is currently being archived at libpng.sf.net in the +[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) +at GO GRAPHSUP. If you can't find it in any of those places, +e-mail me, and I'll help you find it. + +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 group. + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net +(subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe) or to glennrp at users.sourceforge.net + +You can't reach Guy, the original libpng author, at the addresses +given in previous versions of this document. He and Andreas will read mail +addressed to the png-implement list, however. + +Please do not send general questions about PNG. Send them to +the (png-list at ccrc.wustl.edu, subscription required, write to +majordomo at ccrc.wustl.edu with "subscribe png-list" in your message). +On the other hand, +please do not send libpng questions to that address, send them to me +or to the png-implement list. I'll +get them in the end anyway. If you have a question about something +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 nine 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: + + ANNOUNCE => Announcement of this version, with recent changes + CHANGES => Description of changes between libpng versions + KNOWNBUG => List of known bugs and deficiencies + LICENSE => License to use and redistribute libpng + README => This file + TODO => Things not implemented in the current library + Y2KINFO => Statement of Y2K compliance + example.c => Example code for using libpng functions + libpng.3 => manual page for libpng (includes libpng.txt) + libpng.txt => Description of libpng and its functions + libpngpf.3 => manual page for libpng's private functions + png.5 => manual page for the PNG format + png.c => Basic interface functions common to library + png.h => Library function and interface declarations + pngconf.h => System specific library configuration + pngasmrd.h => Header file for assembler-coded functions + pngerror.c => Error/warning message I/O functions + pngget.c => Functions for retrieving info from struct + pngmem.c => Memory handling functions + pngbar.png => PNG logo, 88x31 + pngnow.png => PNG logo, 98x31 + pngpread.c => Progressive reading functions + pngread.c => Read data/helper high-level functions + pngrio.c => Lowest-level data read I/O functions + pngrtran.c => Read data transformation functions + pngrutil.c => Read data utility functions + pngset.c => Functions for storing data into the info_struct + pngtest.c => Library test program + pngtest.png => Library test sample image + pngtrans.c => Common data transformation functions + pngwio.c => Lowest-level write I/O functions + pngwrite.c => High-level write functions + pngwtran.c => Write data transformations + pngwutil.c => Write utility functions + contrib => Contributions + gregbook => source code for PNG reading and writing, from + Greg Roelofs' "PNG: The Definitive Guide", + O'Reilly, 1999 + msvctest => Builds and runs pngtest using a MSVC workspace + pngminus => Simple pnm2png and png2pnm programs + pngsuite => Test images + visupng => Contains a MSVC workspace for VisualPng + projects => Contains project files and workspaces for building DLL + beos => Contains a Beos workspace for building libpng + c5builder => Contains a Borland workspace for building libpng + and zlib + visualc6 => Contains a Microsoft Visual C++ (MSVC) workspace + for building libpng and zlib + netware.txt => Contains instructions for downloading a set of + project files for building libpng and zlib on + Netware. + wince.txt => Contains instructions for downloading a Microsoft + Visual C++ (Windows CD Toolkit) workspace for + building libpng and zlib on WindowsCE + scripts => Directory containing scripts for building libpng: + descrip.mms => VMS makefile for MMS or MMK + makefile.std => Generic UNIX makefile (cc, creates static libpng.a) + makefile.elf => Linux/ELF makefile symbol versioning, + gcc, creates libpng12.so.0.1.2.18) + makefile.linux => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.18) + makefile.gcmmx => Linux/ELF makefile + (gcc, creates libpng12.so.0.1.2.18, + uses assembler code tuned for Intel MMX platform) + makefile.gcc => Generic makefile (gcc, creates static libpng.a) + makefile.knr => Archaic UNIX Makefile that converts files with + ansi2knr (Requires ansi2knr.c from + ftp://ftp.cs.wisc.edu/ghost) + makefile.aix => AIX makefile + makefile.cygwin => Cygwin/gcc makefile + makefile.darwin => Darwin makefile + makefile.dec => DEC Alpha UNIX makefile + makefile.freebsd => FreeBSD makefile + makefile.hpgcc => HPUX makefile using gcc + makefile.hpux => HPUX (10.20 and 11.00) makefile + makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64 bit + makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static) + makefile.intel => Intel C/C++ version 4.0 and later + libpng.icc => Project file, IBM VisualAge/C++ 4.0 or later + makefile.netbsd => NetBSD/cc makefile, PNGGCCRD, makes libpng.so. + makefile.ne12bsd => NetBSD/cc makefile, PNGGCCRD, makes libpng12.so + makefile.openbsd => OpenBSD makefile + makefile.sgi => Silicon Graphics IRIX (cc, creates static lib) + makefile.sggcc => Silicon Graphics + (gcc, creates libpng12.so.0.1.2.18) + makefile.sunos => Sun makefile + makefile.solaris => Solaris 2.X makefile + (gcc, creates libpng12.so.0.1.2.18) + makefile.so9 => Solaris 9 makefile + (gcc, creates libpng12.so.0.1.2.18) + makefile.32sunu => Sun Ultra 32-bit makefile + makefile.64sunu => Sun Ultra 64-bit makefile + makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc + makefile.mips => MIPS makefile + makefile.acorn => Acorn makefile + makefile.amiga => Amiga makefile + smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC + compiler (Requires SCOPTIONS, copied from + scripts/SCOPTIONS.ppc) + makefile.atari => Atari makefile + makefile.beos => BEOS makefile for X86 + makefile.bor => Borland makefile (uses bcc) + makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode) + makefile.tc3 => Turbo C 3.0 makefile + makefile.dj2 => DJGPP 2 makefile + makefile.msc => Microsoft C makefile + makefile.vcawin32=> makefile for Microsoft Visual C++ 5.0 and + later (uses assembler code tuned for Intel MMX + platform) + makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and + later (does not use assembler code) + makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def) + pngos2.def => OS/2 module definition file used by makefile.os2 + makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model + makevms.com => VMS build script + SCOPTIONS.ppc => Used with smakefile.ppc + +Good luck, and happy coding. + +-Glenn Randers-Pehrson (current maintainer) + Internet: glennrp at users.sourceforge.net + +-Andreas Eric Dilger (former maintainer, 1996-1997) + Internet: adilger at enel.ucalgary.ca + 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 diff --git a/src/dep/src/irrlicht/libpng/TODO b/src/dep/src/irrlicht/libpng/TODO new file mode 100644 index 0000000..90f945c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/TODO @@ -0,0 +1,24 @@ +TODO - list of things to do for libpng: + +Final bug fixes. +Improve API by hiding the png_struct and png_info structs. +Finish work on the no-floating-point version (including gamma compensation) +Better C++ wrapper/full C++ implementation? +Fix problem with C++ and EXTERN "C". +cHRM transformation. +Improve setjmp/longjmp usage or remove it in favor of returning error codes. +Add "grayscale->palette" transformation and "palette->grayscale" detection. +Improved dithering. +Multi-lingual error and warning message support. +Complete sRGB transformation (presently it simply uses gamma=0.45455). +Man pages for function calls. +Better documentation. +Better filter selection + (counting huffman bits/precompression? filter inertia? filter costs?). +Histogram creation. +Text conversion between different code pages (Latin-1 -> Mac and DOS). +Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety? +Build gamma tables using fixed point (and do away with floating point entirely). +Use greater precision when changing to linear gamma for compositing against + background and doing rgb-to-gray transformation. +Investigate pre-incremented loop counters and other loop constructions. diff --git a/src/dep/src/irrlicht/libpng/Y2KINFO b/src/dep/src/irrlicht/libpng/Y2KINFO new file mode 100644 index 0000000..a299123 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/Y2KINFO @@ -0,0 +1,55 @@ + Y2K compliance in libpng: + ========================= + + May 15, 2007 + + 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.2.18 are Y2K compliant. It is my belief that earlier + versions were also Y2K compliant. + + Libpng only has three year fields. One is a 2-byte unsigned integer + that will hold years up to 65535. The other two hold the date in text + format, and will hold years up to 9999. + + The integer is + "png_uint_16 year" in png_time_struct. + + The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + + There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + 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 diff --git a/src/dep/src/irrlicht/libpng/configure b/src/dep/src/irrlicht/libpng/configure new file mode 100644 index 0000000..0766c27 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/configure @@ -0,0 +1,13 @@ +#!/bin/sh +echo " + There is no \"configure\" script in this distribution of + libpng-1.2.18. + + 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.2.18.tar.gz or libpng-1.2.18.tar.bz2 +" + diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/LICENSE b/src/dep/src/irrlicht/libpng/contrib/gregbook/LICENSE new file mode 100644 index 0000000..f47b7c4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/LICENSE @@ -0,0 +1,26 @@ + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + --------------------------------------------------------------------------- diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.sgi b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.sgi new file mode 100644 index 0000000..f8f22f9 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.sgi @@ -0,0 +1,104 @@ +# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make. +# Greg Roelofs +# Last modified: 7 March 2002 +# +# The programs built by this makefile are described in the book, +# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and +# Associates, 1999). Go buy a copy, eh? Buy some for friends +# and family, too. (Not that this is a blatant plug or anything.) +# +# Invoke this makefile from a shell prompt in the usual way; for example: +# +# make -f Makefile.sgi +# +# This makefile assumes libpng and zlib have already been built or downloaded +# and are both installed in /usr/local/{include,lib} (as indicated by the +# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of +# the PNGINC, PNGLIB, ZINC and ZLIB lines. +# +# This makefile builds dynamically linked executables (against libpng and zlib, +# that is), but that can be changed by uncommenting the appropriate PNGLIB and +# ZLIB lines. + + +# macros -------------------------------------------------------------------- + +PNGINC = -I/usr/local/include/libpng12 +PNGLIB = -L/usr/local/lib -lpng12 # dynamically linked against libpng +#PNGLIB = /usr/local/lib/libpng12.a # statically linked against libpng +# or: +#PNGINC = -I../.. +#PNGLIB = -L../.. -lpng +#PNGLIB = ../../libpng.a + +ZINC = -I/usr/local/include +ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib +#ZLIB = /usr/local/lib/libz.a # statically linked against zlib +#ZINC = -I../zlib +#ZLIB = -L../zlib -lz +#ZLIB = ../../../zlib/libz.a + +XINC = -I/usr/include/X11 # old-style, stock X distributions +XLIB = -L/usr/lib/X11 -lX11 +#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) +#XLIB = -L/usr/openwin/lib -lX11 +#XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.) +#XLIB = -L/usr/X11R6/lib -lX11 + +INCS = $(PNGINC) $(ZINC) $(XINC) +RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm +WLIBS = $(PNGLIB) $(ZLIB) + +CC = cc +LD = cc +RM = rm -f +# ABI must be the same as that used to build libpng. +ABI= +CFLAGS = $(ABI) -O -fullwarn $(INCS) +LDFLAGS = $(ABI) +O = .o +E = + +RPNG = rpng-x +RPNG2 = rpng2-x +WPNG = wpng + +ROBJS = $(RPNG)$(O) readpng$(O) +ROBJS2 = $(RPNG2)$(O) readpng2$(O) +WOBJS = $(WPNG)$(O) writepng$(O) + +EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) + + +# implicit make rules ------------------------------------------------------- + +.c$(O): + $(CC) -c $(CFLAGS) $< + + +# dependencies -------------------------------------------------------------- + +all: $(EXES) + +$(RPNG)$(E): $(ROBJS) + $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS) + +$(RPNG2)$(E): $(ROBJS2) + $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS) + +$(WPNG)$(E): $(WOBJS) + $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS) + +$(RPNG)$(O): $(RPNG).c readpng.h +$(RPNG2)$(O): $(RPNG2).c readpng2.h +$(WPNG)$(O): $(WPNG).c writepng.h + +readpng$(O): readpng.c readpng.h +readpng2$(O): readpng2.c readpng2.h +writepng$(O): writepng.c writepng.h + + +# maintenance --------------------------------------------------------------- + +clean: + $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.unx b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.unx new file mode 100644 index 0000000..3d055d2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.unx @@ -0,0 +1,104 @@ +# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make. +# Greg Roelofs +# Last modified: 7 March 2002 +# +# The programs built by this makefile are described in the book, +# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and +# Associates, 1999). Go buy a copy, eh? Buy some for friends +# and family, too. (Not that this is a blatant plug or anything.) +# +# Invoke this makefile from a shell prompt in the usual way; for example: +# +# make -f Makefile.unx +# +# This makefile assumes libpng and zlib have already been built or downloaded +# and are both installed in /usr/local/{include,lib} (as indicated by the +# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of +# the PNGINC, PNGLIB, ZINC and ZLIB lines. +# +# This makefile builds statically linked executables (against libpng and zlib, +# that is), but that can be changed by uncommenting the appropriate PNGLIB and +# ZLIB lines. + + +# macros -------------------------------------------------------------------- + +PNGINC = -I/usr/local/include/libpng12 +#PNGLIB = -L/usr/local/lib -lpng12 # dynamically linked against libpng +PNGLIB = /usr/local/lib/libpng12.a # statically linked against libpng +# or: +#PNGINC = -I../libpng +#PNGLIB = -L../libpng -lpng +#PNGLIB = ../libpng/libpng.a + +ZINC = -I/usr/local/include +#ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib +ZLIB = /usr/local/lib/libz.a # statically linked against zlib +#ZINC = -I../zlib +#ZLIB = -L../zlib -lz +#ZLIB = ../zlib/libz.a + +#XINC = -I/usr/include # old-style, stock X distributions +#XLIB = -L/usr/lib/X11 -lX11 +#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) +#XLIB = -L/usr/openwin/lib -lX11 +XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.) +XLIB = -L/usr/X11R6/lib -lX11 + +INCS = $(PNGINC) $(ZINC) $(XINC) +RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm +WLIBS = $(PNGLIB) $(ZLIB) + +CC = gcc +LD = gcc +RM = rm -f +CFLAGS = -O -Wall $(INCS) +# [note that -Wall is a gcc-specific compilation flag ("most warnings on")] +# [-ansi, -pedantic and -W can also be used] +LDFLAGS = +O = .o +E = + +RPNG = rpng-x +RPNG2 = rpng2-x +WPNG = wpng + +ROBJS = $(RPNG)$(O) readpng$(O) +ROBJS2 = $(RPNG2)$(O) readpng2$(O) +WOBJS = $(WPNG)$(O) writepng$(O) + +EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) + + +# implicit make rules ------------------------------------------------------- + +.c$(O): + $(CC) -c $(CFLAGS) $< + + +# dependencies -------------------------------------------------------------- + +all: $(EXES) + +$(RPNG)$(E): $(ROBJS) + $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS) + +$(RPNG2)$(E): $(ROBJS2) + $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS) + +$(WPNG)$(E): $(WOBJS) + $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS) + +$(RPNG)$(O): $(RPNG).c readpng.h +$(RPNG2)$(O): $(RPNG2).c readpng2.h +$(WPNG)$(O): $(WPNG).c writepng.h + +readpng$(O): readpng.c readpng.h +readpng2$(O): readpng2.c readpng2.h +writepng$(O): writepng.c writepng.h + + +# maintenance --------------------------------------------------------------- + +clean: + $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.w32 b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.w32 new file mode 100644 index 0000000..ceb6a51 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/Makefile.w32 @@ -0,0 +1,112 @@ +# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE. +# Greg Roelofs +# Last modified: 16 February 1999 +# +# The programs built by this makefile are described in the book, +# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and +# Associates, 1999). Go buy a copy, eh? Buy some for friends +# and family, too. (Not that this is a blatant plug or anything.) +# +# Invoke this makefile from a DOS prompt window via: +# +# %devstudio%\vc\bin\vcvars32.bat +# nmake -nologo -f Makefile.w32 +# +# where %devstudio% is the installation directory for MSVC / DevStudio. If +# you get "environment out of space" errors, create a desktop shortcut with +# "c:\windows\command.com /e:4096" as the program command line and set the +# working directory to this directory. Then double-click to open the new +# DOS-prompt window with a bigger environment and retry the commands above. +# +# This makefile assumes libpng and zlib have already been built or downloaded +# and are in subdirectories at the same level as the current subdirectory +# (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate. +# +# Note that the names of the dynamic and static libpng and zlib libraries +# used below may change in later releases of the libraries. This makefile +# builds statically linked executables, but that can be changed by uncom- +# menting the appropriate PNGLIB and ZLIB lines. + +!include + + +# macros -------------------------------------------------------------------- + +PNGPATH = ../libpng +PNGINC = -I$(PNGPATH) +#PNGLIB = $(PNGPATH)/pngdll.lib +PNGLIB = $(PNGPATH)/libpng.lib + +ZPATH = ../zlib +ZINC = -I$(ZPATH) +#ZLIB = $(ZPATH)/zlibdll.lib +ZLIB = $(ZPATH)/zlibstat.lib + +WINLIBS = -defaultlib:user32.lib gdi32.lib +# ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.] + +INCS = $(PNGINC) $(ZINC) +RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS) +WLIBS = $(PNGLIB) $(ZLIB) + +CC = cl +LD = link +RM = del +CFLAGS = -nologo -O -W3 $(INCS) $(cvars) +# [note that -Wall is an MSVC-specific compilation flag ("all warnings on")] +# [see %devstudio%\vc\include\win32.mak for cvars macro definition] +O = .obj +E = .exe + +RLDFLAGS = -nologo -subsystem:windows +WLDFLAGS = -nologo + +RPNG = rpng-win +RPNG2 = rpng2-win +WPNG = wpng + +ROBJS = $(RPNG)$(O) readpng$(O) +ROBJS2 = $(RPNG2)$(O) readpng2$(O) +WOBJS = $(WPNG)$(O) writepng$(O) + +EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) + + +# implicit make rules ------------------------------------------------------- + +.c$(O): + $(CC) -c $(CFLAGS) $< + + +# dependencies -------------------------------------------------------------- + +all: $(EXES) + +$(RPNG)$(E): $(ROBJS) + $(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS) + +$(RPNG2)$(E): $(ROBJS2) + $(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS) + +$(WPNG)$(E): $(WOBJS) + $(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS) + +$(RPNG)$(O): $(RPNG).c readpng.h +$(RPNG2)$(O): $(RPNG2).c readpng2.h +$(WPNG)$(O): $(WPNG).c writepng.h + +readpng$(O): readpng.c readpng.h +readpng2$(O): readpng2.c readpng2.h +writepng$(O): writepng.c writepng.h + + +# maintenance --------------------------------------------------------------- + +clean: +# ideally we could just do this: +# $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) +# ...but the Windows "DEL" command is none too bright, so: + $(RM) r*$(E) + $(RM) w*$(E) + $(RM) r*$(O) + $(RM) w*$(O) diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/README b/src/dep/src/irrlicht/libpng/contrib/gregbook/README new file mode 100644 index 0000000..d083c76 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/README @@ -0,0 +1,185 @@ + =========================== + PNG: The Definitive Guide + =========================== + + Source Code + +Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free, +cross-platform demo programs that show how to use the libpng reference +library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is +a very simple example that that shows how a standard file-viewer might use +libpng, while the second is designed to process streaming data and shows +how a web browser might be written. wpng is a simple command-line program +that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets +of PBMPLUS/NetPBM) and converts them to PNG. + +The source code for all three demo programs currently compiles under +Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser, +zinser@decus.de, for making the necessary changes for OpenVMS and for +providing an appropriate build script.) Build instructions can be found +below. + +Files: + + README this file + LICENSE terms of distribution and reuse (BSD-like) + + Makefile.unx Unix makefile + Makefile.w32 Windows (MSVC) makefile + makevms.com OpenVMS build script + + rpng-win.c Windows front end for the basic viewer + rpng-x.c X Window System (Unix, OpenVMS) front end + readpng.c generic back end for the basic viewer + readpng.h header file for the basic viewer + + rpng2-win.c Windows front end for the progressive viewer + rpng2-x.c X front end for the progressive viewer + readpng2.c generic back end for the progressive viewer + readpng2.h header file for the progressive viewer + + wpng.c generic (text) front end for the converter + writepng.c generic back end for the converter + writepng.h header file for the converter + + toucan.png transparent PNG for testing (by Stefan Schneider) + +Note that, although the programs are designed to be functional, their +primary purpose is to illustrate how to use libpng to add PNG support to +other programs. As such, their user interfaces are crude and definitely +are not intended for everyday use. + +Please see http://www.libpng.org/pub/png/pngbook.html for further infor- +mation and links to the latest version of the source code, and Chapters +13-15 of the book for detailed discussion of the three programs. + +Greg Roelofs +newt@pobox.com +30 June 2001 + + +BUILD INSTRUCTIONS + + - Prerequisites (in order of compilation): + + - zlib http://www.gzip.org/zlib/ + - libpng http://www.libpng.org/pub/png/libpng.html + - pngbook http://www.libpng.org/pub/png/book/sources.html + + The pngbook demo programs are explicitly designed to demonstrate proper + coding techniques for using the libpng reference library. As a result, + you need to download and build both zlib (on which libpng depends) and + libpng. A common build setup is to place the zlib, libpng and pngbook + subdirectory trees ("folders") in the same parent directory. Then the + libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]), + and similarly for the pngbook build. + + Note that all three packages are designed to be built from a command + line by default; those who wish to use a graphical or other integrated + development environments are on their own. + + + - Unix: + + Unpack the latest pngbook sources (which should correspond to this + README file) into a directory and change into that directory. + + Copy Makefile.unx to Makefile and edit the PNG* and Z* variables + appropriately (possibly also the X* variables if necessary). + + make + + There is no "install" target, so copy the three executables somewhere + in your path or run them from the current directory. All three will + print a basic usage screen when run without any command-line arguments; + see the book for more details. + + + - Windows: + + Unpack the latest pngbook sources (which should correspond to this + README file) into a folder, open a "DOS shell" or "command prompt" + or equivalent command-line window, and cd into the folder where you + unpacked the source code. + + For MSVC, set up the necessary environment variables by invoking + + %devstudio%\vc\bin\vcvars32.bat + + where where %devstudio% is the installation directory for MSVC / + DevStudio. If you get "environment out of space" errors under 95/98, + create a desktop shortcut with "c:\windows\command.com /e:4096" as + the program command line and set the working directory to the pngbook + directory. Then double-click to open the new DOS-prompt window with + a bigger environment and retry the commands above. + + Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables + appropriately (possibly also the "INC" and "LIB" variables if needed). + Note that the names of the dynamic and static libpng and zlib libraries + used in the makefile may change in later releases of the libraries. + Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work. + This makefile therefore builds statically linked executables, but if + the DLL problems ever get fixed, uncommenting the appropriate PNGLIB + and ZLIB lines will build dynamically linked executables instead. + + Do the build by typing + + nmake + + The result should be three executables: rpng-win.exe, rpng2-win.exe, + and wpng.exe. Copy them somewhere in your PATH or run them from the + current folder. Like the Unix versions, the two windowed programs + (rpng and rpng2) now display a usage screen in a console window when + invoked without command-line arguments; this is new behavior as of + the June 2001 release. Note that the programs use the Unix-style "-" + character to specify options, instead of the more common DOS/Windows + "/" character. (For example: "rpng2-win -bgpat 4 foo.png", not + "rpng2-win /bgpat 4 foo.png") + + + - OpenVMS: + + Unpack the pngbook sources into a subdirectory and change into that + subdirectory. + + Edit makevms.com appropriately, specifically the zpath and pngpath + variables. + + @makevms + + To run the programs, they probably first need to be set up as "foreign + symbols," with "disk" and "dir" set appropriately: + + $ rpng == "$disk:[dir]rpng-x.exe" + $ rpng2 == "$disk:[dir]rpng2-x.exe" + $ wpng == "$disk:[dir]wpng.exe" + + All three will print a basic usage screen when run without any command- + line arguments; see the book for more details. Note that the options + style is Unix-like, i.e., preceded by "-" rather than "/". + + +RUNNING THE PROGRAMS: (VERY) BRIEF INTRO + + rpng is a simple PNG viewer that can display transparent PNGs with a + specified background color; for example, + + rpng -bgcolor #ff0000 toucan.png + + would display the image with a red background. rpng2 is a progressive + viewer that simulates a web browser in some respects; it can display + images against either a background color or a dynamically generated + background image. For example: + + rpng2 -bgpat 16 toucan.png + + wpng is a purely command-line image converter from binary PBMPLUS/NetPBM + format (.pgm or .ppm) to PNG; for example, + + wpng -time < toucan.ppm > toucan.png + + would convert the specified PPM file (using redirection) to PNG, auto- + matically setting the PNG modification-time chunk. + + All options can be abbreviated to the shortest unique value; for example, + "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma. diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/makevms.com b/src/dep/src/irrlicht/libpng/contrib/gregbook/makevms.com new file mode 100644 index 0000000..ae1b999 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/makevms.com @@ -0,0 +1,132 @@ +$!------------------------------------------------------------------------------ +$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS +$! +$! Script created by Martin Zinser for libpng; modified by Greg Roelofs +$! for standalone pngbook source distribution. +$! +$! +$! Set locations where zlib and libpng sources live. +$! +$ zpath = "" +$ pngpath = "" +$! +$ if f$search("[---.zlib]zlib.h").nes."" then zpath = "[---.zlib]" +$ if f$search("[--]png.h").nes."" then pngpath = "[--]" +$! +$ if f$search("[-.zlib]zlib.h").nes."" then zpath = "[-.zlib]" +$ if f$search("[-.libpng]png.h").nes."" then pngpath = "[-.libpng]" +$! +$ if zpath .eqs. "" +$ then +$ write sys$output "zlib include not found. Exiting..." +$ exit 2 +$ endif +$! +$ if pngpath .eqs. "" +$ then +$ write sys$output "libpng include not found. Exiting..." +$ exit 2 +$ endif +$! +$! Look for the compiler used. +$! +$ ccopt="/include=(''zpath',''pngpath')" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" +$ then +$ comp = "__gcc__=1" +$ CC :== GCC +$ else +$ comp = "__vaxc__=1" +$ endif +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$ open/write lopt lib.opt +$ write lopt "''pngpath'libpng.olb/lib" +$ write lopt "''zpath'libz.olb/lib" +$ close lopt +$ open/write xopt x11.opt +$ write xopt "sys$library:decw$xlibshr.exe/share" +$ close xopt +$! +$! Build 'em. +$! +$ write sys$output "Compiling PNG book programs ..." +$ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" - + readpng.c readpng.h +$ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" - + readpng2.c readpng2.h +$ CALL MAKE writepng.OBJ "cc ''CCOPT' writepng" - + writepng.c writepng.h +$ write sys$output "Building rpng-x..." +$ CALL MAKE rpng-x.OBJ "cc ''CCOPT' rpng-x" - + rpng-x.c readpng.h +$ call make rpng-x.exe - + "LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt" - + rpng-x.obj readpng.obj +$ write sys$output "Building rpng2-x..." +$ CALL MAKE rpng2-x.OBJ "cc ''CCOPT' rpng2-x" - + rpng2-x.c readpng2.h +$ call make rpng2-x.exe - + "LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt" - + rpng2-x.obj readpng2.obj +$ write sys$output "Building wpng..." +$ CALL MAKE wpng.OBJ "cc ''CCOPT' wpng" - + wpng.c writepng.h +$ call make wpng.exe - + "LINK wpng,writepng,lib.opt/opt" - + wpng.obj writepng.obj +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.c new file mode 100644 index 0000000..35d49e9 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.c @@ -0,0 +1,280 @@ +/*--------------------------------------------------------------------------- + + rpng - simple PNG display program readpng.c + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2000 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#include +#include + +#include "png.h" /* libpng header; includes zlib.h */ +#include "readpng.h" /* typedefs, common macros, public prototypes */ + +/* future versions of libpng will provide this macro: */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + + +static png_structp png_ptr = NULL; +static png_infop info_ptr = NULL; + +png_uint_32 width, height; +int bit_depth, color_type; +uch *image_data = NULL; + + +void readpng_version_info(void) +{ + fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", + PNG_LIBPNG_VER_STRING, png_libpng_ver); + fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", + ZLIB_VERSION, zlib_version); +} + + +/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */ + +int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight) +{ + uch sig[8]; + + + /* first do a quick check that the file really is a PNG image; could + * have used slightly more general png_sig_cmp() function instead */ + + fread(sig, 1, 8, infile); + if (!png_check_sig(sig, 8)) + return 1; /* bad signature */ + + + /* could pass pointers to user-defined error handlers instead of NULLs: */ + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + return 4; /* out of memory */ + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 4; /* out of memory */ + } + + + /* we could create a second info struct here (end_info), but it's only + * useful if we want to keep pre- and post-IDAT chunk info separated + * (mainly for PNG-aware image editors and converters) */ + + + /* setjmp() must be called in every function that calls a PNG-reading + * libpng function */ + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return 2; + } + + + png_init_io(png_ptr, infile); + png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ + + png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ + + + /* alternatively, could make separate calls to png_get_image_width(), + * etc., but want bit_depth and color_type for later [don't care about + * compression_type and filter_type => NULLs] */ + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + NULL, NULL, NULL); + *pWidth = width; + *pHeight = height; + + + /* OK, that's all we need for now; return happy */ + + return 0; +} + + + + +/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error; + * scales values to 8-bit if necessary */ + +int readpng_get_bgcolor(uch *red, uch *green, uch *blue) +{ + png_color_16p pBackground; + + + /* setjmp() must be called in every function that calls a PNG-reading + * libpng function */ + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return 2; + } + + + if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) + return 1; + + /* it is not obvious from the libpng documentation, but this function + * takes a pointer to a pointer, and it always returns valid red, green + * and blue values, regardless of color_type: */ + + png_get_bKGD(png_ptr, info_ptr, &pBackground); + + + /* however, it always returns the raw bKGD data, regardless of any + * bit-depth transformations, so check depth and adjust if necessary */ + + if (bit_depth == 16) { + *red = pBackground->red >> 8; + *green = pBackground->green >> 8; + *blue = pBackground->blue >> 8; + } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { + if (bit_depth == 1) + *red = *green = *blue = pBackground->gray? 255 : 0; + else if (bit_depth == 2) + *red = *green = *blue = (255/3) * pBackground->gray; + else /* bit_depth == 4 */ + *red = *green = *blue = (255/15) * pBackground->gray; + } else { + *red = (uch)pBackground->red; + *green = (uch)pBackground->green; + *blue = (uch)pBackground->blue; + } + + return 0; +} + + + + +/* display_exponent == LUT_exponent * CRT_exponent */ + +uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) +{ + double gamma; + png_uint_32 i, rowbytes; + png_bytepp row_pointers = NULL; + + + /* setjmp() must be called in every function that calls a PNG-reading + * libpng function */ + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return NULL; + } + + + /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, + * transparency chunks to full alpha channel; strip 16-bit-per-sample + * images to 8 bits per sample; and convert grayscale to RGB[A] */ + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (bit_depth == 16) + png_set_strip_16(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + + /* unlike the example in the libpng documentation, we have *no* idea where + * this file may have come from--so if it doesn't have a file gamma, don't + * do any correction ("do no harm") */ + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, display_exponent, gamma); + + + /* all transformations have been registered; now update info_ptr data, + * get rowbytes and channels, and allocate image memory */ + + png_read_update_info(png_ptr, info_ptr); + + *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); + *pChannels = (int)png_get_channels(png_ptr, info_ptr); + + if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return NULL; + } + if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + free(image_data); + image_data = NULL; + return NULL; + } + + Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n", *pChannels, rowbytes, height)); + + + /* set the individual row_pointers to point at the correct offsets */ + + for (i = 0; i < height; ++i) + row_pointers[i] = image_data + i*rowbytes; + + + /* now we can go ahead and just read the whole image */ + + png_read_image(png_ptr, row_pointers); + + + /* and we're done! (png_read_end() can be omitted if no processing of + * post-IDAT text/time/etc. is desired) */ + + free(row_pointers); + row_pointers = NULL; + + png_read_end(png_ptr, NULL); + + return image_data; +} + + +void readpng_cleanup(int free_image_data) +{ + if (free_image_data && image_data) { + free(image_data); + image_data = NULL; + } + + if (png_ptr && info_ptr) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_ptr = NULL; + info_ptr = NULL; + } +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.h b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.h new file mode 100644 index 0000000..6e378de --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng.h @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------- + + rpng - simple PNG display program readpng.h + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2000 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b)? (a) : (b)) +# define MIN(a,b) ((a) < (b)? (a) : (b)) +#endif + +#ifdef DEBUG +# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} +#else +# define Trace(x) ; +#endif + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + + +/* prototypes for public functions in readpng.c */ + +void readpng_version_info(void); + +int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight); + +int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue); + +uch *readpng_get_image(double display_exponent, int *pChannels, + ulg *pRowbytes); + +void readpng_cleanup(int free_image_data); diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.c new file mode 100644 index 0000000..2f723be --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.c @@ -0,0 +1,624 @@ +/*--------------------------------------------------------------------------- + + rpng2 - progressive-model PNG display program readpng2.c + + --------------------------------------------------------------------------- + + Changelog: + - 1.01: initial public release + - 1.02: added code to skip unused chunks (GR-P) + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2002 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + + +#include /* for exit() prototype */ + +#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ +#include "readpng2.h" /* typedefs, common macros, public prototypes */ + + +/* local prototypes */ + +static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr); +static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass); +static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr); +static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg); + + + + +void readpng2_version_info(void) +{ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \ + (defined(__i386__) || defined(_M_IX86)) && \ + defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + /* + * WARNING: This preprocessor approach means that the following code + * cannot be used with a libpng DLL older than 1.2.0--the + * compiled-in symbols for the new functions will not exist. + * (Could use dlopen() and dlsym() on Unix and corresponding + * calls for Windows, but not portable...) + */ + { + int mmxsupport = png_mmx_support(); + if (mmxsupport < 0) + fprintf(stderr, " Compiled with libpng %s; using libpng %s " + "without MMX support.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver); + else { + int compilerID; + png_uint_32 mmx_mask = png_get_mmx_flagmask( + PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID); + + fprintf(stderr, " Compiled with libpng %s; using libpng %s " + "with MMX support\n (%s version).", PNG_LIBPNG_VER_STRING, + png_libpng_ver, compilerID == 1? "MSVC++" : + (compilerID == 2? "GNU C" : "unknown")); + fprintf(stderr, " Processor %s MMX instructions.\n", + mmxsupport? "supports" : "does not support"); + if (mmxsupport > 0) { + int num_optims = 0; + + fprintf(stderr, + " Potential MMX optimizations supported by libpng:\n"); + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) + ++num_optims; + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_UP) + ++num_optims; + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) + ++num_optims; + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) + ++num_optims; + if (num_optims) + fprintf(stderr, + " decoding %s row filters (reading)\n", + (num_optims == 4)? "all non-trivial" : "some"); + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) { + fprintf(stderr, " combining rows (reading)\n"); + ++num_optims; + } + if (mmx_mask & PNG_ASM_FLAG_MMX_READ_INTERLACE) { + fprintf(stderr, + " expanding interlacing (reading)\n"); + ++num_optims; + } + mmx_mask &= ~( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + if (mmx_mask) { + fprintf(stderr, " other (unknown)\n"); + ++num_optims; + } + if (num_optims == 0) + fprintf(stderr, " (none)\n"); + } + } + } +#else + fprintf(stderr, " Compiled with libpng %s; using libpng %s " + "without MMX support.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver); +#endif + + fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", + ZLIB_VERSION, zlib_version); +} + + + + +int readpng2_check_sig(uch *sig, int num) +{ + return png_check_sig(sig, num); +} + + + + +/* returns 0 for success, 2 for libpng problem, 4 for out of memory */ + +int readpng2_init(mainprog_info *mainprog_ptr) +{ + png_structp png_ptr; /* note: temporary variables! */ + png_infop info_ptr; + + + /* could also replace libpng warning-handler (final NULL), but no need: */ + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, + readpng2_error_handler, NULL); + if (!png_ptr) + return 4; /* out of memory */ + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 4; /* out of memory */ + } + + + /* we could create a second info struct here (end_info), but it's only + * useful if we want to keep pre- and post-IDAT chunk info separated + * (mainly for PNG-aware image editors and converters) */ + + + /* setjmp() must be called in every function that calls a PNG-reading + * libpng function, unless an alternate error handler was installed-- + * but compatible error handlers must either use longjmp() themselves + * (as in this program) or exit immediately, so here we are: */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return 2; + } + + /* prepare the reader to ignore all recognized chunks whose data isn't + * going to be used, i.e., all chunks recognized by libpng except for + * IHDR, PLTE, IDAT, IEND, tRNS, bKGD, gAMA, and sRGB : */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + { +#ifndef HANDLE_CHUNK_NEVER +/* prior to libpng-1.2.5, this macro was internal, so we define it here. */ +# define HANDLE_CHUNK_NEVER 1 +#endif + /* these byte strings were copied from png.h. + * If a future libpng version recognizes more chunks, add them + * to this list. If a future version of readpng2.c recognizes + * more chunks, delete them from this list. */ + png_byte png_chunk_types_to_ignore[]= + { 99, 72, 82, 77, '\0', /* cHRM */ + 104, 73, 83, 84, '\0', /* hIST */ + 105, 67, 67, 80, '\0', /* iCCP */ + 105, 84, 88, 116, '\0', /* iTXt */ + 111, 70, 70, 115, '\0', /* oFFs */ + 112, 67, 65, 76, '\0', /* pCAL */ + 115, 67, 65, 76, '\0', /* sCAL */ + 112, 72, 89, 115, '\0', /* pHYs */ + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 80, 76, 84, '\0', /* sPLT */ + 116, 69, 88, 116, '\0', /* tEXt */ + 116, 73, 77, 69, '\0', /* tIME */ + 122, 84, 88, 116, '\0'}; /* zTXt */ +#define NUM_PNG_CHUNK_TYPES_TO_IGNORE 13 + + png_set_keep_unknown_chunks(png_ptr, HANDLE_CHUNK_NEVER, + png_chunk_types_to_ignore, NUM_PNG_CHUNK_TYPES_TO_IGNORE); + } +#endif + + /* instead of doing png_init_io() here, now we set up our callback + * functions for progressive decoding */ + + png_set_progressive_read_fn(png_ptr, mainprog_ptr, + readpng2_info_callback, readpng2_row_callback, readpng2_end_callback); + + + /* + * may as well enable or disable MMX routines here, if supported; + * + * to enable all: mask = png_get_mmx_flagmask ( + * PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID); + * flags = png_get_asm_flags (png_ptr); + * flags |= mask; + * png_set_asm_flags (png_ptr, flags); + * + * to disable all: mask = png_get_mmx_flagmask ( + * PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID); + * flags = png_get_asm_flags (png_ptr); + * flags &= ~mask; + * png_set_asm_flags (png_ptr, flags); + */ + +#if (defined(__i386__) || defined(_M_IX86)) && \ + defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + /* + * WARNING: This preprocessor approach means that the following code + * cannot be used with a libpng DLL older than 1.2.0--the + * compiled-in symbols for the new functions will not exist. + * (Could use dlopen() and dlsym() on Unix and corresponding + * calls for Windows, but not portable...) + */ + { +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_uint_32 mmx_disable_mask = 0; + png_uint_32 asm_flags, mmx_mask; + int compilerID; + + if (mainprog_ptr->nommxfilters) + mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + if (mainprog_ptr->nommxcombine) + mmx_disable_mask |= PNG_ASM_FLAG_MMX_READ_COMBINE_ROW; + if (mainprog_ptr->nommxinterlace) + mmx_disable_mask |= PNG_ASM_FLAG_MMX_READ_INTERLACE; + asm_flags = png_get_asm_flags(png_ptr); + png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); + + + /* Now query libpng's asm settings, just for yuks. Note that this + * differs from the querying of its *potential* MMX capabilities + * in readpng2_version_info(); this is true runtime verification. */ + + asm_flags = png_get_asm_flags(png_ptr); + mmx_mask = png_get_mmx_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE, + &compilerID); + if (asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) + fprintf(stderr, + " MMX support (%s version) is compiled into libpng\n", + compilerID == 1? "MSVC++" : + (compilerID == 2? "GNU C" : "unknown")); + else + fprintf(stderr, " MMX support is not compiled into libpng\n"); + fprintf(stderr, " MMX instructions are %ssupported by CPU\n", + (asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)? "" : "not "); + fprintf(stderr, " MMX read support for combining rows is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)? "en" : "dis"); + fprintf(stderr, + " MMX read support for expanding interlacing is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)? "en" : "dis"); + fprintf(stderr, " MMX read support for \"sub\" filter is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "en" : "dis"); + fprintf(stderr, " MMX read support for \"up\" filter is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "en" : "dis"); + fprintf(stderr, " MMX read support for \"avg\" filter is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "en" : "dis"); + fprintf(stderr, " MMX read support for \"Paeth\" filter is %sabled\n", + (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "en" : "dis"); + asm_flags &= (mmx_mask & ~( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )); + if (asm_flags) + fprintf(stderr, + " additional MMX support is also enabled (0x%02lx)\n", + asm_flags); +#else /* !PNG_ASSEMBLER_CODE_SUPPORTED */ + fprintf(stderr, " MMX querying is disabled in libpng.\n"); +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + } +#endif + + + /* make sure we save our pointers for use in readpng2_decode_data() */ + + mainprog_ptr->png_ptr = png_ptr; + mainprog_ptr->info_ptr = info_ptr; + + + /* and that's all there is to initialization */ + + return 0; +} + + + + +/* returns 0 for success, 2 for libpng (longjmp) problem */ + +int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length) +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + + /* setjmp() must be called in every function that calls a PNG-reading + * libpng function */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + mainprog_ptr->png_ptr = NULL; + mainprog_ptr->info_ptr = NULL; + return 2; + } + + + /* hand off the next chunk of input data to libpng for decoding */ + + png_process_data(png_ptr, info_ptr, rawbuf, length); + + return 0; +} + + + + +static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) +{ + mainprog_info *mainprog_ptr; + int color_type, bit_depth; + double gamma; + + + /* setjmp() doesn't make sense here, because we'd either have to exit(), + * longjmp() ourselves, or return control to libpng, which doesn't want + * to see us again. By not doing anything here, libpng will instead jump + * to readpng2_decode_data(), which can return an error value to the main + * program. */ + + + /* retrieve the pointer to our special-purpose struct, using the png_ptr + * that libpng passed back to us (i.e., not a global this time--there's + * no real difference for a single image, but for a multithreaded browser + * decoding several PNG images at the same time, one needs to avoid mixing + * up different images' structs) */ + + mainprog_ptr = png_get_progressive_ptr(png_ptr); + + if (mainprog_ptr == NULL) { /* we be hosed */ + fprintf(stderr, + "readpng2 error: main struct not recoverable in info_callback.\n"); + fflush(stderr); + return; + /* + * Alternatively, we could call our error-handler just like libpng + * does, which would effectively terminate the program. Since this + * can only happen if png_ptr gets redirected somewhere odd or the + * main PNG struct gets wiped, we're probably toast anyway. (If + * png_ptr itself is NULL, we would not have been called.) + */ + } + + + /* this is just like in the non-progressive case */ + + png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, + &mainprog_ptr->height, &bit_depth, &color_type, NULL, NULL, NULL); + + + /* since we know we've read all of the PNG file's "header" (i.e., up + * to IDAT), we can check for a background color here */ + + if (mainprog_ptr->need_bgcolor && + png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) + { + png_color_16p pBackground; + + /* it is not obvious from the libpng documentation, but this function + * takes a pointer to a pointer, and it always returns valid red, + * green and blue values, regardless of color_type: */ + png_get_bKGD(png_ptr, info_ptr, &pBackground); + + /* however, it always returns the raw bKGD data, regardless of any + * bit-depth transformations, so check depth and adjust if necessary */ + if (bit_depth == 16) { + mainprog_ptr->bg_red = pBackground->red >> 8; + mainprog_ptr->bg_green = pBackground->green >> 8; + mainprog_ptr->bg_blue = pBackground->blue >> 8; + } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { + if (bit_depth == 1) + mainprog_ptr->bg_red = mainprog_ptr->bg_green = + mainprog_ptr->bg_blue = pBackground->gray? 255 : 0; + else if (bit_depth == 2) + mainprog_ptr->bg_red = mainprog_ptr->bg_green = + mainprog_ptr->bg_blue = (255/3) * pBackground->gray; + else /* bit_depth == 4 */ + mainprog_ptr->bg_red = mainprog_ptr->bg_green = + mainprog_ptr->bg_blue = (255/15) * pBackground->gray; + } else { + mainprog_ptr->bg_red = (uch)pBackground->red; + mainprog_ptr->bg_green = (uch)pBackground->green; + mainprog_ptr->bg_blue = (uch)pBackground->blue; + } + } + + + /* as before, let libpng expand palette images to RGB, low-bit-depth + * grayscale images to 8 bits, transparency chunks to full alpha channel; + * strip 16-bit-per-sample images to 8 bits per sample; and convert + * grayscale to RGB[A] */ + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (bit_depth == 16) + png_set_strip_16(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + + /* Unlike the basic viewer, which was designed to operate on local files, + * this program is intended to simulate a web browser--even though we + * actually read from a local file, too. But because we are pretending + * that most of the images originate on the Internet, we follow the recom- + * mendation of the sRGB proposal and treat unlabelled images (no gAMA + * chunk) as existing in the sRGB color space. That is, we assume that + * such images have a file gamma of 0.45455, which corresponds to a PC-like + * display system. This change in assumptions will have no effect on a + * PC-like system, but on a Mac, SGI, NeXT or other system with a non- + * identity lookup table, it will darken unlabelled images, which effec- + * tively favors images from PC-like systems over those originating on + * the local platform. Note that mainprog_ptr->display_exponent is the + * "gamma" value for the entire display system, i.e., the product of + * LUT_exponent and CRT_exponent. */ + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma); + else + png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455); + + + /* we'll let libpng expand interlaced images, too */ + + mainprog_ptr->passes = png_set_interlace_handling(png_ptr); + + + /* all transformations have been registered; now update info_ptr data and + * then get rowbytes and channels */ + + png_read_update_info(png_ptr, info_ptr); + + mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr); + mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr); + + + /* Call the main program to allocate memory for the image buffer and + * initialize windows and whatnot. (The old-style function-pointer + * invocation is used for compatibility with a few supposedly ANSI + * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */ + + (*mainprog_ptr->mainprog_init)(); + + + /* and that takes care of initialization */ + + return; +} + + + + + +static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) +{ + mainprog_info *mainprog_ptr; + + + /* first check whether the row differs from the previous pass; if not, + * nothing to combine or display */ + + if (!new_row) + return; + + + /* retrieve the pointer to our special-purpose struct so we can access + * the old rows and image-display callback function */ + + mainprog_ptr = png_get_progressive_ptr(png_ptr); + + + /* save the pass number for optional use by the front end */ + + mainprog_ptr->pass = pass; + + + /* have libpng either combine the new row data with the existing row data + * from previous passes (if interlaced) or else just copy the new row + * into the main program's image buffer */ + + png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num], + new_row); + + + /* finally, call the display routine in the main program with the number + * of the row we just updated */ + + (*mainprog_ptr->mainprog_display_row)(row_num); + + + /* and we're ready for more */ + + return; +} + + + + + +static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr) +{ + mainprog_info *mainprog_ptr; + + + /* retrieve the pointer to our special-purpose struct */ + + mainprog_ptr = png_get_progressive_ptr(png_ptr); + + + /* let the main program know that it should flush any buffered image + * data to the display now and set a "done" flag or whatever, but note + * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do + * NOT call readpng2_cleanup() either here or in the finish_display() + * routine; wait until control returns to the main program via + * readpng2_decode_data() */ + + (*mainprog_ptr->mainprog_finish_display)(); + + + /* all done */ + + return; +} + + + + + +void readpng2_cleanup(mainprog_info *mainprog_ptr) +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + if (png_ptr && info_ptr) + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + mainprog_ptr->png_ptr = NULL; + mainprog_ptr->info_ptr = NULL; +} + + + + + +static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg) +{ + mainprog_info *mainprog_ptr; + + /* This function, aside from the extra step of retrieving the "error + * pointer" (below) and the fact that it exists within the application + * rather than within libpng, is essentially identical to libpng's + * default error handler. The second point is critical: since both + * setjmp() and longjmp() are called from the same code, they are + * guaranteed to have compatible notions of how big a jmp_buf is, + * regardless of whether _BSD_SOURCE or anything else has (or has not) + * been defined. */ + + fprintf(stderr, "readpng2 libpng error: %s\n", msg); + fflush(stderr); + + mainprog_ptr = png_get_error_ptr(png_ptr); + if (mainprog_ptr == NULL) { /* we are completely hosed now */ + fprintf(stderr, + "readpng2 severe error: jmpbuf not recoverable; terminating.\n"); + fflush(stderr); + exit(99); + } + + longjmp(mainprog_ptr->jmpbuf, 1); +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.h b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.h new file mode 100644 index 0000000..2ed70d4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/readpng2.h @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------- + + rpng2 - progressive-model PNG display program readpng2.h + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b)? (a) : (b)) +# define MIN(a,b) ((a) < (b)? (a) : (b)) +#endif + +#ifdef DEBUG +# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} +#else +# define Trace(x) ; +#endif + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +typedef struct _mainprog_info { + double display_exponent; + ulg width; + ulg height; + void *png_ptr; + void *info_ptr; + void (*mainprog_init)(void); + void (*mainprog_display_row)(ulg row_num); + void (*mainprog_finish_display)(void); + uch *image_data; + uch **row_pointers; + jmp_buf jmpbuf; + int passes; /* not used */ + int pass; + int rowbytes; + int channels; + int need_bgcolor; +#if (defined(__i386__) || defined(_M_IX86)) + int nommxfilters; + int nommxcombine; + int nommxinterlace; +#endif + int done; + uch bg_red; + uch bg_green; + uch bg_blue; +} mainprog_info; + + +/* prototypes for public functions in readpng2.c */ + +void readpng2_version_info(void); + +int readpng2_check_sig(uch *sig, int num); + +int readpng2_init(mainprog_info *mainprog_ptr); + +int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length); + +void readpng2_cleanup(mainprog_info *mainprog_ptr); diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-win.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-win.c new file mode 100644 index 0000000..b35e3ab --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-win.c @@ -0,0 +1,642 @@ +/*--------------------------------------------------------------------------- + + rpng - simple PNG display program rpng-win.c + + This program decodes and displays PNG images, with gamma correction and + optionally with a user-specified background color (in case the image has + transparency). It is very nearly the most basic PNG viewer possible. + This version is for 32-bit Windows; it may compile under 16-bit Windows + with a little tweaking (or maybe not). + + to do: + - handle quoted command-line args (especially filenames with spaces) + - have minimum window width: oh well + - use %.1023s to simplify truncation of title-bar string? + + --------------------------------------------------------------------------- + + Changelog: + - 1.00: initial public release + - 1.01: modified to allow abbreviated options; fixed long/ulong mis- + match; switched to png_jmpbuf() macro + - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed + command-line parsing bug + - 1.10: enabled "message window"/console (thanks to David Geldreich) + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#define PROGNAME "rpng-win" +#define LONGNAME "Simple PNG Viewer for Windows" +#define VERSION "1.20 of 28 May 2001" + +#include +#include +#include +#include +#include +#include /* only for _getch() */ + +/* #define DEBUG : this enables the Trace() macros */ + +#include "readpng.h" /* typedefs, common macros, readpng prototypes */ + + +/* could just include png.h, but this macro is the only thing we need + * (name and typedefs changed to local versions); note that side effects + * only happen with alpha (which could easily be avoided with + * "ush acopy = (alpha);") */ + +#define alpha_composite(composite, fg, alpha, bg) { \ + ush temp = ((ush)(fg)*(ush)(alpha) + \ + (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ + (composite) = (uch)((temp + (temp >> 8)) >> 8); \ +} + + +/* local prototypes */ +static int rpng_win_create_window(HINSTANCE hInst, int showmode); +static int rpng_win_display_image(void); +static void rpng_win_cleanup(void); +LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM); + + +static char titlebar[1024], *window_name = titlebar; +static char *progname = PROGNAME; +static char *appname = LONGNAME; +static char *icon_name = PROGNAME; /* GRR: not (yet) used */ +static char *filename; +static FILE *infile; + +static char *bgstr; +static uch bg_red=0, bg_green=0, bg_blue=0; + +static double display_exponent; + +static ulg image_width, image_height, image_rowbytes; +static int image_channels; +static uch *image_data; + +/* Windows-specific variables */ +static ulg wimage_rowbytes; +static uch *dib; +static uch *wimage_data; +static BITMAPINFOHEADER *bmih; + +static HWND global_hwnd; + + + + +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) +{ + char *args[1024]; /* arbitrary limit, but should suffice */ + char *p, *q, **argv = args; + int argc = 0; + int rc, alen, flen; + int error = 0; + int have_bg = FALSE; + double LUT_exponent; /* just the lookup table */ + double CRT_exponent = 2.2; /* just the monitor */ + double default_display_exponent; /* whole display system */ + MSG msg; + + + filename = (char *)NULL; + + + /* First reenable console output, which normally goes to the bit bucket + * for windowed apps. Closing the console window will terminate the + * app. Thanks to David.Geldreich@realviz.com for supplying the magical + * incantation. */ + + AllocConsole(); + freopen("CONOUT$", "a", stderr); + freopen("CONOUT$", "a", stdout); + + + /* Next set the default value for our display-system exponent, i.e., + * the product of the CRT exponent and the exponent corresponding to + * the frame-buffer's lookup table (LUT), if any. This is not an + * exhaustive list of LUT values (e.g., OpenStep has a lot of weird + * ones), but it should cover 99% of the current possibilities. And + * yes, these ifdefs are completely wasted in a Windows program... */ + +#if defined(NeXT) + LUT_exponent = 1.0 / 2.2; + /* + if (some_next_function_that_returns_gamma(&next_gamma)) + LUT_exponent = 1.0 / next_gamma; + */ +#elif defined(sgi) + LUT_exponent = 1.0 / 1.7; + /* there doesn't seem to be any documented function to get the + * "gamma" value, so we do it the hard way */ + infile = fopen("/etc/config/system.glGammaVal", "r"); + if (infile) { + double sgi_gamma; + + fgets(tmpline, 80, infile); + fclose(infile); + sgi_gamma = atof(tmpline); + if (sgi_gamma > 0.0) + LUT_exponent = 1.0 / sgi_gamma; + } +#elif defined(Macintosh) + LUT_exponent = 1.8 / 2.61; + /* + if (some_mac_function_that_returns_gamma(&mac_gamma)) + LUT_exponent = mac_gamma / 2.61; + */ +#else + LUT_exponent = 1.0; /* assume no LUT: most PCs */ +#endif + + /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ + default_display_exponent = LUT_exponent * CRT_exponent; + + + /* If the user has set the SCREEN_GAMMA environment variable as suggested + * (somewhat imprecisely) in the libpng documentation, use that; otherwise + * use the default value we just calculated. Either way, the user may + * override this via a command-line option. */ + + if ((p = getenv("SCREEN_GAMMA")) != NULL) + display_exponent = atof(p); + else + display_exponent = default_display_exponent; + + + /* Windows really hates command lines, so we have to set up our own argv. + * Note that we do NOT bother with quoted arguments here, so don't use + * filenames with spaces in 'em! */ + + argv[argc++] = PROGNAME; + p = cmd; + for (;;) { + if (*p == ' ') + while (*++p == ' ') + ; + /* now p points at the first non-space after some spaces */ + if (*p == '\0') + break; /* nothing after the spaces: done */ + argv[argc++] = q = p; + while (*q && *q != ' ') + ++q; + /* now q points at a space or the end of the string */ + if (*q == '\0') + break; /* last argv already terminated; quit */ + *q = '\0'; /* change space to terminator */ + p = q + 1; + } + argv[argc] = NULL; /* terminate the argv array itself */ + + + /* Now parse the command line for options and the PNG filename. */ + + while (*++argv && !error) { + if (!strncmp(*argv, "-gamma", 2)) { + if (!*++argv) + ++error; + else { + display_exponent = atof(*argv); + if (display_exponent <= 0.0) + ++error; + } + } else if (!strncmp(*argv, "-bgcolor", 2)) { + if (!*++argv) + ++error; + else { + bgstr = *argv; + if (strlen(bgstr) != 7 || bgstr[0] != '#') + ++error; + else + have_bg = TRUE; + } + } else { + if (**argv != '-') { + filename = *argv; + if (argv[1]) /* shouldn't be any more args after filename */ + ++error; + } else + ++error; /* not expecting any other options */ + } + } + + if (!filename) { + ++error; + } else if (!(infile = fopen(filename, "rb"))) { + fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); + ++error; + } else { + if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { + switch (rc) { + case 1: + fprintf(stderr, PROGNAME + ": [%s] is not a PNG file: incorrect signature\n", + filename); + break; + case 2: + fprintf(stderr, PROGNAME + ": [%s] has bad IHDR (libpng longjmp)\n", + filename); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown readpng_init() error\n"); + break; + } + ++error; + } + if (error) + fclose(infile); + } + + + /* usage screen */ + + if (error) { + int ch; + + fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); + readpng_version_info(); + fprintf(stderr, "\n" + "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n" + " exp \ttransfer-function exponent (``gamma'') of the display\n" + "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" + "\t\t to the product of the lookup-table exponent (varies)\n" + "\t\t and the CRT exponent (usually 2.2); must be positive\n" + " bg \tdesired background color in 7-character hex RGB format\n" + "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" + "\t\t used with transparent images\n" + "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" + "Press Q or Esc to quit this usage screen.\n" + "\n", PROGNAME, default_display_exponent); + do + ch = _getch(); + while (ch != 'q' && ch != 'Q' && ch != 0x1B); + exit(1); + } else { + fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); + fprintf(stderr, + "\n [console window: closing this window will terminate %s]\n\n", + PROGNAME); + } + + + /* set the title-bar string, but make sure buffer doesn't overflow */ + + alen = strlen(appname); + flen = strlen(filename); + if (alen + flen + 3 > 1023) + sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); + else + sprintf(titlebar, "%s: %s", appname, filename); + + + /* if the user didn't specify a background color on the command line, + * check for one in the PNG file--if not, the initialized values of 0 + * (black) will be used */ + + if (have_bg) + sscanf(bgstr+1, "%2x%2x%2x", &bg_red, &bg_green, &bg_blue); + else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { + readpng_cleanup(TRUE); + fprintf(stderr, PROGNAME + ": libpng error while checking for background color\n"); + exit(2); + } + + + /* do the basic Windows initialization stuff, make the window and fill it + * with the background color */ + + if (rpng_win_create_window(hInst, showmode)) + exit(2); + + + /* decode the image, all at once */ + + Trace((stderr, "calling readpng_get_image()\n")) + image_data = readpng_get_image(display_exponent, &image_channels, + &image_rowbytes); + Trace((stderr, "done with readpng_get_image()\n")) + + + /* done with PNG file, so clean up to minimize memory usage (but do NOT + * nuke image_data!) */ + + readpng_cleanup(FALSE); + fclose(infile); + + if (!image_data) { + fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); + exit(3); + } + + + /* display image (composite with background if requested) */ + + Trace((stderr, "calling rpng_win_display_image()\n")) + if (rpng_win_display_image()) { + free(image_data); + exit(4); + } + Trace((stderr, "done with rpng_win_display_image()\n")) + + + /* wait for the user to tell us when to quit */ + + printf( + "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); + fflush(stdout); + + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + + /* OK, we're done: clean up all image and Windows resources and go away */ + + rpng_win_cleanup(); + + return msg.wParam; +} + + + + + +static int rpng_win_create_window(HINSTANCE hInst, int showmode) +{ + uch *dest; + int extra_width, extra_height; + ulg i, j; + WNDCLASSEX wndclass; + + +/*--------------------------------------------------------------------------- + Allocate memory for the display-specific version of the image (round up + to multiple of 4 for Windows DIB). + ---------------------------------------------------------------------------*/ + + wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; + + if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + + wimage_rowbytes*image_height))) + { + return 4; /* fail */ + } + +/*--------------------------------------------------------------------------- + Initialize the DIB. Negative height means to use top-down BMP ordering + (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 + implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values + directly => wimage_data begins immediately after BMP header. + ---------------------------------------------------------------------------*/ + + memset(dib, 0, sizeof(BITMAPINFOHEADER)); + bmih = (BITMAPINFOHEADER *)dib; + bmih->biSize = sizeof(BITMAPINFOHEADER); + bmih->biWidth = image_width; + bmih->biHeight = -((long)image_height); + bmih->biPlanes = 1; + bmih->biBitCount = 24; + bmih->biCompression = 0; + wimage_data = dib + sizeof(BITMAPINFOHEADER); + +/*--------------------------------------------------------------------------- + Fill in background color (black by default); data are in BGR order. + ---------------------------------------------------------------------------*/ + + for (j = 0; j < image_height; ++j) { + dest = wimage_data + j*wimage_rowbytes; + for (i = image_width; i > 0; --i) { + *dest++ = bg_blue; + *dest++ = bg_green; + *dest++ = bg_red; + } + } + +/*--------------------------------------------------------------------------- + Set the window parameters. + ---------------------------------------------------------------------------*/ + + memset(&wndclass, 0, sizeof(wndclass)); + + wndclass.cbSize = sizeof(wndclass); + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = rpng_win_wndproc; + wndclass.hInstance = hInst; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = progname; + wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + RegisterClassEx(&wndclass); + +/*--------------------------------------------------------------------------- + Finally, create the window. + ---------------------------------------------------------------------------*/ + + extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + + GetSystemMetrics(SM_CXDLGFRAME)); + extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYDLGFRAME)) + + GetSystemMetrics(SM_CYCAPTION); + + global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width, + image_height+extra_height, NULL, NULL, hInst, NULL); + + ShowWindow(global_hwnd, showmode); + UpdateWindow(global_hwnd); + + return 0; + +} /* end function rpng_win_create_window() */ + + + + + +static int rpng_win_display_image() +{ + uch *src, *dest; + uch r, g, b, a; + ulg i, row, lastrow; + RECT rect; + + + Trace((stderr, "beginning display loop (image_channels == %d)\n", + image_channels)) + Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n", + image_width, image_rowbytes, wimage_rowbytes)) + + +/*--------------------------------------------------------------------------- + Blast image data to buffer. This whole routine takes place before the + message loop begins, so there's no real point in any pseudo-progressive + display... + ---------------------------------------------------------------------------*/ + + for (lastrow = row = 0; row < image_height; ++row) { + src = image_data + row*image_rowbytes; + dest = wimage_data + row*wimage_rowbytes; + if (image_channels == 3) { + for (i = image_width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + *dest++ = b; + *dest++ = g; /* note reverse order */ + *dest++ = r; + } + } else /* if (image_channels == 4) */ { + for (i = image_width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (a == 255) { + *dest++ = b; + *dest++ = g; + *dest++ = r; + } else if (a == 0) { + *dest++ = bg_blue; + *dest++ = bg_green; + *dest++ = bg_red; + } else { + /* this macro (copied from png.h) composites the + * foreground and background values and puts the + * result into the first argument; there are no + * side effects with the first argument */ + alpha_composite(*dest++, b, a, bg_blue); + alpha_composite(*dest++, g, a, bg_green); + alpha_composite(*dest++, r, a, bg_red); + } + } + } + /* display after every 16 lines */ + if (((row+1) & 0xf) == 0) { + rect.left = 0L; + rect.top = (LONG)lastrow; + rect.right = (LONG)image_width; /* possibly off by one? */ + rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */ + InvalidateRect(global_hwnd, &rect, FALSE); + UpdateWindow(global_hwnd); /* similar to XFlush() */ + lastrow = row + 1; + } + } + + Trace((stderr, "calling final image-flush routine\n")) + if (lastrow < image_height) { + rect.left = 0L; + rect.top = (LONG)lastrow; + rect.right = (LONG)image_width; /* possibly off by one? */ + rect.bottom = (LONG)image_height; /* possibly off by one? */ + InvalidateRect(global_hwnd, &rect, FALSE); + UpdateWindow(global_hwnd); /* similar to XFlush() */ + } + +/* + last param determines whether or not background is wiped before paint + InvalidateRect(global_hwnd, NULL, TRUE); + UpdateWindow(global_hwnd); + */ + + return 0; +} + + + + + +static void rpng_win_cleanup() +{ + if (image_data) { + free(image_data); + image_data = NULL; + } + + if (dib) { + free(dib); + dib = NULL; + } +} + + + + + +LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) +{ + HDC hdc; + PAINTSTRUCT ps; + int rc; + + switch (iMsg) { + case WM_CREATE: + /* one-time processing here, if any */ + return 0; + + case WM_PAINT: + hdc = BeginPaint(hwnd, &ps); + /* dest */ + rc = StretchDIBits(hdc, 0, 0, image_width, image_height, + /* source */ + 0, 0, image_width, image_height, + wimage_data, (BITMAPINFO *)bmih, + /* iUsage: no clue */ + 0, SRCCOPY); + EndPaint(hwnd, &ps); + return 0; + + /* wait for the user to tell us when to quit */ + case WM_CHAR: + switch (wP) { /* only need one, so ignore repeat count */ + case 'q': + case 'Q': + case 0x1B: /* Esc key */ + PostQuitMessage(0); + } + return 0; + + case WM_LBUTTONDOWN: /* another way of quitting */ + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, iMsg, wP, lP); +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-x.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-x.c new file mode 100644 index 0000000..0623397 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng-x.c @@ -0,0 +1,858 @@ +/*--------------------------------------------------------------------------- + + rpng - simple PNG display program rpng-x.c + + This program decodes and displays PNG images, with gamma correction and + optionally with a user-specified background color (in case the image has + transparency). It is very nearly the most basic PNG viewer possible. + This version is for the X Window System (tested by author under Unix and + by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking). + + to do: + - 8-bit support + - use %.1023s to simplify truncation of title-bar string? + + --------------------------------------------------------------------------- + + Changelog: + - 1.01: initial public release + - 1.02: modified to allow abbreviated options; fixed long/ulong mis- + match; switched to png_jmpbuf() macro + - 1.10: added support for non-default visuals; fixed X pixel-conversion + - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed + command-line parsing bug + - 1.12: fixed small X memory leak (thanks to Francois Petitjean) + - 1.13: fixed XFreeGC() crash bug + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#define PROGNAME "rpng-x" +#define LONGNAME "Simple PNG Viewer for X" +#define VERSION "1.13 of 16 August 2001" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* #define DEBUG : this enables the Trace() macros */ + +#include "readpng.h" /* typedefs, common macros, readpng prototypes */ + + +/* could just include png.h, but this macro is the only thing we need + * (name and typedefs changed to local versions); note that side effects + * only happen with alpha (which could easily be avoided with + * "ush acopy = (alpha);") */ + +#define alpha_composite(composite, fg, alpha, bg) { \ + ush temp = ((ush)(fg)*(ush)(alpha) + \ + (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ + (composite) = (uch)((temp + (temp >> 8)) >> 8); \ +} + + +/* local prototypes */ +static int rpng_x_create_window(void); +static int rpng_x_display_image(void); +static void rpng_x_cleanup(void); +static int rpng_x_msb(ulg u32val); + + +static char titlebar[1024], *window_name = titlebar; +static char *appname = LONGNAME; +static char *icon_name = PROGNAME; +static char *filename; +static FILE *infile; + +static char *bgstr; +static uch bg_red=0, bg_green=0, bg_blue=0; + +static double display_exponent; + +static ulg image_width, image_height, image_rowbytes; +static int image_channels; +static uch *image_data; + +/* X-specific variables */ +static char *displayname; +static XImage *ximage; +static Display *display; +static int depth; +static Visual *visual; +static XVisualInfo *visual_list; +static int RShift, GShift, BShift; +static ulg RMask, GMask, BMask; +static Window window; +static GC gc; +static Colormap colormap; + +static int have_nondefault_visual = FALSE; +static int have_colormap = FALSE; +static int have_window = FALSE; +static int have_gc = FALSE; +/* +ulg numcolors=0, pixels[256]; +ush reds[256], greens[256], blues[256]; + */ + + + + +int main(int argc, char **argv) +{ +#ifdef sgi + char tmpline[80]; +#endif + char *p; + int rc, alen, flen; + int error = 0; + int have_bg = FALSE; + double LUT_exponent; /* just the lookup table */ + double CRT_exponent = 2.2; /* just the monitor */ + double default_display_exponent; /* whole display system */ + XEvent e; + KeySym k; + + + displayname = (char *)NULL; + filename = (char *)NULL; + + + /* First set the default value for our display-system exponent, i.e., + * the product of the CRT exponent and the exponent corresponding to + * the frame-buffer's lookup table (LUT), if any. This is not an + * exhaustive list of LUT values (e.g., OpenStep has a lot of weird + * ones), but it should cover 99% of the current possibilities. */ + +#if defined(NeXT) + LUT_exponent = 1.0 / 2.2; + /* + if (some_next_function_that_returns_gamma(&next_gamma)) + LUT_exponent = 1.0 / next_gamma; + */ +#elif defined(sgi) + LUT_exponent = 1.0 / 1.7; + /* there doesn't seem to be any documented function to get the + * "gamma" value, so we do it the hard way */ + infile = fopen("/etc/config/system.glGammaVal", "r"); + if (infile) { + double sgi_gamma; + + fgets(tmpline, 80, infile); + fclose(infile); + sgi_gamma = atof(tmpline); + if (sgi_gamma > 0.0) + LUT_exponent = 1.0 / sgi_gamma; + } +#elif defined(Macintosh) + LUT_exponent = 1.8 / 2.61; + /* + if (some_mac_function_that_returns_gamma(&mac_gamma)) + LUT_exponent = mac_gamma / 2.61; + */ +#else + LUT_exponent = 1.0; /* assume no LUT: most PCs */ +#endif + + /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ + default_display_exponent = LUT_exponent * CRT_exponent; + + + /* If the user has set the SCREEN_GAMMA environment variable as suggested + * (somewhat imprecisely) in the libpng documentation, use that; otherwise + * use the default value we just calculated. Either way, the user may + * override this via a command-line option. */ + + if ((p = getenv("SCREEN_GAMMA")) != NULL) + display_exponent = atof(p); + else + display_exponent = default_display_exponent; + + + /* Now parse the command line for options and the PNG filename. */ + + while (*++argv && !error) { + if (!strncmp(*argv, "-display", 2)) { + if (!*++argv) + ++error; + else + displayname = *argv; + } else if (!strncmp(*argv, "-gamma", 2)) { + if (!*++argv) + ++error; + else { + display_exponent = atof(*argv); + if (display_exponent <= 0.0) + ++error; + } + } else if (!strncmp(*argv, "-bgcolor", 2)) { + if (!*++argv) + ++error; + else { + bgstr = *argv; + if (strlen(bgstr) != 7 || bgstr[0] != '#') + ++error; + else + have_bg = TRUE; + } + } else { + if (**argv != '-') { + filename = *argv; + if (argv[1]) /* shouldn't be any more args after filename */ + ++error; + } else + ++error; /* not expecting any other options */ + } + } + + if (!filename) { + ++error; + } else if (!(infile = fopen(filename, "rb"))) { + fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); + ++error; + } else { + if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { + switch (rc) { + case 1: + fprintf(stderr, PROGNAME + ": [%s] is not a PNG file: incorrect signature\n", + filename); + break; + case 2: + fprintf(stderr, PROGNAME + ": [%s] has bad IHDR (libpng longjmp)\n", + filename); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown readpng_init() error\n"); + break; + } + ++error; + } else { + display = XOpenDisplay(displayname); + if (!display) { + readpng_cleanup(TRUE); + fprintf(stderr, PROGNAME ": can't open X display [%s]\n", + displayname? displayname : "default"); + ++error; + } + } + if (error) + fclose(infile); + } + + + /* usage screen */ + + if (error) { + fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); + readpng_version_info(); + fprintf(stderr, "\n" + "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n" + " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" + " exp \ttransfer-function exponent (``gamma'') of the display\n" + "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" + "\t\t to the product of the lookup-table exponent (varies)\n" + "\t\t and the CRT exponent (usually 2.2); must be positive\n" + " bg \tdesired background color in 7-character hex RGB format\n" + "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" + "\t\t used with transparent images\n" + "\nPress Q, Esc or mouse button 1 (within image window, after image\n" + "is displayed) to quit.\n" + "\n", PROGNAME, default_display_exponent); + exit(1); + } + + + /* set the title-bar string, but make sure buffer doesn't overflow */ + + alen = strlen(appname); + flen = strlen(filename); + if (alen + flen + 3 > 1023) + sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); + else + sprintf(titlebar, "%s: %s", appname, filename); + + + /* if the user didn't specify a background color on the command line, + * check for one in the PNG file--if not, the initialized values of 0 + * (black) will be used */ + + if (have_bg) { + unsigned r, g, b; /* this approach quiets compiler warnings */ + + sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); + bg_red = (uch)r; + bg_green = (uch)g; + bg_blue = (uch)b; + } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { + readpng_cleanup(TRUE); + fprintf(stderr, PROGNAME + ": libpng error while checking for background color\n"); + exit(2); + } + + + /* do the basic X initialization stuff, make the window and fill it + * with the background color */ + + if (rpng_x_create_window()) + exit(2); + + + /* decode the image, all at once */ + + Trace((stderr, "calling readpng_get_image()\n")) + image_data = readpng_get_image(display_exponent, &image_channels, + &image_rowbytes); + Trace((stderr, "done with readpng_get_image()\n")) + + + /* done with PNG file, so clean up to minimize memory usage (but do NOT + * nuke image_data!) */ + + readpng_cleanup(FALSE); + fclose(infile); + + if (!image_data) { + fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); + exit(3); + } + + + /* display image (composite with background if requested) */ + + Trace((stderr, "calling rpng_x_display_image()\n")) + if (rpng_x_display_image()) { + free(image_data); + exit(4); + } + Trace((stderr, "done with rpng_x_display_image()\n")) + + + /* wait for the user to tell us when to quit */ + + printf( + "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); + fflush(stdout); + + do + XNextEvent(display, &e); + while (!(e.type == ButtonPress && e.xbutton.button == Button1) && + !(e.type == KeyPress && /* v--- or 1 for shifted keys */ + ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )); + + + /* OK, we're done: clean up all image and X resources and go away */ + + rpng_x_cleanup(); + + return 0; +} + + + + + +static int rpng_x_create_window(void) +{ + uch *xdata; + int need_colormap = FALSE; + int screen, pad; + ulg bg_pixel = 0L; + ulg attrmask; + Window root; + XEvent e; + XGCValues gcvalues; + XSetWindowAttributes attr; + XSizeHints *size_hints; + XTextProperty windowName, *pWindowName = &windowName; + XTextProperty iconName, *pIconName = &iconName; + XVisualInfo visual_info; + XWMHints *wm_hints; + + + screen = DefaultScreen(display); + depth = DisplayPlanes(display, screen); + root = RootWindow(display, screen); + +#ifdef DEBUG + XSynchronize(display, True); +#endif + +#if 0 +/* GRR: add 8-bit support */ + if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) { + fprintf(stderr, + "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n", + depth); + return 2; + } + + XMatchVisualInfo(display, screen, depth, + (depth == 8)? PseudoColor : TrueColor, &visual_info); + visual = visual_info.visual; +#else + if (depth != 16 && depth != 24 && depth != 32) { + int visuals_matched = 0; + + Trace((stderr, "default depth is %d: checking other visuals\n", + depth)) + + /* 24-bit first */ + visual_info.screen = screen; + visual_info.depth = 24; + visual_list = XGetVisualInfo(display, + VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); + if (visuals_matched == 0) { +/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ + fprintf(stderr, "default screen depth %d not supported, and no" + " 24-bit visuals found\n", depth); + return 2; + } + Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", + visuals_matched)) + visual = visual_list[0].visual; + depth = visual_list[0].depth; +/* + colormap_size = visual_list[0].colormap_size; + visual_class = visual->class; + visualID = XVisualIDFromVisual(visual); + */ + have_nondefault_visual = TRUE; + need_colormap = TRUE; + } else { + XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); + visual = visual_info.visual; + } +#endif + + RMask = visual->red_mask; + GMask = visual->green_mask; + BMask = visual->blue_mask; + +/* GRR: add/check 8-bit support */ + if (depth == 8 || need_colormap) { + colormap = XCreateColormap(display, root, visual, AllocNone); + if (!colormap) { + fprintf(stderr, "XCreateColormap() failed\n"); + return 2; + } + have_colormap = TRUE; + } + if (depth == 15 || depth == 16) { + RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */ + GShift = 15 - rpng_x_msb(GMask); + BShift = 15 - rpng_x_msb(BMask); + } else if (depth > 16) { +#define NO_24BIT_MASKS +#ifdef NO_24BIT_MASKS + RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */ + GShift = rpng_x_msb(GMask) - 7; + BShift = rpng_x_msb(BMask) - 7; +#else + RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */ + GShift = 7 - rpng_x_msb(GMask); + BShift = 7 - rpng_x_msb(BMask); +#endif + } + if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { + fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n"); + return 2; + } + +/*--------------------------------------------------------------------------- + Finally, create the window. + ---------------------------------------------------------------------------*/ + + attr.backing_store = Always; + attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; + attrmask = CWBackingStore | CWEventMask; + if (have_nondefault_visual) { + attr.colormap = colormap; + attr.background_pixel = 0; + attr.border_pixel = 1; + attrmask |= CWColormap | CWBackPixel | CWBorderPixel; + } + + window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0, + depth, InputOutput, visual, attrmask, &attr); + + if (window == None) { + fprintf(stderr, "XCreateWindow() failed\n"); + return 2; + } else + have_window = TRUE; + + if (depth == 8) + XSetWindowColormap(display, window, colormap); + + if (!XStringListToTextProperty(&window_name, 1, pWindowName)) + pWindowName = NULL; + if (!XStringListToTextProperty(&icon_name, 1, pIconName)) + pIconName = NULL; + + /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */ + + if ((size_hints = XAllocSizeHints()) != NULL) { + /* window will not be resizable */ + size_hints->flags = PMinSize | PMaxSize; + size_hints->min_width = size_hints->max_width = (int)image_width; + size_hints->min_height = size_hints->max_height = (int)image_height; + } + + if ((wm_hints = XAllocWMHints()) != NULL) { + wm_hints->initial_state = NormalState; + wm_hints->input = True; + /* wm_hints->icon_pixmap = icon_pixmap; */ + wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; + } + + XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, + size_hints, wm_hints, NULL); + + /* various properties and hints no longer needed; free memory */ + if (pWindowName) + XFree(pWindowName->value); + if (pIconName) + XFree(pIconName->value); + if (size_hints) + XFree(size_hints); + if (wm_hints) + XFree(wm_hints); + + XMapWindow(display, window); + + gc = XCreateGC(display, window, 0, &gcvalues); + have_gc = TRUE; + +/*--------------------------------------------------------------------------- + Fill window with the specified background color. + ---------------------------------------------------------------------------*/ + + if (depth == 24 || depth == 32) { + bg_pixel = ((ulg)bg_red << RShift) | + ((ulg)bg_green << GShift) | + ((ulg)bg_blue << BShift); + } else if (depth == 16) { + bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) | + ((((ulg)bg_green << 8) >> GShift) & GMask) | + ((((ulg)bg_blue << 8) >> BShift) & BMask); + } else /* depth == 8 */ { + + /* GRR: add 8-bit support */ + + } + + XSetForeground(display, gc, bg_pixel); + XFillRectangle(display, window, gc, 0, 0, image_width, image_height); + +/*--------------------------------------------------------------------------- + Wait for first Expose event to do any drawing, then flush. + ---------------------------------------------------------------------------*/ + + do + XNextEvent(display, &e); + while (e.type != Expose || e.xexpose.count); + + XFlush(display); + +/*--------------------------------------------------------------------------- + Allocate memory for the X- and display-specific version of the image. + ---------------------------------------------------------------------------*/ + + if (depth == 24 || depth == 32) { + xdata = (uch *)malloc(4*image_width*image_height); + pad = 32; + } else if (depth == 16) { + xdata = (uch *)malloc(2*image_width*image_height); + pad = 16; + } else /* depth == 8 */ { + xdata = (uch *)malloc(image_width*image_height); + pad = 8; + } + + if (!xdata) { + fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); + return 4; + } + + ximage = XCreateImage(display, visual, depth, ZPixmap, 0, + (char *)xdata, image_width, image_height, pad, 0); + + if (!ximage) { + fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); + free(xdata); + return 3; + } + + /* to avoid testing the byte order every pixel (or doubling the size of + * the drawing routine with a giant if-test), we arbitrarily set the byte + * order to MSBFirst and let Xlib worry about inverting things on little- + * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most + * efficient approach (the giant if-test would be better), but in the + * interest of clarity, we take the easy way out... */ + + ximage->byte_order = MSBFirst; + + return 0; + +} /* end function rpng_x_create_window() */ + + + + + +static int rpng_x_display_image(void) +{ + uch *src; + char *dest; + uch r, g, b, a; + ulg i, row, lastrow = 0; + ulg pixel; + int ximage_rowbytes = ximage->bytes_per_line; +/* int bpp = ximage->bits_per_pixel; */ + + + Trace((stderr, "beginning display loop (image_channels == %d)\n", + image_channels)) + Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n", + image_width, image_rowbytes, ximage_rowbytes)) + Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel)) + Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst? + "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown"))) + + if (depth == 24 || depth == 32) { + ulg red, green, blue; + + for (lastrow = row = 0; row < image_height; ++row) { + src = image_data + row*image_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + if (image_channels == 3) { + for (i = image_width; i > 0; --i) { + red = *src++; + green = *src++; + blue = *src++; +#ifdef NO_24BIT_MASKS + pixel = (red << RShift) | + (green << GShift) | + (blue << BShift); + /* recall that we set ximage->byte_order = MSBFirst above */ + /* GRR BUG: this assumes bpp == 32, but may be 24: */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); +#else + red = (RShift < 0)? red << (-RShift) : red >> RShift; + green = (GShift < 0)? green << (-GShift) : green >> GShift; + blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; + pixel = (red & RMask) | (green & GMask) | (blue & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); +#endif + } + } else /* if (image_channels == 4) */ { + for (i = image_width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (a == 255) { + red = r; + green = g; + blue = b; + } else if (a == 0) { + red = bg_red; + green = bg_green; + blue = bg_blue; + } else { + /* this macro (from png.h) composites the foreground + * and background values and puts the result into the + * first argument */ + alpha_composite(red, r, a, bg_red); + alpha_composite(green, g, a, bg_green); + alpha_composite(blue, b, a, bg_blue); + } + pixel = (red << RShift) | + (green << GShift) | + (blue << BShift); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + /* display after every 16 lines */ + if (((row+1) & 0xf) == 0) { + XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, + (int)lastrow, image_width, 16); + XFlush(display); + lastrow = row + 1; + } + } + + } else if (depth == 16) { + ush red, green, blue; + + for (lastrow = row = 0; row < image_height; ++row) { + src = image_data + row*image_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + if (image_channels == 3) { + for (i = image_width; i > 0; --i) { + red = ((ush)(*src) << 8); + ++src; + green = ((ush)(*src) << 8); + ++src; + blue = ((ush)(*src) << 8); + ++src; + pixel = ((red >> RShift) & RMask) | + ((green >> GShift) & GMask) | + ((blue >> BShift) & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } else /* if (image_channels == 4) */ { + for (i = image_width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (a == 255) { + red = ((ush)r << 8); + green = ((ush)g << 8); + blue = ((ush)b << 8); + } else if (a == 0) { + red = ((ush)bg_red << 8); + green = ((ush)bg_green << 8); + blue = ((ush)bg_blue << 8); + } else { + /* this macro (from png.h) composites the foreground + * and background values and puts the result back into + * the first argument (== fg byte here: safe) */ + alpha_composite(r, r, a, bg_red); + alpha_composite(g, g, a, bg_green); + alpha_composite(b, b, a, bg_blue); + red = ((ush)r << 8); + green = ((ush)g << 8); + blue = ((ush)b << 8); + } + pixel = ((red >> RShift) & RMask) | + ((green >> GShift) & GMask) | + ((blue >> BShift) & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + /* display after every 16 lines */ + if (((row+1) & 0xf) == 0) { + XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, + (int)lastrow, image_width, 16); + XFlush(display); + lastrow = row + 1; + } + } + + } else /* depth == 8 */ { + + /* GRR: add 8-bit support */ + + } + + Trace((stderr, "calling final XPutImage()\n")) + if (lastrow < image_height) { + XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, + (int)lastrow, image_width, image_height-lastrow); + XFlush(display); + } + + return 0; +} + + + + +static void rpng_x_cleanup(void) +{ + if (image_data) { + free(image_data); + image_data = NULL; + } + + if (ximage) { + if (ximage->data) { + free(ximage->data); /* we allocated it, so we free it */ + ximage->data = (char *)NULL; /* instead of XDestroyImage() */ + } + XDestroyImage(ximage); + ximage = NULL; + } + + if (have_gc) + XFreeGC(display, gc); + + if (have_window) + XDestroyWindow(display, window); + + if (have_colormap) + XFreeColormap(display, colormap); + + if (have_nondefault_visual) + XFree(visual_list); +} + + + + + +static int rpng_x_msb(ulg u32val) +{ + int i; + + for (i = 31; i >= 0; --i) { + if (u32val & 0x80000000L) + break; + u32val <<= 1; + } + return i; +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-win.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-win.c new file mode 100644 index 0000000..46f2191 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-win.c @@ -0,0 +1,1166 @@ +/*--------------------------------------------------------------------------- + + rpng2 - progressive-model PNG display program rpng2-win.c + + This program decodes and displays PNG files progressively, as if it were + a web browser (though the front end is only set up to read from files). + It supports gamma correction, user-specified background colors, and user- + specified background patterns (for transparent images). This version is + for 32-bit Windows; it may compile under 16-bit Windows with a little + tweaking (or maybe not). Thanks to Adam Costello and Pieter S. van der + Meulen for the "diamond" and "radial waves" patterns, respectively. + + to do: + - handle quoted command-line args (especially filenames with spaces) + - finish resizable checkerboard-gradient (sizes 4-128?) + - use %.1023s to simplify truncation of title-bar string? + - have minimum window width: oh well + + --------------------------------------------------------------------------- + + Changelog: + - 1.01: initial public release + - 1.02: fixed cut-and-paste error in usage screen (oops...) + - 1.03: modified to allow abbreviated options + - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?]; + fixed command-line parsing bug + - 1.10: enabled "message window"/console (thanks to David Geldreich) + - 1.20: added runtime MMX-enabling/disabling and new -mmx* options + - 1.21: made minor tweak to usage screen to fit within 25-line console + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#define PROGNAME "rpng2-win" +#define LONGNAME "Progressive PNG Viewer for Windows" +#define VERSION "1.21 of 29 June 2001" + +#include +#include +#include +#include /* for jmpbuf declaration in readpng2.h */ +#include +#include /* only for PvdM background code */ +#include +#include /* only for _getch() */ + +/* all for PvdM background code: */ +#ifndef PI +# define PI 3.141592653589793238 +#endif +#define PI_2 (PI*0.5) +#define INV_PI_360 (360.0 / PI) +#define MAX(a,b) (a>b?a:b) +#define MIN(a,b) (a> 8)) >> 8); \ +} + + +#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this + * block size corresponds roughly to a download + * speed 10% faster than theoretical 33.6K maximum + * (assuming 8 data bits, 1 stop bit and no other + * overhead) */ + +/* local prototypes */ +static void rpng2_win_init(void); +static int rpng2_win_create_window(void); +static int rpng2_win_load_bg_image(void); +static void rpng2_win_display_row(ulg row); +static void rpng2_win_finish_display(void); +static void rpng2_win_cleanup(void); +LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM); + + +static char titlebar[1024], *window_name = titlebar; +static char *progname = PROGNAME; +static char *appname = LONGNAME; +static char *icon_name = PROGNAME; /* GRR: not (yet) used */ +static char *filename; +static FILE *infile; + +static mainprog_info rpng2_info; + +static uch inbuf[INBUFSIZE]; +static int incount; + +static int pat = 6; /* must be less than num_bgpat */ +static int bg_image = 0; +static int bgscale = 16; +static ulg bg_rowbytes; +static uch *bg_data; + +static struct rgb_color { + uch r, g, b; +} rgb[] = { + { 0, 0, 0}, /* 0: black */ + {255, 255, 255}, /* 1: white */ + {173, 132, 57}, /* 2: tan */ + { 64, 132, 0}, /* 3: medium green */ + {189, 117, 1}, /* 4: gold */ + {253, 249, 1}, /* 5: yellow */ + { 0, 0, 255}, /* 6: blue */ + { 0, 0, 120}, /* 7: medium blue */ + {255, 0, 255}, /* 8: magenta */ + { 64, 0, 64}, /* 9: dark magenta */ + {255, 0, 0}, /* 10: red */ + { 64, 0, 0}, /* 11: dark red */ + {255, 127, 0}, /* 12: orange */ + {192, 96, 0}, /* 13: darker orange */ + { 24, 60, 0}, /* 14: dark green-yellow */ + { 85, 125, 200} /* 15: ice blue */ +}; +/* not used for now, but should be for error-checking: +static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); + */ + +/* + This whole struct is a fairly cheesy way to keep the number of + command-line options to a minimum. The radial-waves background + type is a particularly poor fit to the integer elements of the + struct...but a few macros and a little fixed-point math will do + wonders for ya. + + type bits: + F E D C B A 9 8 7 6 5 4 3 2 1 0 + | | | | | + | | +-+-+-- 0 = sharp-edged checkerboard + | | 1 = soft diamonds + | | 2 = radial waves + | | 3-7 = undefined + | +-- gradient #2 inverted? + +-- alternating columns inverted? + */ +static struct background_pattern { + ush type; + int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ + int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ +} bg[] = { + {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ + {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ + {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ + {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ + {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ + {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ + {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ + {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ + {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ + {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ + {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ + {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ + {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ + {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ + {2, 16, 256, 100, 250}, /* radial: very tight spiral */ + {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ +}; +static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); + + +/* Windows-specific global variables (could go in struct, but messy...) */ +static ulg wimage_rowbytes; +static uch *dib; +static uch *wimage_data; +static BITMAPINFOHEADER *bmih; + +static HWND global_hwnd; +static HINSTANCE global_hInst; +static int global_showmode; + + + + +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) +{ + char *args[1024]; /* arbitrary limit, but should suffice */ + char **argv = args; + char *p, *q, *bgstr = NULL; + int argc = 0; + int rc, alen, flen; + int error = 0; + int timing = FALSE; + int have_bg = FALSE; + double LUT_exponent; /* just the lookup table */ + double CRT_exponent = 2.2; /* just the monitor */ + double default_display_exponent; /* whole display system */ + MSG msg; + + + /* First initialize a few things, just to be sure--memset takes care of + * default background color (black), booleans (FALSE), pointers (NULL), + * etc. */ + + global_hInst = hInst; + global_showmode = showmode; + filename = (char *)NULL; + memset(&rpng2_info, 0, sizeof(mainprog_info)); + + + /* Next reenable console output, which normally goes to the bit bucket + * for windowed apps. Closing the console window will terminate the + * app. Thanks to David.Geldreich@realviz.com for supplying the magical + * incantation. */ + + AllocConsole(); + freopen("CONOUT$", "a", stderr); + freopen("CONOUT$", "a", stdout); + + + /* Set the default value for our display-system exponent, i.e., the + * product of the CRT exponent and the exponent corresponding to + * the frame-buffer's lookup table (LUT), if any. This is not an + * exhaustive list of LUT values (e.g., OpenStep has a lot of weird + * ones), but it should cover 99% of the current possibilities. And + * yes, these ifdefs are completely wasted in a Windows program... */ + +#if defined(NeXT) + /* third-party utilities can modify the default LUT exponent */ + LUT_exponent = 1.0 / 2.2; + /* + if (some_next_function_that_returns_gamma(&next_gamma)) + LUT_exponent = 1.0 / next_gamma; + */ +#elif defined(sgi) + LUT_exponent = 1.0 / 1.7; + /* there doesn't seem to be any documented function to + * get the "gamma" value, so we do it the hard way */ + infile = fopen("/etc/config/system.glGammaVal", "r"); + if (infile) { + double sgi_gamma; + + fgets(tmpline, 80, infile); + fclose(infile); + sgi_gamma = atof(tmpline); + if (sgi_gamma > 0.0) + LUT_exponent = 1.0 / sgi_gamma; + } +#elif defined(Macintosh) + LUT_exponent = 1.8 / 2.61; + /* + if (some_mac_function_that_returns_gamma(&mac_gamma)) + LUT_exponent = mac_gamma / 2.61; + */ +#else + LUT_exponent = 1.0; /* assume no LUT: most PCs */ +#endif + + /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ + default_display_exponent = LUT_exponent * CRT_exponent; + + + /* If the user has set the SCREEN_GAMMA environment variable as suggested + * (somewhat imprecisely) in the libpng documentation, use that; otherwise + * use the default value we just calculated. Either way, the user may + * override this via a command-line option. */ + + if ((p = getenv("SCREEN_GAMMA")) != NULL) + rpng2_info.display_exponent = atof(p); + else + rpng2_info.display_exponent = default_display_exponent; + + + /* Windows really hates command lines, so we have to set up our own argv. + * Note that we do NOT bother with quoted arguments here, so don't use + * filenames with spaces in 'em! */ + + argv[argc++] = PROGNAME; + p = cmd; + for (;;) { + if (*p == ' ') + while (*++p == ' ') + ; + /* now p points at the first non-space after some spaces */ + if (*p == '\0') + break; /* nothing after the spaces: done */ + argv[argc++] = q = p; + while (*q && *q != ' ') + ++q; + /* now q points at a space or the end of the string */ + if (*q == '\0') + break; /* last argv already terminated; quit */ + *q = '\0'; /* change space to terminator */ + p = q + 1; + } + argv[argc] = NULL; /* terminate the argv array itself */ + + + /* Now parse the command line for options and the PNG filename. */ + + while (*++argv && !error) { + if (!strncmp(*argv, "-gamma", 2)) { + if (!*++argv) + ++error; + else { + rpng2_info.display_exponent = atof(*argv); + if (rpng2_info.display_exponent <= 0.0) + ++error; + } + } else if (!strncmp(*argv, "-bgcolor", 4)) { + if (!*++argv) + ++error; + else { + bgstr = *argv; + if (strlen(bgstr) != 7 || bgstr[0] != '#') + ++error; + else { + have_bg = TRUE; + bg_image = FALSE; + } + } + } else if (!strncmp(*argv, "-bgpat", 4)) { + if (!*++argv) + ++error; + else { + pat = atoi(*argv) - 1; + if (pat < 0 || pat >= num_bgpat) + ++error; + else { + bg_image = TRUE; + have_bg = FALSE; + } + } + } else if (!strncmp(*argv, "-timing", 2)) { + timing = TRUE; +#if (defined(__i386__) || defined(_M_IX86)) + } else if (!strncmp(*argv, "-nommxfilters", 7)) { + rpng2_info.nommxfilters = TRUE; + } else if (!strncmp(*argv, "-nommxcombine", 7)) { + rpng2_info.nommxcombine = TRUE; + } else if (!strncmp(*argv, "-nommxinterlace", 7)) { + rpng2_info.nommxinterlace = TRUE; + } else if (!strcmp(*argv, "-nommx")) { + rpng2_info.nommxfilters = TRUE; + rpng2_info.nommxcombine = TRUE; + rpng2_info.nommxinterlace = TRUE; +#endif + } else { + if (**argv != '-') { + filename = *argv; + if (argv[1]) /* shouldn't be any more args after filename */ + ++error; + } else + ++error; /* not expecting any other options */ + } + } + + if (!filename) { + ++error; + } else if (!(infile = fopen(filename, "rb"))) { + fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); + ++error; + } else { + incount = fread(inbuf, 1, INBUFSIZE, infile); + if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { + fprintf(stderr, PROGNAME + ": [%s] is not a PNG file: incorrect signature\n", + filename); + ++error; + } else if ((rc = readpng2_init(&rpng2_info)) != 0) { + switch (rc) { + case 2: + fprintf(stderr, PROGNAME + ": [%s] has bad IHDR (libpng longjmp)\n", + filename); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown readpng2_init() error\n"); + break; + } + ++error; + } + if (error) + fclose(infile); + } + + + /* usage screen */ + + if (error) { + int ch; + + fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); + readpng2_version_info(); + fprintf(stderr, "\n" + "Usage: %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n" +#if (defined(__i386__) || defined(_M_IX86)) + " %*s [[-nommxfilters] [-nommxcombine] [-nommxinterlace] | -nommx]\n" +#endif + " %*s file.png\n\n" + " exp \ttransfer-function exponent (``gamma'') of the display\n" + "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" + "\t\t to the product of the lookup-table exponent (varies)\n" + "\t\t and the CRT exponent (usually 2.2); must be positive\n" + " bg \tdesired background color in 7-character hex RGB format\n" + "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" + "\t\t used with transparent images; overrides -bgpat option\n" + " pat \tdesired background pattern number (1-%d); used with\n" + "\t\t transparent images; overrides -bgcolor option\n" + " -timing\tenables delay for every block read, to simulate modem\n" + "\t\t download of image (~36 Kbps)\n" +#if (defined(__i386__) || defined(_M_IX86)) + " -nommx*\tdisable optimized MMX routines for decoding row filters,\n" + "\t\t combining rows, and expanding interlacing, respectively\n" +#endif + "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" + "Press Q or Esc to quit this usage screen. ", + PROGNAME, +#if (defined(__i386__) || defined(_M_IX86)) + strlen(PROGNAME), " ", +#endif + strlen(PROGNAME), " ", default_display_exponent, num_bgpat); + fflush(stderr); + do + ch = _getch(); + while (ch != 'q' && ch != 'Q' && ch != 0x1B); + exit(1); + } else { + fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); + fprintf(stderr, + "\n [console window: closing this window will terminate %s]\n\n", + PROGNAME); + fflush(stderr); + } + + + /* set the title-bar string, but make sure buffer doesn't overflow */ + + alen = strlen(appname); + flen = strlen(filename); + if (alen + flen + 3 > 1023) + sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); + else + sprintf(titlebar, "%s: %s", appname, filename); + + + /* set some final rpng2_info variables before entering main data loop */ + + if (have_bg) { + unsigned r, g, b; /* this approach quiets compiler warnings */ + + sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); + rpng2_info.bg_red = (uch)r; + rpng2_info.bg_green = (uch)g; + rpng2_info.bg_blue = (uch)b; + } else + rpng2_info.need_bgcolor = TRUE; + + rpng2_info.done = FALSE; + rpng2_info.mainprog_init = rpng2_win_init; + rpng2_info.mainprog_display_row = rpng2_win_display_row; + rpng2_info.mainprog_finish_display = rpng2_win_finish_display; + + + /* OK, this is the fun part: call readpng2_decode_data() at the start of + * the loop to deal with our first buffer of data (read in above to verify + * that the file is a PNG image), then loop through the file and continue + * calling the same routine to handle each chunk of data. It in turn + * passes the data to libpng, which will invoke one or more of our call- + * backs as decoded data become available. We optionally call Sleep() for + * one second per iteration to simulate downloading the image via an analog + * modem. */ + + for (;;) { + Trace((stderr, "about to call readpng2_decode_data()\n")) + if (readpng2_decode_data(&rpng2_info, inbuf, incount)) + ++error; + Trace((stderr, "done with readpng2_decode_data()\n")) + if (error || feof(infile) || rpng2_info.done) + break; + if (timing) + Sleep(1000L); + incount = fread(inbuf, 1, INBUFSIZE, infile); + } + + + /* clean up PNG stuff and report any decoding errors */ + + fclose(infile); + Trace((stderr, "about to call readpng2_cleanup()\n")) + readpng2_cleanup(&rpng2_info); + + if (error) { + fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); + exit(3); + } + + + /* wait for the user to tell us when to quit */ + + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + + /* we're done: clean up all image and Windows resources and go away */ + + Trace((stderr, "about to call rpng2_win_cleanup()\n")) + rpng2_win_cleanup(); + + return msg.wParam; +} + + + + + +/* this function is called by readpng2_info_callback() in readpng2.c, which + * in turn is called by libpng after all of the pre-IDAT chunks have been + * read and processed--i.e., we now have enough info to finish initializing */ + +static void rpng2_win_init() +{ + ulg i; + ulg rowbytes = rpng2_info.rowbytes; + + Trace((stderr, "beginning rpng2_win_init()\n")) + Trace((stderr, " rowbytes = %ld\n", rpng2_info.rowbytes)) + Trace((stderr, " width = %ld\n", rpng2_info.width)) + Trace((stderr, " height = %ld\n", rpng2_info.height)) + + rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); + if (!rpng2_info.image_data) { + readpng2_cleanup(&rpng2_info); + return; + } + + rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); + if (!rpng2_info.row_pointers) { + free(rpng2_info.image_data); + rpng2_info.image_data = NULL; + readpng2_cleanup(&rpng2_info); + return; + } + + for (i = 0; i < rpng2_info.height; ++i) + rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; + +/*--------------------------------------------------------------------------- + Do the basic Windows initialization stuff, make the window, and fill it + with the user-specified, file-specified or default background color. + ---------------------------------------------------------------------------*/ + + if (rpng2_win_create_window()) { + readpng2_cleanup(&rpng2_info); + return; + } +} + + + + + +static int rpng2_win_create_window() +{ + uch bg_red = rpng2_info.bg_red; + uch bg_green = rpng2_info.bg_green; + uch bg_blue = rpng2_info.bg_blue; + uch *dest; + int extra_width, extra_height; + ulg i, j; + WNDCLASSEX wndclass; + RECT rect; + + +/*--------------------------------------------------------------------------- + Allocate memory for the display-specific version of the image (round up + to multiple of 4 for Windows DIB). + ---------------------------------------------------------------------------*/ + + wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2; + + if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + + wimage_rowbytes*rpng2_info.height))) + { + return 4; /* fail */ + } + +/*--------------------------------------------------------------------------- + Initialize the DIB. Negative height means to use top-down BMP ordering + (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 + implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values + directly => wimage_data begins immediately after BMP header. + ---------------------------------------------------------------------------*/ + + memset(dib, 0, sizeof(BITMAPINFOHEADER)); + bmih = (BITMAPINFOHEADER *)dib; + bmih->biSize = sizeof(BITMAPINFOHEADER); + bmih->biWidth = rpng2_info.width; + bmih->biHeight = -((long)rpng2_info.height); + bmih->biPlanes = 1; + bmih->biBitCount = 24; + bmih->biCompression = 0; + wimage_data = dib + sizeof(BITMAPINFOHEADER); + +/*--------------------------------------------------------------------------- + Fill window with the specified background color (default is black), but + defer loading faked "background image" until window is displayed (may be + slow to compute). Data are in BGR order. + ---------------------------------------------------------------------------*/ + + if (bg_image) { /* just fill with black for now */ + memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height); + } else { + for (j = 0; j < rpng2_info.height; ++j) { + dest = wimage_data + j*wimage_rowbytes; + for (i = rpng2_info.width; i > 0; --i) { + *dest++ = bg_blue; + *dest++ = bg_green; + *dest++ = bg_red; + } + } + } + +/*--------------------------------------------------------------------------- + Set the window parameters. + ---------------------------------------------------------------------------*/ + + memset(&wndclass, 0, sizeof(wndclass)); + + wndclass.cbSize = sizeof(wndclass); + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = rpng2_win_wndproc; + wndclass.hInstance = global_hInst; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = progname; + wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + RegisterClassEx(&wndclass); + +/*--------------------------------------------------------------------------- + Finally, create the window. + ---------------------------------------------------------------------------*/ + + extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + + GetSystemMetrics(SM_CXDLGFRAME)); + extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYDLGFRAME)) + + GetSystemMetrics(SM_CYCAPTION); + + global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width, + rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL); + + ShowWindow(global_hwnd, global_showmode); + UpdateWindow(global_hwnd); + +/*--------------------------------------------------------------------------- + Now compute the background image and display it. If it fails (memory + allocation), revert to a plain background color. + ---------------------------------------------------------------------------*/ + + if (bg_image) { + static const char *msg = "Computing background image..."; + int x, y, len = strlen(msg); + HDC hdc = GetDC(global_hwnd); + TEXTMETRIC tm; + + GetTextMetrics(hdc, &tm); + x = (rpng2_info.width - len*tm.tmAveCharWidth)/2; + y = (rpng2_info.height - tm.tmHeight)/2; + SetBkMode(hdc, TRANSPARENT); + SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + /* this can still begin out of bounds even if x is positive (???): */ + TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len); + ReleaseDC(global_hwnd, hdc); + + rpng2_win_load_bg_image(); /* resets bg_image if fails */ + } + + if (!bg_image) { + for (j = 0; j < rpng2_info.height; ++j) { + dest = wimage_data + j*wimage_rowbytes; + for (i = rpng2_info.width; i > 0; --i) { + *dest++ = bg_blue; + *dest++ = bg_green; + *dest++ = bg_red; + } + } + } + + rect.left = 0L; + rect.top = 0L; + rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ + rect.bottom = (LONG)rpng2_info.height; /* possibly off by one? */ + InvalidateRect(global_hwnd, &rect, FALSE); + UpdateWindow(global_hwnd); /* similar to XFlush() */ + + return 0; + +} /* end function rpng2_win_create_window() */ + + + + + +static int rpng2_win_load_bg_image() +{ + uch *src, *dest; + uch r1, r2, g1, g2, b1, b2; + uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; + int k, hmax, max; + int xidx, yidx, yidx_max = (bgscale-1); + int even_odd_vert, even_odd_horiz, even_odd; + int invert_gradient2 = (bg[pat].type & 0x08); + int invert_column; + ulg i, row; + +/*--------------------------------------------------------------------------- + Allocate buffer for fake background image to be used with transparent + images; if this fails, revert to plain background color. + ---------------------------------------------------------------------------*/ + + bg_rowbytes = 3 * rpng2_info.width; + bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); + if (!bg_data) { + fprintf(stderr, PROGNAME + ": unable to allocate memory for background image\n"); + bg_image = 0; + return 1; + } + +/*--------------------------------------------------------------------------- + Vertical gradients (ramps) in NxN squares, alternating direction and + colors (N == bgscale). + ---------------------------------------------------------------------------*/ + + if ((bg[pat].type & 0x07) == 0) { + uch r1_min = rgb[bg[pat].rgb1_min].r; + uch g1_min = rgb[bg[pat].rgb1_min].g; + uch b1_min = rgb[bg[pat].rgb1_min].b; + uch r2_min = rgb[bg[pat].rgb2_min].r; + uch g2_min = rgb[bg[pat].rgb2_min].g; + uch b2_min = rgb[bg[pat].rgb2_min].b; + int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; + int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; + int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; + int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; + int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; + int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; + + for (row = 0; row < rpng2_info.height; ++row) { + yidx = row % bgscale; + even_odd_vert = (row / bgscale) & 1; + + r1 = r1_min + (r1_diff * yidx) / yidx_max; + g1 = g1_min + (g1_diff * yidx) / yidx_max; + b1 = b1_min + (b1_diff * yidx) / yidx_max; + r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; + g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; + b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; + + r2 = r2_min + (r2_diff * yidx) / yidx_max; + g2 = g2_min + (g2_diff * yidx) / yidx_max; + b2 = b2_min + (b2_diff * yidx) / yidx_max; + r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; + g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; + b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; + + dest = bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + even_odd_horiz = (i / bgscale) & 1; + even_odd = even_odd_vert ^ even_odd_horiz; + invert_column = + (even_odd_horiz && (bg[pat].type & 0x10)); + if (even_odd == 0) { /* gradient #1 */ + if (invert_column) { + *dest++ = r1_inv; + *dest++ = g1_inv; + *dest++ = b1_inv; + } else { + *dest++ = r1; + *dest++ = g1; + *dest++ = b1; + } + } else { /* gradient #2 */ + if ((invert_column && invert_gradient2) || + (!invert_column && !invert_gradient2)) + { + *dest++ = r2; /* not inverted or */ + *dest++ = g2; /* doubly inverted */ + *dest++ = b2; + } else { + *dest++ = r2_inv; + *dest++ = g2_inv; /* singly inverted */ + *dest++ = b2_inv; + } + } + } + } + +/*--------------------------------------------------------------------------- + Soft gradient-diamonds with scale = bgscale. Code contributed by Adam + M. Costello. + ---------------------------------------------------------------------------*/ + + } else if ((bg[pat].type & 0x07) == 1) { + + hmax = (bgscale-1)/2; /* half the max weight of a color */ + max = 2*hmax; /* the max weight of a color */ + + r1 = rgb[bg[pat].rgb1_max].r; + g1 = rgb[bg[pat].rgb1_max].g; + b1 = rgb[bg[pat].rgb1_max].b; + r2 = rgb[bg[pat].rgb2_max].r; + g2 = rgb[bg[pat].rgb2_max].g; + b2 = rgb[bg[pat].rgb2_max].b; + + for (row = 0; row < rpng2_info.height; ++row) { + yidx = row % bgscale; + if (yidx > hmax) + yidx = bgscale-1 - yidx; + dest = bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + xidx = i % bgscale; + if (xidx > hmax) + xidx = bgscale-1 - xidx; + k = xidx + yidx; + *dest++ = (k*r1 + (max-k)*r2) / max; + *dest++ = (k*g1 + (max-k)*g2) / max; + *dest++ = (k*b1 + (max-k)*b2) / max; + } + } + +/*--------------------------------------------------------------------------- + Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- + soids will equal bgscale?]. This one is slow but very cool. Code con- + tributed by Pieter S. van der Meulen (originally in Smalltalk). + ---------------------------------------------------------------------------*/ + + } else if ((bg[pat].type & 0x07) == 2) { + uch ch; + int ii, x, y, hw, hh, grayspot; + double freq, rotate, saturate, gray, intensity; + double angle=0.0, aoffset=0.0, maxDist, dist; + double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; + + fprintf(stderr, "%s: computing radial background...", + PROGNAME); + fflush(stderr); + + hh = rpng2_info.height / 2; + hw = rpng2_info.width / 2; + + /* variables for radial waves: + * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] + * freq: number of color beams originating from the center + * grayspot: size of the graying center area (anti-alias) + * rotate: rotation of the beams as a function of radius + * saturate: saturation of beams' shape azimuthally + */ + angle = CLIP(angle, 0.0, 360.0); + grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); + freq = MAX((double)bg[pat].bg_freq, 0.0); + saturate = (double)bg[pat].bg_bsat * 0.1; + rotate = (double)bg[pat].bg_brot * 0.1; + gray = 0.0; + intensity = 0.0; + maxDist = (double)((hw*hw) + (hh*hh)); + + for (row = 0; row < rpng2_info.height; ++row) { + y = row - hh; + dest = bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + x = i - hw; + angle = (x == 0)? PI_2 : atan((double)y / (double)x); + gray = (double)MAX(ABS(y), ABS(x)) / grayspot; + gray = MIN(1.0, gray); + dist = (double)((x*x) + (y*y)) / maxDist; + intensity = cos((angle+(rotate*dist*PI)) * freq) * + gray * saturate; + intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; + hue = (angle + PI) * INV_PI_360 + aoffset; + s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); + s = MIN(MAX(s,0.0), 1.0); + v = MIN(MAX(intensity,0.0), 1.0); + + if (s == 0.0) { + ch = (uch)(v * 255.0); + *dest++ = ch; + *dest++ = ch; + *dest++ = ch; + } else { + if ((hue < 0.0) || (hue >= 360.0)) + hue -= (((int)(hue / 360.0)) * 360.0); + hue /= 60.0; + ii = (int)hue; + f = hue - (double)ii; + p = (1.0 - s) * v; + q = (1.0 - (s * f)) * v; + t = (1.0 - (s * (1.0 - f))) * v; + if (ii == 0) { red = v; green = t; blue = p; } + else if (ii == 1) { red = q; green = v; blue = p; } + else if (ii == 2) { red = p; green = v; blue = t; } + else if (ii == 3) { red = p; green = q; blue = v; } + else if (ii == 4) { red = t; green = p; blue = v; } + else if (ii == 5) { red = v; green = p; blue = q; } + *dest++ = (uch)(red * 255.0); + *dest++ = (uch)(green * 255.0); + *dest++ = (uch)(blue * 255.0); + } + } + } + fprintf(stderr, "done.\n"); + fflush(stderr); + } + +/*--------------------------------------------------------------------------- + Blast background image to display buffer before beginning PNG decode; + calling function will handle invalidation and UpdateWindow() call. + ---------------------------------------------------------------------------*/ + + for (row = 0; row < rpng2_info.height; ++row) { + src = bg_data + row*bg_rowbytes; + dest = wimage_data + row*wimage_rowbytes; + for (i = rpng2_info.width; i > 0; --i) { + r1 = *src++; + g1 = *src++; + b1 = *src++; + *dest++ = b1; + *dest++ = g1; /* note reverse order */ + *dest++ = r1; + } + } + + return 0; + +} /* end function rpng2_win_load_bg_image() */ + + + + + +static void rpng2_win_display_row(ulg row) +{ + uch bg_red = rpng2_info.bg_red; + uch bg_green = rpng2_info.bg_green; + uch bg_blue = rpng2_info.bg_blue; + uch *src, *src2=NULL, *dest; + uch r, g, b, a; + ulg i; + static int rows=0; + static ulg firstrow; + +/*--------------------------------------------------------------------------- + rows and firstrow simply track how many rows (and which ones) have not + yet been displayed; alternatively, we could call InvalidateRect() for + every row and not bother with the records-keeping. + ---------------------------------------------------------------------------*/ + + Trace((stderr, "beginning rpng2_win_display_row()\n")) + + if (rows == 0) + firstrow = row; /* first row not yet displayed */ + + ++rows; /* count of rows received but not yet displayed */ + +/*--------------------------------------------------------------------------- + Aside from the use of the rpng2_info struct and the lack of an outer + loop (over rows), this routine is identical to rpng_win_display_image() + in the non-progressive version of the program. + ---------------------------------------------------------------------------*/ + + src = rpng2_info.image_data + row*rpng2_info.rowbytes; + if (bg_image) + src2 = bg_data + row*bg_rowbytes; + dest = wimage_data + row*wimage_rowbytes; + + if (rpng2_info.channels == 3) { + for (i = rpng2_info.width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + *dest++ = b; + *dest++ = g; /* note reverse order */ + *dest++ = r; + } + } else /* if (rpng2_info.channels == 4) */ { + for (i = rpng2_info.width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (bg_image) { + bg_red = *src2++; + bg_green = *src2++; + bg_blue = *src2++; + } + if (a == 255) { + *dest++ = b; + *dest++ = g; + *dest++ = r; + } else if (a == 0) { + *dest++ = bg_blue; + *dest++ = bg_green; + *dest++ = bg_red; + } else { + /* this macro (copied from png.h) composites the + * foreground and background values and puts the + * result into the first argument; there are no + * side effects with the first argument */ + alpha_composite(*dest++, b, a, bg_blue); + alpha_composite(*dest++, g, a, bg_green); + alpha_composite(*dest++, r, a, bg_red); + } + } + } + +/*--------------------------------------------------------------------------- + Display after every 16 rows or when on last row. (Region may include + previously displayed lines due to interlacing--i.e., not contiguous.) + ---------------------------------------------------------------------------*/ + + if ((rows & 0xf) == 0 || row == rpng2_info.height-1) { + RECT rect; + + rect.left = 0L; + rect.top = (LONG)firstrow; + rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ + rect.bottom = (LONG)row + 1L; /* possibly off by one? */ + InvalidateRect(global_hwnd, &rect, FALSE); + UpdateWindow(global_hwnd); /* similar to XFlush() */ + rows = 0; + } + +} /* end function rpng2_win_display_row() */ + + + + + +static void rpng2_win_finish_display() +{ + Trace((stderr, "beginning rpng2_win_finish_display()\n")) + + /* last row has already been displayed by rpng2_win_display_row(), so + * we have nothing to do here except set a flag and let the user know + * that the image is done */ + + rpng2_info.done = TRUE; + printf( + "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); + fflush(stdout); +} + + + + + +static void rpng2_win_cleanup() +{ + if (bg_image && bg_data) { + free(bg_data); + bg_data = NULL; + } + + if (rpng2_info.image_data) { + free(rpng2_info.image_data); + rpng2_info.image_data = NULL; + } + + if (rpng2_info.row_pointers) { + free(rpng2_info.row_pointers); + rpng2_info.row_pointers = NULL; + } + + if (dib) { + free(dib); + dib = NULL; + } +} + + + + + +LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) +{ + HDC hdc; + PAINTSTRUCT ps; + int rc; + + switch (iMsg) { + case WM_CREATE: + /* one-time processing here, if any */ + return 0; + + case WM_PAINT: + hdc = BeginPaint(hwnd, &ps); + rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height, + 0, 0, rpng2_info.width, rpng2_info.height, + wimage_data, (BITMAPINFO *)bmih, + 0, SRCCOPY); + EndPaint(hwnd, &ps); + return 0; + + /* wait for the user to tell us when to quit */ + case WM_CHAR: + switch (wP) { /* only need one, so ignore repeat count */ + case 'q': + case 'Q': + case 0x1B: /* Esc key */ + PostQuitMessage(0); + } + return 0; + + case WM_LBUTTONDOWN: /* another way of quitting */ + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, iMsg, wP, lP); +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-x.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-x.c new file mode 100644 index 0000000..2e30bd1 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/rpng2-x.c @@ -0,0 +1,1408 @@ +/*--------------------------------------------------------------------------- + + rpng2 - progressive-model PNG display program rpng2-x.c + + This program decodes and displays PNG files progressively, as if it were + a web browser (though the front end is only set up to read from files). + It supports gamma correction, user-specified background colors, and user- + specified background patterns (for transparent images). This version is + for the X Window System (tested by the author under Unix and by Martin + Zinser under OpenVMS; may work under OS/2 with a little tweaking). + + Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond" + and "radial waves" patterns, respectively. + + to do: + - 8-bit support + - finish resizable checkerboard-gradient (sizes 4-128?) + - use %.1023s to simplify truncation of title-bar string? + + --------------------------------------------------------------------------- + + Changelog: + - 1.01: initial public release + - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch + - 1.10: added support for non-default visuals; fixed X pixel-conversion + - 1.11: added -usleep option for demos; fixed command-line parsing bug + - 1.12: added -pause option for demos and testing + - 1.20: added runtime MMX-enabling/disabling and new -mmx* options + - 1.21: fixed small X memory leak (thanks to Francois Petitjean) + - 1.22: fixed XFreeGC() crash bug + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#define PROGNAME "rpng2-x" +#define LONGNAME "Progressive PNG Viewer for X" +#define VERSION "1.22 of 16 August 2001" + +#include +#include +#include +#include /* for jmpbuf declaration in readpng2.h */ +#include +#include /* only for PvdM background code */ +#include +#include +#include +#include /* defines XK_* macros */ + +#ifdef VMS +# include +#endif + +/* all for PvdM background code: */ +#ifndef PI +# define PI 3.141592653589793238 +#endif +#define PI_2 (PI*0.5) +#define INV_PI_360 (360.0 / PI) +#define MAX(a,b) (a>b?a:b) +#define MIN(a,b) (a> 8)) >> 8); \ +} + + +#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this + * block size corresponds roughly to a download + * speed 10% faster than theoretical 33.6K maximum + * (assuming 8 data bits, 1 stop bit and no other + * overhead) */ + +/* local prototypes */ +static void rpng2_x_init(void); +static int rpng2_x_create_window(void); +static int rpng2_x_load_bg_image(void); +static void rpng2_x_display_row(ulg row); +static void rpng2_x_finish_display(void); +static void rpng2_x_cleanup(void); +static int rpng2_x_msb(ulg u32val); + + +static char titlebar[1024], *window_name = titlebar; +static char *appname = LONGNAME; +static char *icon_name = PROGNAME; +static char *filename; +static FILE *infile; + +static mainprog_info rpng2_info; + +static uch inbuf[INBUFSIZE]; +static int incount; + +static int pat = 6; /* must be less than num_bgpat */ +static int bg_image = 0; +static int bgscale = 16; +static ulg bg_rowbytes; +static uch *bg_data; + +int pause_after_pass = FALSE; +int demo_timing = FALSE; +ulg usleep_duration = 0L; + +static struct rgb_color { + uch r, g, b; +} rgb[] = { + { 0, 0, 0}, /* 0: black */ + {255, 255, 255}, /* 1: white */ + {173, 132, 57}, /* 2: tan */ + { 64, 132, 0}, /* 3: medium green */ + {189, 117, 1}, /* 4: gold */ + {253, 249, 1}, /* 5: yellow */ + { 0, 0, 255}, /* 6: blue */ + { 0, 0, 120}, /* 7: medium blue */ + {255, 0, 255}, /* 8: magenta */ + { 64, 0, 64}, /* 9: dark magenta */ + {255, 0, 0}, /* 10: red */ + { 64, 0, 0}, /* 11: dark red */ + {255, 127, 0}, /* 12: orange */ + {192, 96, 0}, /* 13: darker orange */ + { 24, 60, 0}, /* 14: dark green-yellow */ + { 85, 125, 200} /* 15: ice blue */ +}; +/* not used for now, but should be for error-checking: +static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); + */ + +/* + This whole struct is a fairly cheesy way to keep the number of + command-line options to a minimum. The radial-waves background + type is a particularly poor fit to the integer elements of the + struct...but a few macros and a little fixed-point math will do + wonders for ya. + + type bits: + F E D C B A 9 8 7 6 5 4 3 2 1 0 + | | | | | + | | +-+-+-- 0 = sharp-edged checkerboard + | | 1 = soft diamonds + | | 2 = radial waves + | | 3-7 = undefined + | +-- gradient #2 inverted? + +-- alternating columns inverted? + */ +static struct background_pattern { + ush type; + int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ + int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ +} bg[] = { + {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ + {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ + {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ + {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ + {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ + {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ + {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ + {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ + {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ + {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ + {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ + {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ + {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ + {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ + {2, 16, 256, 100, 250}, /* radial: very tight spiral */ + {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ +}; +static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); + + +/* X-specific variables */ +static char *displayname; +static XImage *ximage; +static Display *display; +static int depth; +static Visual *visual; +static XVisualInfo *visual_list; +static int RShift, GShift, BShift; +static ulg RMask, GMask, BMask; +static Window window; +static GC gc; +static Colormap colormap; + +static int have_nondefault_visual = FALSE; +static int have_colormap = FALSE; +static int have_window = FALSE; +static int have_gc = FALSE; + + + + +int main(int argc, char **argv) +{ +#ifdef sgi + char tmpline[80]; +#endif + char *p, *bgstr = NULL; + int rc, alen, flen; + int error = 0; + int timing = FALSE; + int have_bg = FALSE; + double LUT_exponent; /* just the lookup table */ + double CRT_exponent = 2.2; /* just the monitor */ + double default_display_exponent; /* whole display system */ + XEvent e; + KeySym k; + + + /* First initialize a few things, just to be sure--memset takes care of + * default background color (black), booleans (FALSE), pointers (NULL), + * etc. */ + + displayname = (char *)NULL; + filename = (char *)NULL; + memset(&rpng2_info, 0, sizeof(mainprog_info)); + + + /* Set the default value for our display-system exponent, i.e., the + * product of the CRT exponent and the exponent corresponding to + * the frame-buffer's lookup table (LUT), if any. This is not an + * exhaustive list of LUT values (e.g., OpenStep has a lot of weird + * ones), but it should cover 99% of the current possibilities. */ + +#if defined(NeXT) + /* third-party utilities can modify the default LUT exponent */ + LUT_exponent = 1.0 / 2.2; + /* + if (some_next_function_that_returns_gamma(&next_gamma)) + LUT_exponent = 1.0 / next_gamma; + */ +#elif defined(sgi) + LUT_exponent = 1.0 / 1.7; + /* there doesn't seem to be any documented function to + * get the "gamma" value, so we do it the hard way */ + infile = fopen("/etc/config/system.glGammaVal", "r"); + if (infile) { + double sgi_gamma; + + fgets(tmpline, 80, infile); + fclose(infile); + sgi_gamma = atof(tmpline); + if (sgi_gamma > 0.0) + LUT_exponent = 1.0 / sgi_gamma; + } +#elif defined(Macintosh) + LUT_exponent = 1.8 / 2.61; + /* + if (some_mac_function_that_returns_gamma(&mac_gamma)) + LUT_exponent = mac_gamma / 2.61; + */ +#else + LUT_exponent = 1.0; /* assume no LUT: most PCs */ +#endif + + /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ + default_display_exponent = LUT_exponent * CRT_exponent; + + + /* If the user has set the SCREEN_GAMMA environment variable as suggested + * (somewhat imprecisely) in the libpng documentation, use that; otherwise + * use the default value we just calculated. Either way, the user may + * override this via a command-line option. */ + + if ((p = getenv("SCREEN_GAMMA")) != NULL) + rpng2_info.display_exponent = atof(p); + else + rpng2_info.display_exponent = default_display_exponent; + + + /* Now parse the command line for options and the PNG filename. */ + + while (*++argv && !error) { + if (!strncmp(*argv, "-display", 2)) { + if (!*++argv) + ++error; + else + displayname = *argv; + } else if (!strncmp(*argv, "-gamma", 2)) { + if (!*++argv) + ++error; + else { + rpng2_info.display_exponent = atof(*argv); + if (rpng2_info.display_exponent <= 0.0) + ++error; + } + } else if (!strncmp(*argv, "-bgcolor", 4)) { + if (!*++argv) + ++error; + else { + bgstr = *argv; + if (strlen(bgstr) != 7 || bgstr[0] != '#') + ++error; + else { + have_bg = TRUE; + bg_image = FALSE; + } + } + } else if (!strncmp(*argv, "-bgpat", 4)) { + if (!*++argv) + ++error; + else { + pat = atoi(*argv) - 1; + if (pat < 0 || pat >= num_bgpat) + ++error; + else { + bg_image = TRUE; + have_bg = FALSE; + } + } + } else if (!strncmp(*argv, "-usleep", 2)) { + if (!*++argv) + ++error; + else { + usleep_duration = (ulg)atol(*argv); + demo_timing = TRUE; + } + } else if (!strncmp(*argv, "-pause", 2)) { + pause_after_pass = TRUE; + } else if (!strncmp(*argv, "-timing", 2)) { + timing = TRUE; +#if (defined(__i386__) || defined(_M_IX86)) + } else if (!strncmp(*argv, "-nommxfilters", 7)) { + rpng2_info.nommxfilters = TRUE; + } else if (!strncmp(*argv, "-nommxcombine", 7)) { + rpng2_info.nommxcombine = TRUE; + } else if (!strncmp(*argv, "-nommxinterlace", 7)) { + rpng2_info.nommxinterlace = TRUE; + } else if (!strcmp(*argv, "-nommx")) { + rpng2_info.nommxfilters = TRUE; + rpng2_info.nommxcombine = TRUE; + rpng2_info.nommxinterlace = TRUE; +#endif + } else { + if (**argv != '-') { + filename = *argv; + if (argv[1]) /* shouldn't be any more args after filename */ + ++error; + } else + ++error; /* not expecting any other options */ + } + } + + if (!filename) { + ++error; + } else if (!(infile = fopen(filename, "rb"))) { + fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); + ++error; + } else { + incount = fread(inbuf, 1, INBUFSIZE, infile); + if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { + fprintf(stderr, PROGNAME + ": [%s] is not a PNG file: incorrect signature\n", + filename); + ++error; + } else if ((rc = readpng2_init(&rpng2_info)) != 0) { + switch (rc) { + case 2: + fprintf(stderr, PROGNAME + ": [%s] has bad IHDR (libpng longjmp)\n", + filename); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown readpng2_init() error\n"); + break; + } + ++error; + } else { + display = XOpenDisplay(displayname); + if (!display) { + readpng2_cleanup(&rpng2_info); + fprintf(stderr, PROGNAME ": can't open X display [%s]\n", + displayname? displayname : "default"); + ++error; + } + } + if (error) + fclose(infile); + } + + + /* usage screen */ + + if (error) { + fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); + readpng2_version_info(); + fprintf(stderr, "\n" + "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n" +#if (defined(__i386__) || defined(_M_IX86)) + " %*s [[-nommxfilters] [-nommxcombine] [-nommxinterlace] | -nommx]\n" +#endif + " %*s [-usleep dur | -timing] [-pause] file.png\n\n" + " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" + " exp \ttransfer-function exponent (``gamma'') of the display\n" + "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" + "\t\t to the product of the lookup-table exponent (varies)\n" + "\t\t and the CRT exponent (usually 2.2); must be positive\n" + " bg \tdesired background color in 7-character hex RGB format\n" + "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" + "\t\t used with transparent images; overrides -bgpat\n" + " pat \tdesired background pattern number (1-%d); used with\n" + "\t\t transparent images; overrides -bgcolor\n" +#if (defined(__i386__) || defined(_M_IX86)) + " -nommx*\tdisable optimized MMX routines for decoding row filters,\n" + "\t\t combining rows, and expanding interlacing, respectively\n" +#endif + " dur \tduration in microseconds to wait after displaying each\n" + "\t\t row (for demo purposes)\n" + " -timing\tenables delay for every block read, to simulate modem\n" + "\t\t download of image (~36 Kbps)\n" + " -pause\tpauses after displaying each pass until key pressed\n" + "\nPress Q, Esc or mouse button 1 (within image window, after image\n" + "is displayed) to quit.\n" + "\n", PROGNAME, +#if (defined(__i386__) || defined(_M_IX86)) + strlen(PROGNAME), " ", +#endif + strlen(PROGNAME), " ", default_display_exponent, num_bgpat); + exit(1); + } + + + /* set the title-bar string, but make sure buffer doesn't overflow */ + + alen = strlen(appname); + flen = strlen(filename); + if (alen + flen + 3 > 1023) + sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); + else + sprintf(titlebar, "%s: %s", appname, filename); + + + /* set some final rpng2_info variables before entering main data loop */ + + if (have_bg) { + unsigned r, g, b; /* this approach quiets compiler warnings */ + + sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); + rpng2_info.bg_red = (uch)r; + rpng2_info.bg_green = (uch)g; + rpng2_info.bg_blue = (uch)b; + } else + rpng2_info.need_bgcolor = TRUE; + + rpng2_info.done = FALSE; + rpng2_info.mainprog_init = rpng2_x_init; + rpng2_info.mainprog_display_row = rpng2_x_display_row; + rpng2_info.mainprog_finish_display = rpng2_x_finish_display; + + + /* OK, this is the fun part: call readpng2_decode_data() at the start of + * the loop to deal with our first buffer of data (read in above to verify + * that the file is a PNG image), then loop through the file and continue + * calling the same routine to handle each chunk of data. It in turn + * passes the data to libpng, which will invoke one or more of our call- + * backs as decoded data become available. We optionally call sleep() for + * one second per iteration to simulate downloading the image via an analog + * modem. */ + + for (;;) { + Trace((stderr, "about to call readpng2_decode_data()\n")) + if (readpng2_decode_data(&rpng2_info, inbuf, incount)) + ++error; + Trace((stderr, "done with readpng2_decode_data()\n")) + if (error || feof(infile) || rpng2_info.done) + break; + if (timing) + sleep(1); + incount = fread(inbuf, 1, INBUFSIZE, infile); + } + + + /* clean up PNG stuff and report any decoding errors */ + + fclose(infile); + Trace((stderr, "about to call readpng2_cleanup()\n")) + readpng2_cleanup(&rpng2_info); + + if (error) { + fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); + exit(3); + } + + + /* wait for the user to tell us when to quit */ + + do + XNextEvent(display, &e); + while (!(e.type == ButtonPress && e.xbutton.button == Button1) && + !(e.type == KeyPress && /* v--- or 1 for shifted keys */ + ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )); + + + /* we're done: clean up all image and X resources and go away */ + + Trace((stderr, "about to call rpng2_x_cleanup()\n")) + rpng2_x_cleanup(); + + return 0; +} + + + + + +/* this function is called by readpng2_info_callback() in readpng2.c, which + * in turn is called by libpng after all of the pre-IDAT chunks have been + * read and processed--i.e., we now have enough info to finish initializing */ + +static void rpng2_x_init(void) +{ + ulg i; + ulg rowbytes = rpng2_info.rowbytes; + + Trace((stderr, "beginning rpng2_x_init()\n")) + Trace((stderr, " rowbytes = %ld\n", rpng2_info.rowbytes)) + Trace((stderr, " width = %ld\n", rpng2_info.width)) + Trace((stderr, " height = %ld\n", rpng2_info.height)) + + rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); + if (!rpng2_info.image_data) { + readpng2_cleanup(&rpng2_info); + return; + } + + rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); + if (!rpng2_info.row_pointers) { + free(rpng2_info.image_data); + rpng2_info.image_data = NULL; + readpng2_cleanup(&rpng2_info); + return; + } + + for (i = 0; i < rpng2_info.height; ++i) + rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; + + + /* do the basic X initialization stuff, make the window, and fill it with + * the user-specified, file-specified or default background color or + * pattern */ + + if (rpng2_x_create_window()) { + + /* GRR TEMPORARY HACK: this is fundamentally no different from cases + * above; libpng should longjmp() back to us when png_ptr goes away. + * If we/it segfault instead, seems like a libpng bug... */ + + /* we're here via libpng callback, so if window fails, clean and bail */ +printf("readpng2_cleanup.\n"); + readpng2_cleanup(&rpng2_info); + rpng2_x_cleanup(); + exit(2); + } +} + + + + + +static int rpng2_x_create_window(void) +{ + ulg bg_red = rpng2_info.bg_red; + ulg bg_green = rpng2_info.bg_green; + ulg bg_blue = rpng2_info.bg_blue; + ulg bg_pixel = 0L; + ulg attrmask; + int need_colormap = FALSE; + int screen, pad; + uch *xdata; + Window root; + XEvent e; + XGCValues gcvalues; + XSetWindowAttributes attr; + XSizeHints *size_hints; + XTextProperty windowName, *pWindowName = &windowName; + XTextProperty iconName, *pIconName = &iconName; + XVisualInfo visual_info; + XWMHints *wm_hints; + + + Trace((stderr, "beginning rpng2_x_create_window()\n")) + + screen = DefaultScreen(display); + depth = DisplayPlanes(display, screen); + root = RootWindow(display, screen); + +#ifdef DEBUG + XSynchronize(display, True); +#endif + + if (depth != 16 && depth != 24 && depth != 32) { + int visuals_matched = 0; + + Trace((stderr, "default depth is %d: checking other visuals\n", + depth)) + + /* 24-bit first */ + visual_info.screen = screen; + visual_info.depth = 24; + visual_list = XGetVisualInfo(display, + VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); + if (visuals_matched == 0) { +/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ + fprintf(stderr, "default screen depth %d not supported, and no" + " 24-bit visuals found\n", depth); + return 2; + } + Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", + visuals_matched)) + visual = visual_list[0].visual; + depth = visual_list[0].depth; +/* + colormap_size = visual_list[0].colormap_size; + visual_class = visual->class; + visualID = XVisualIDFromVisual(visual); + */ + have_nondefault_visual = TRUE; + need_colormap = TRUE; + } else { + XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); + visual = visual_info.visual; + } + + RMask = visual->red_mask; + GMask = visual->green_mask; + BMask = visual->blue_mask; + +/* GRR: add/check 8-bit support */ + if (depth == 8 || need_colormap) { + colormap = XCreateColormap(display, root, visual, AllocNone); + if (!colormap) { + fprintf(stderr, "XCreateColormap() failed\n"); + return 2; + } + have_colormap = TRUE; + if (depth == 8) + bg_image = FALSE; /* gradient just wastes palette entries */ + } + if (depth == 15 || depth == 16) { + RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */ + GShift = 15 - rpng2_x_msb(GMask); + BShift = 15 - rpng2_x_msb(BMask); + } else if (depth > 16) { + RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */ + GShift = rpng2_x_msb(GMask) - 7; + BShift = rpng2_x_msb(BMask) - 7; + } + if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { + fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n"); + return 2; + } + +/*--------------------------------------------------------------------------- + Finally, create the window. + ---------------------------------------------------------------------------*/ + + attr.backing_store = Always; + attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; + attrmask = CWBackingStore | CWEventMask; + if (have_nondefault_visual) { + attr.colormap = colormap; + attr.background_pixel = 0; + attr.border_pixel = 1; + attrmask |= CWColormap | CWBackPixel | CWBorderPixel; + } + + window = XCreateWindow(display, root, 0, 0, rpng2_info.width, + rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr); + + if (window == None) { + fprintf(stderr, "XCreateWindow() failed\n"); + return 2; + } else + have_window = TRUE; + + if (depth == 8) + XSetWindowColormap(display, window, colormap); + + if (!XStringListToTextProperty(&window_name, 1, pWindowName)) + pWindowName = NULL; + if (!XStringListToTextProperty(&icon_name, 1, pIconName)) + pIconName = NULL; + + /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */ + + if ((size_hints = XAllocSizeHints()) != NULL) { + /* window will not be resizable */ + size_hints->flags = PMinSize | PMaxSize; + size_hints->min_width = size_hints->max_width = (int)rpng2_info.width; + size_hints->min_height = size_hints->max_height = + (int)rpng2_info.height; + } + + if ((wm_hints = XAllocWMHints()) != NULL) { + wm_hints->initial_state = NormalState; + wm_hints->input = True; + /* wm_hints->icon_pixmap = icon_pixmap; */ + wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; + } + + XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, + size_hints, wm_hints, NULL); + + /* various properties and hints no longer needed; free memory */ + if (pWindowName) + XFree(pWindowName->value); + if (pIconName) + XFree(pIconName->value); + if (size_hints) + XFree(size_hints); + if (wm_hints) + XFree(wm_hints); + + XMapWindow(display, window); + + gc = XCreateGC(display, window, 0, &gcvalues); + have_gc = TRUE; + +/*--------------------------------------------------------------------------- + Allocate memory for the X- and display-specific version of the image. + ---------------------------------------------------------------------------*/ + + if (depth == 24 || depth == 32) { + xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height); + pad = 32; + } else if (depth == 16) { + xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height); + pad = 16; + } else /* depth == 8 */ { + xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height); + pad = 8; + } + + if (!xdata) { + fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); + return 4; + } + + ximage = XCreateImage(display, visual, depth, ZPixmap, 0, + (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0); + + if (!ximage) { + fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); + free(xdata); + return 3; + } + + /* to avoid testing the byte order every pixel (or doubling the size of + * the drawing routine with a giant if-test), we arbitrarily set the byte + * order to MSBFirst and let Xlib worry about inverting things on little- + * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the + * most efficient approach (the giant if-test would be better), but in + * the interest of clarity, we'll take the easy way out... */ + + ximage->byte_order = MSBFirst; + +/*--------------------------------------------------------------------------- + Fill window with the specified background color (default is black) or + faked "background image" (but latter is disabled if 8-bit; gradients + just waste palette entries). + ---------------------------------------------------------------------------*/ + + if (bg_image) + rpng2_x_load_bg_image(); /* resets bg_image if fails */ + + if (!bg_image) { + if (depth == 24 || depth == 32) { + bg_pixel = (bg_red << RShift) | + (bg_green << GShift) | + (bg_blue << BShift); + } else if (depth == 16) { + bg_pixel = (((bg_red << 8) >> RShift) & RMask) | + (((bg_green << 8) >> GShift) & GMask) | + (((bg_blue << 8) >> BShift) & BMask); + } else /* depth == 8 */ { + + /* GRR: add 8-bit support */ + + } + XSetForeground(display, gc, bg_pixel); + XFillRectangle(display, window, gc, 0, 0, rpng2_info.width, + rpng2_info.height); + } + +/*--------------------------------------------------------------------------- + Wait for first Expose event to do any drawing, then flush and return. + ---------------------------------------------------------------------------*/ + + do + XNextEvent(display, &e); + while (e.type != Expose || e.xexpose.count); + + XFlush(display); + + return 0; + +} /* end function rpng2_x_create_window() */ + + + + + +static int rpng2_x_load_bg_image(void) +{ + uch *src; + char *dest; + uch r1, r2, g1, g2, b1, b2; + uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; + int k, hmax, max; + int xidx, yidx, yidx_max = (bgscale-1); + int even_odd_vert, even_odd_horiz, even_odd; + int invert_gradient2 = (bg[pat].type & 0x08); + int invert_column; + int ximage_rowbytes = ximage->bytes_per_line; + ulg i, row; + ulg pixel; + +/*--------------------------------------------------------------------------- + Allocate buffer for fake background image to be used with transparent + images; if this fails, revert to plain background color. + ---------------------------------------------------------------------------*/ + + bg_rowbytes = 3 * rpng2_info.width; + bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); + if (!bg_data) { + fprintf(stderr, PROGNAME + ": unable to allocate memory for background image\n"); + bg_image = 0; + return 1; + } + +/*--------------------------------------------------------------------------- + Vertical gradients (ramps) in NxN squares, alternating direction and + colors (N == bgscale). + ---------------------------------------------------------------------------*/ + + if ((bg[pat].type & 0x07) == 0) { + uch r1_min = rgb[bg[pat].rgb1_min].r; + uch g1_min = rgb[bg[pat].rgb1_min].g; + uch b1_min = rgb[bg[pat].rgb1_min].b; + uch r2_min = rgb[bg[pat].rgb2_min].r; + uch g2_min = rgb[bg[pat].rgb2_min].g; + uch b2_min = rgb[bg[pat].rgb2_min].b; + int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; + int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; + int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; + int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; + int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; + int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; + + for (row = 0; row < rpng2_info.height; ++row) { + yidx = (int)(row % bgscale); + even_odd_vert = (int)((row / bgscale) & 1); + + r1 = r1_min + (r1_diff * yidx) / yidx_max; + g1 = g1_min + (g1_diff * yidx) / yidx_max; + b1 = b1_min + (b1_diff * yidx) / yidx_max; + r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; + g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; + b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; + + r2 = r2_min + (r2_diff * yidx) / yidx_max; + g2 = g2_min + (g2_diff * yidx) / yidx_max; + b2 = b2_min + (b2_diff * yidx) / yidx_max; + r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; + g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; + b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; + + dest = (char *)bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + even_odd_horiz = (int)((i / bgscale) & 1); + even_odd = even_odd_vert ^ even_odd_horiz; + invert_column = + (even_odd_horiz && (bg[pat].type & 0x10)); + if (even_odd == 0) { /* gradient #1 */ + if (invert_column) { + *dest++ = r1_inv; + *dest++ = g1_inv; + *dest++ = b1_inv; + } else { + *dest++ = r1; + *dest++ = g1; + *dest++ = b1; + } + } else { /* gradient #2 */ + if ((invert_column && invert_gradient2) || + (!invert_column && !invert_gradient2)) + { + *dest++ = r2; /* not inverted or */ + *dest++ = g2; /* doubly inverted */ + *dest++ = b2; + } else { + *dest++ = r2_inv; + *dest++ = g2_inv; /* singly inverted */ + *dest++ = b2_inv; + } + } + } + } + +/*--------------------------------------------------------------------------- + Soft gradient-diamonds with scale = bgscale. Code contributed by Adam + M. Costello. + ---------------------------------------------------------------------------*/ + + } else if ((bg[pat].type & 0x07) == 1) { + + hmax = (bgscale-1)/2; /* half the max weight of a color */ + max = 2*hmax; /* the max weight of a color */ + + r1 = rgb[bg[pat].rgb1_max].r; + g1 = rgb[bg[pat].rgb1_max].g; + b1 = rgb[bg[pat].rgb1_max].b; + r2 = rgb[bg[pat].rgb2_max].r; + g2 = rgb[bg[pat].rgb2_max].g; + b2 = rgb[bg[pat].rgb2_max].b; + + for (row = 0; row < rpng2_info.height; ++row) { + yidx = (int)(row % bgscale); + if (yidx > hmax) + yidx = bgscale-1 - yidx; + dest = (char *)bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + xidx = (int)(i % bgscale); + if (xidx > hmax) + xidx = bgscale-1 - xidx; + k = xidx + yidx; + *dest++ = (k*r1 + (max-k)*r2) / max; + *dest++ = (k*g1 + (max-k)*g2) / max; + *dest++ = (k*b1 + (max-k)*b2) / max; + } + } + +/*--------------------------------------------------------------------------- + Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- + soids will equal bgscale?]. This one is slow but very cool. Code con- + tributed by Pieter S. van der Meulen (originally in Smalltalk). + ---------------------------------------------------------------------------*/ + + } else if ((bg[pat].type & 0x07) == 2) { + uch ch; + int ii, x, y, hw, hh, grayspot; + double freq, rotate, saturate, gray, intensity; + double angle=0.0, aoffset=0.0, maxDist, dist; + double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; + + fprintf(stderr, "%s: computing radial background...", + PROGNAME); + fflush(stderr); + + hh = (int)(rpng2_info.height / 2); + hw = (int)(rpng2_info.width / 2); + + /* variables for radial waves: + * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] + * freq: number of color beams originating from the center + * grayspot: size of the graying center area (anti-alias) + * rotate: rotation of the beams as a function of radius + * saturate: saturation of beams' shape azimuthally + */ + angle = CLIP(angle, 0.0, 360.0); + grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); + freq = MAX((double)bg[pat].bg_freq, 0.0); + saturate = (double)bg[pat].bg_bsat * 0.1; + rotate = (double)bg[pat].bg_brot * 0.1; + gray = 0.0; + intensity = 0.0; + maxDist = (double)((hw*hw) + (hh*hh)); + + for (row = 0; row < rpng2_info.height; ++row) { + y = (int)(row - hh); + dest = (char *)bg_data + row*bg_rowbytes; + for (i = 0; i < rpng2_info.width; ++i) { + x = (int)(i - hw); + angle = (x == 0)? PI_2 : atan((double)y / (double)x); + gray = (double)MAX(ABS(y), ABS(x)) / grayspot; + gray = MIN(1.0, gray); + dist = (double)((x*x) + (y*y)) / maxDist; + intensity = cos((angle+(rotate*dist*PI)) * freq) * + gray * saturate; + intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; + hue = (angle + PI) * INV_PI_360 + aoffset; + s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); + s = MIN(MAX(s,0.0), 1.0); + v = MIN(MAX(intensity,0.0), 1.0); + + if (s == 0.0) { + ch = (uch)(v * 255.0); + *dest++ = ch; + *dest++ = ch; + *dest++ = ch; + } else { + if ((hue < 0.0) || (hue >= 360.0)) + hue -= (((int)(hue / 360.0)) * 360.0); + hue /= 60.0; + ii = (int)hue; + f = hue - (double)ii; + p = (1.0 - s) * v; + q = (1.0 - (s * f)) * v; + t = (1.0 - (s * (1.0 - f))) * v; + if (ii == 0) { red = v; green = t; blue = p; } + else if (ii == 1) { red = q; green = v; blue = p; } + else if (ii == 2) { red = p; green = v; blue = t; } + else if (ii == 3) { red = p; green = q; blue = v; } + else if (ii == 4) { red = t; green = p; blue = v; } + else if (ii == 5) { red = v; green = p; blue = q; } + *dest++ = (uch)(red * 255.0); + *dest++ = (uch)(green * 255.0); + *dest++ = (uch)(blue * 255.0); + } + } + } + fprintf(stderr, "done.\n"); + fflush(stderr); + } + +/*--------------------------------------------------------------------------- + Blast background image to display buffer before beginning PNG decode. + ---------------------------------------------------------------------------*/ + + if (depth == 24 || depth == 32) { + ulg red, green, blue; + + for (row = 0; row < rpng2_info.height; ++row) { + src = bg_data + row*bg_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + for (i = rpng2_info.width; i > 0; --i) { + red = *src++; + green = *src++; + blue = *src++; + pixel = (red << RShift) | + (green << GShift) | + (blue << BShift); + /* recall that we set ximage->byte_order = MSBFirst above */ + /* GRR BUG: this assumes bpp == 32, but may be 24: */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + + } else if (depth == 16) { + ush red, green, blue; + + for (row = 0; row < rpng2_info.height; ++row) { + src = bg_data + row*bg_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + for (i = rpng2_info.width; i > 0; --i) { + red = ((ush)(*src) << 8); ++src; + green = ((ush)(*src) << 8); ++src; + blue = ((ush)(*src) << 8); ++src; + pixel = ((red >> RShift) & RMask) | + ((green >> GShift) & GMask) | + ((blue >> BShift) & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + + } else /* depth == 8 */ { + + /* GRR: add 8-bit support */ + + } + + XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width, + rpng2_info.height); + + return 0; + +} /* end function rpng2_x_load_bg_image() */ + + + + + +static void rpng2_x_display_row(ulg row) +{ + uch bg_red = rpng2_info.bg_red; + uch bg_green = rpng2_info.bg_green; + uch bg_blue = rpng2_info.bg_blue; + uch *src, *src2=NULL; + char *dest; + uch r, g, b, a; + int ximage_rowbytes = ximage->bytes_per_line; + ulg i, pixel; + static int rows=0, prevpass=(-1); + static ulg firstrow; + +/*--------------------------------------------------------------------------- + rows and firstrow simply track how many rows (and which ones) have not + yet been displayed; alternatively, we could call XPutImage() for every + row and not bother with the records-keeping. + ---------------------------------------------------------------------------*/ + + Trace((stderr, "beginning rpng2_x_display_row()\n")) + + if (rpng2_info.pass != prevpass) { + if (pause_after_pass && rpng2_info.pass > 0) { + XEvent e; + KeySym k; + + fprintf(stderr, + "%s: end of pass %d of 7; click in image window to continue\n", + PROGNAME, prevpass + 1); + do + XNextEvent(display, &e); + while (!(e.type == ButtonPress && e.xbutton.button == Button1) + && !(e.type == KeyPress && + ((k = XLookupKeysym(&e.xkey, 0)) == XK_q + || k == XK_Escape) )) ; + } + fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1); + fflush(stderr); + prevpass = rpng2_info.pass; + } + + if (rows == 0) + firstrow = row; /* first row that is not yet displayed */ + + ++rows; /* count of rows received but not yet displayed */ + +/*--------------------------------------------------------------------------- + Aside from the use of the rpng2_info struct, the lack of an outer loop + (over rows) and moving the XPutImage() call outside the "if (depth)" + tests, this routine is identical to rpng_x_display_image() in the non- + progressive version of the program. + ---------------------------------------------------------------------------*/ + + if (depth == 24 || depth == 32) { + ulg red, green, blue; + + src = rpng2_info.image_data + row*rpng2_info.rowbytes; + if (bg_image) + src2 = bg_data + row*bg_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + if (rpng2_info.channels == 3) { + for (i = rpng2_info.width; i > 0; --i) { + red = *src++; + green = *src++; + blue = *src++; + pixel = (red << RShift) | + (green << GShift) | + (blue << BShift); + /* recall that we set ximage->byte_order = MSBFirst above */ + /* GRR BUG: this assumes bpp == 32, but may be 24: */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } else /* if (rpng2_info.channels == 4) */ { + for (i = rpng2_info.width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (bg_image) { + bg_red = *src2++; + bg_green = *src2++; + bg_blue = *src2++; + } + if (a == 255) { + red = r; + green = g; + blue = b; + } else if (a == 0) { + red = bg_red; + green = bg_green; + blue = bg_blue; + } else { + /* this macro (from png.h) composites the foreground + * and background values and puts the result into the + * first argument */ + alpha_composite(red, r, a, bg_red); + alpha_composite(green, g, a, bg_green); + alpha_composite(blue, b, a, bg_blue); + } + pixel = (red << RShift) | + (green << GShift) | + (blue << BShift); + /* recall that we set ximage->byte_order = MSBFirst above */ + /* GRR BUG: this assumes bpp == 32, but may be 24: */ + *dest++ = (char)((pixel >> 24) & 0xff); + *dest++ = (char)((pixel >> 16) & 0xff); + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + + } else if (depth == 16) { + ush red, green, blue; + + src = rpng2_info.row_pointers[row]; + if (bg_image) + src2 = bg_data + row*bg_rowbytes; + dest = ximage->data + row*ximage_rowbytes; + if (rpng2_info.channels == 3) { + for (i = rpng2_info.width; i > 0; --i) { + red = ((ush)(*src) << 8); + ++src; + green = ((ush)(*src) << 8); + ++src; + blue = ((ush)(*src) << 8); + ++src; + pixel = ((red >> RShift) & RMask) | + ((green >> GShift) & GMask) | + ((blue >> BShift) & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } else /* if (rpng2_info.channels == 4) */ { + for (i = rpng2_info.width; i > 0; --i) { + r = *src++; + g = *src++; + b = *src++; + a = *src++; + if (bg_image) { + bg_red = *src2++; + bg_green = *src2++; + bg_blue = *src2++; + } + if (a == 255) { + red = ((ush)r << 8); + green = ((ush)g << 8); + blue = ((ush)b << 8); + } else if (a == 0) { + red = ((ush)bg_red << 8); + green = ((ush)bg_green << 8); + blue = ((ush)bg_blue << 8); + } else { + /* this macro (from png.h) composites the foreground + * and background values and puts the result back into + * the first argument (== fg byte here: safe) */ + alpha_composite(r, r, a, bg_red); + alpha_composite(g, g, a, bg_green); + alpha_composite(b, b, a, bg_blue); + red = ((ush)r << 8); + green = ((ush)g << 8); + blue = ((ush)b << 8); + } + pixel = ((red >> RShift) & RMask) | + ((green >> GShift) & GMask) | + ((blue >> BShift) & BMask); + /* recall that we set ximage->byte_order = MSBFirst above */ + *dest++ = (char)((pixel >> 8) & 0xff); + *dest++ = (char)( pixel & 0xff); + } + } + + } else /* depth == 8 */ { + + /* GRR: add 8-bit support */ + + } + + +/*--------------------------------------------------------------------------- + Display after every 16 rows or when on one of last two rows. (Region + may include previously displayed lines due to interlacing--i.e., not + contiguous. Also, second-to-last row is final one in interlaced images + with odd number of rows.) For demos, flush (and delay) after every 16th + row so "sparse" passes don't go twice as fast. + ---------------------------------------------------------------------------*/ + + if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) { + XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, + (int)firstrow, rpng2_info.width, row - firstrow + 1); + XFlush(display); + rows = 0; + usleep(usleep_duration); + } else + if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) { + XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, + (int)firstrow, rpng2_info.width, row - firstrow + 1); + XFlush(display); + rows = 0; + } + +} + + + + + +static void rpng2_x_finish_display(void) +{ + Trace((stderr, "beginning rpng2_x_finish_display()\n")) + + /* last row has already been displayed by rpng2_x_display_row(), so we + * have nothing to do here except set a flag and let the user know that + * the image is done */ + + rpng2_info.done = TRUE; + printf( + "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); + fflush(stdout); +} + + + + + +static void rpng2_x_cleanup(void) +{ + if (bg_image && bg_data) { + free(bg_data); + bg_data = NULL; + } + + if (rpng2_info.image_data) { + free(rpng2_info.image_data); + rpng2_info.image_data = NULL; + } + + if (rpng2_info.row_pointers) { + free(rpng2_info.row_pointers); + rpng2_info.row_pointers = NULL; + } + + if (ximage) { + if (ximage->data) { + free(ximage->data); /* we allocated it, so we free it */ + ximage->data = (char *)NULL; /* instead of XDestroyImage() */ + } + XDestroyImage(ximage); + ximage = NULL; + } + + if (have_gc) + XFreeGC(display, gc); + + if (have_window) + XDestroyWindow(display, window); + + if (have_colormap) + XFreeColormap(display, colormap); + + if (have_nondefault_visual) + XFree(visual_list); +} + + + + + +static int rpng2_x_msb(ulg u32val) +{ + int i; + + for (i = 31; i >= 0; --i) { + if (u32val & 0x80000000L) + break; + u32val <<= 1; + } + return i; +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/toucan.png b/src/dep/src/irrlicht/libpng/contrib/gregbook/toucan.png new file mode 100644 index 0000000000000000000000000000000000000000..03960d4939938541ca3f8efee4bf13ffdecbb2f5 GIT binary patch literal 12901 zcma*NWpo@(vMt(@TFlH07Be$5GlRv<%*<@D#mr!V#mp>=(Xz$NEcMklbI#m(>%AXu zud1#cJ2EmWGkdMBijHVyMJYr$JU9RVfG8s^uKIZ``aIKNAOHX`!oF1CrvbDSQ4j%u zMHH|cr5gbN5CCO)b%{^?{|#6GI1B*%zje6(GU5NlRXmX=`N0_(A%xV>KIS3t$)QLv zQPAKaY!jf6!6DFKA+BP;aS(tXOVE|;Uwp<0CBPxek%2QX+9N}6AR78ggv z7y<(tDDvfVZh(LUCaDtRFhN+r_B0_*rDFZ%cgL7s9GZxYKaNytiAy8o< zK4ankJ;1+)_%uHc3!1etPoK|Y|FdGB%Ksn01O8|4J{$jgBVYkwFaQWRFz_wD zcdvi$%1u>K4FFaS4p9LFfgquvVL)(YupoHQKUfBRfZqSbKFR+@Ea>gi5dR;(-VdVC4xLbxrnJC%1@d03#v_sPy`DI z#TlfBgvIoM42mg1!!%U~fzbW3@x?JfxW%NBWH@-~(jYE^qPPz?TWuREkU7XeRz^L5 z)zI>vp=|&8_%|jKPuzGs^^^~C_x@J`fdc-aA1WYukOQ_TO;%<;MIbQ=x!`vn5GPw2 zDEZULr+>x^0FVG=#6{G-*3W$5xfh>5grL|M$^WKI4*jfQiPuZU9gHbtfkr=&WwSL% zv5i1cx)_WYB{v`4mr;p~|&T`^d9t;6jdFSmVAcQM70jBuR z?DCrr)rN21M1F^DwpOHf(0Mmq*4qpki|KZmt3(dweY4NV@07ejk{o^Dj1K4fcG!3) zmiU_>G75d9f^4;3ONXdK8*Syu3Oq-&Fs{+WHBQPe)5^eBia)QXHevUq^>0j=YYxq1 zB+txJ=r8k!mYI=D>GaJw4tvu-T~01;PbspQHcxpxJu_VUW+NH;R(d179U8i_FNCbA zwTha**o3-x!OATw-r&eCuV9z{C@*n8#^%rlbXQfCAf#?XG)O8QO22baFPc2fG>~X| zd~hg+BxsqcH*37}8-u?KBY`s-bLaVS8kzFrX8E&GN^6>mDhQ10CbQ3Lxi=&_;aGYt|XqdtN;~36;Z*~)4-@L|zt7WFJnPXDgMrr8A21>xD4=rh$ zx`f?YYcTI(hX3>x!gd7Bzll48xv8_uIG!QIPa7CH@SCu)u$W9qWmWB{dV;-)lU;gy zrZ~1WzKNTO9kl4yIfN7!cOx6JS>3&o@MfSeR}o<2s$6g5b~aL{=3Thj#yPk%H&T%k zMei>yxv*|_41?~8XXWyxJEjpdU9Ytvo!J9{E6bqAMJ|57^@09uM(LNqjWbvT z=vO{Z`o4IWFz~a-5L!6QqXIU&K;9!WpZ#muwl3C|aK~E3-!kGZ^AhQkMD- zNVB@qHx)LBh%*!J=)fRmn(Md1ij+BYU#uIq!iaudTOu^1NOBc$-e6LMS-%EXuu?gO zOO8z476;7!Q)fx5+da3Z(6O%^&*3B|=+Q5DhO92EIW?TE&H6}N&MUQ|`=)W~N5d8q zeZo`dV`JR*KInu?DgHw(6|6s=R?OM@9kyZPjJBuxf^aGV4I3B)NA54~PWJ?oeO+TU z0{6K^)5-3oX|(o{5Umk8vaAb^um_P!DySz0jftfY9h|BQHZ>4u};|3qQZ&8o^Qu2Et)yj?hmk6_-CjWtv)m5?}1ryI; z&^H#i94EsMvA(`WXZqyIvH9nNpGf%$l`VZgv`n88sQFF55!H0Cc~3rg(wXkcGw_{_ zt;m$MVBwIOexEax%UEk}WVC6%5bw}av9fyUw9l{+f9MLhh%5Jj&KmEsm);H3icisL z+BH8OoOg#*(ZqFs^_+l!;V2TmCV!|!p*b~q6ndvDZ!*IIy8@s%}mJCUoS%mJZR9PUZ3C~-fq zNGyCRYe}(mtu>VkSwi7p?PUWz@tDaz?rliToGWq!+wLxr-p|QvBv5N2^h&_+2R>4| zSwNGJj3cu3rVx(~Wp#6DW4pX2&+z+)@SO;q-lLMB9wnKp&kC;6Z%QCvUGyd zE!hf*uX~bfZv;Btn7@zV%#}1K^HDQ&bktgdP6xNgWpzIc&LS#DXeMRfB|v;|trpze z+7MrXq_F-Vi#&&2W9OHI_p1hh)qt~e1~(j;kQlT)9V(bPqf)j$z zh+EL~V@);)wPv${r7UT@SP;d1+<~o}_4oHzha%+wy6OGz4$ceX(s@_LQ_XE+*{_tj zzY;3hmCedgXs;rJ5L%^xZy81b(eV;PqG5~A8ND9{+ znpdmTKs1^HJ!GU-vo_A1TKW3%II9ZohSLBC=bn?VYBVL1=&QKCq~EIRCxQ^MOA4-4 zeyrWs#@9`2y+J3eb%aat*UPFrBZ%EW)7V5IHb?0ySbF1~QoQwTcNMxB`MKSZR)@qj zr>9I7O6k9U`NfuRLGux8qwmyq03Q48TZB$MnE2Pmo`|4J>K|qsf2ADZi*&y>sTtH` zgcG#o1~}93vpG(tHbJIM7d27Ss~Y;g1~`RAcQ1 z6(#w-bz8cbg=P#SG<0NSRAf|4L}K-42a-$7B^L25OH5?LeQ$2^$bIi;6>;V7W6HC^ zhxv2z!)0W!V+Y7@533S}kAfHDw_#;9tA4Q6qLcl^RqBN;suUJJMVm-Hx?4NAn+}g{ zK1BV_n@+Yco90byI|G;J4EXf`D85l{mgB{$JR?;=aC&dGU{>4TNic0e#d01+hgdP$wU^ zcY>MpA`HFEkY|R($Fb`U3ko-P6v;l)B&MWU#?}HjYHFt@j1l-jxWj*IYd8E?i@&Li zuJ`y`*M5O|v*qA;eOV9Xl1eA^%6t5?x|M{D+)6jQq9c{#!+>Qkeoo@)=61w-{#{{o zDLyWaUqHb3ZG;eF=Et*v9T@mM;TWHXqmS#Z=v!MLs1s?!oU_wi%JzLfUPXmcii$i2 z^RSRY<=lz9%yw)mPf{o=rE|XQV5LtNCI?n}F3ev)`DlT%IL!%hof=Ts7HQBvf?PV^;fC9Pa#k0m4 z0iVD6JFX>pIW9sid^x`xJhs-2!$YYE)mfh|Af?_y#0ONCv@-Yw)gAR%v=I6+)Zxfe zZ^`l)`sT|+Evh{0%F9P#Nx%uxO&oo_e8;&7f%pLQL*M|?8y~QWU|4E`ATAMhE#-dO zv1C7O%XKpi8wN|e%3$_I&7MpsirDxL&C$B@qIq{CBz-L%!J=!)?yu0~t|*vMpQlgO z{1cg~IZ?$9ECKiM=G6f^lViao;%gCOYinJ(*QGB`Z{xkge&b-gQ1gq@N(g%zlkold zww4RGYv&)!zlj-sCgSsUZ)KxQ#NF@n?mm;Z(CO=S*u_On(5(5ARFO(rioF-u6!R;m z-aPhEGlI)Wpl2^IHJ;xGynN_tJ3b}X;$CSnMY7kacWUnLdbU;S-xfV2FQU5wd;42C zPIfQsOI7$bC)97hpYG zlz*F)g1k>t`XksYBS%+CP{Ey4RI}IPda1}Urf)*4ftq2cwHG+%W>VFu7;#qNxYZ%# znlV8}R^QxJlmadtQ)<$5Sp!yvk&#x+JBwX{>H46_@7-EGXMpk0t|X6?c_I}m6lCDQh%|_WqE7pZnbDaOSEZ{Qa1( zpd{GG8=M>bx!l=@oF~R*YmSO~1S_ zC6>fb%f*}0tdeFNWXn=PyvU3&vtEjXB%Bab+Rd>=w`srb0lNO1)_RYzMWFhYs%Zbe=RE7wLoP2KrX)$=J*zBeGHnyS|-{Vs5h2MHbhaC(}d z=J@WzX`^$x5?gM86-h$OjheicqVrnZXUH&3!jtBABkcDuSR^r{z%;QGjZ#o@KeGGo z1@=wf31jmag{sS=3!?W%c`i35#roAw>4~ zWct=gq_&#udL!parJql4W&NpZmY((^WuJ;bi12}!p7~Oz%OYv4Z{X5!C%P`7Y#7pX zFEKqH6=7-KPUBn!7t0|XjOZ98{XHA)^p;(+yWnKWdXT(2E4EMy&+{keYd%b{&Dq}A zxwCBk?o#7~?dh~Qs{XobY82wh~kBrlN ze84+V1R&0b zr5x<+928i$UIrogsj|q!-?QbBXXWa+odPX26FTu0A(YisRrR^gd{PSbeX5OI!4S4w zk<|?j*uhK*7P7N#SbrTl_c11YTh`9fX>8-(G0>0^F~p+ckx5EV|H$P>JeTQ2O!f5W zA!T5=G`uHqjm4HSs^KtW=D?ulv|U*F4G#n#K-$rjECg!}V?X>oS9N>0FQQ zrQg9OM@6bAg$Jws@^zH$7w*#o9~#c+f|*Seqb7|lRsU_3q#r*t)&MrGP-)KUYvK|RYU60s1i{L9 z?5aBC9OH!hMVLkH7Rd-49Hc)r7NaY>TKqY30*7EWwf(b}ZSWg0L&4gSxLA4hyc!mv zHMXW};7c7h>z`=z;s$N1U*&^)*$#X&Yja7})v@x-f;JFXXU6t;b4!vYe>pnY36I|x z!Hi=^ZJWSk2CvqgX~LgrdwCR>Oije)+2Ix5@#HQFk{hRHY$tzqAYly*4Ux!akc*8% z%E>k&}il|nti(BY+KQ0vm0dtd?(fdo1|2P<~omUo%no*-)ni9 zZ@YG^EwV_|&kAemd9EHYIiIeCQJzErP} z7+uU-kDry@itDT}Zgz%OoSzgzl3UQ;szU|`tC}`C&!YE>JTFZ{Al?bzNx-G#S=&pZ z5N_35&;!qr3iq^sXx;q@Jl)d4^sFv%tTu9wy9n_Ho#|&7Ibrxw>Y8Tuyv;_#mVu5= z?US|P%N`)-Ql_+2e=SS5(A(r!~@AZ_st85|gSvyNRx;M*ChZ&bETRn=_sC_(31*z+ASqxYA5j~!7 zz+Z>95r=MK1&J5-92TeZ3%b?cJl9{4GQcLlhi$U4*St8lbI?cqP1(Zd>^6Jx;j`ax zBeid(n5O%%*FAC|1;2iO^fTLuc*^WV4TlSyGxPZ(oj!W|ckPt&@K2}QUwGE5^rC*m zQq2rK1HB)5oHLwA^kM_g;DW3Gm>czJ#{JogNO|IIo;_W~FJ^Dg6GCJi(BjjNK6YjH~xxza9vOb~g!o4Mv!P`6MP4{>zw z3QOeamD+0q;b?H)VE;DzCQqhoc7SYb<=ptC;{xq!<+t-%y8qlaE~lhuZhQ%UZuh-0 zH0QKKc+s{xSX^kk73{>Q+^;8*?$j{3r{!Kf%6@+<_%4DTGPBEfj}qitn~L1$3)xchji99_ z2Agl;!G5)&eh9QjmOZ^N;mbxRR(6Zmx>(Y?p2~#0aQJO+;^1InkN(O~Q$$6?u#%gM zV&lZb+HXAV>Qy%Xup;y3&E4y!ZeTNpVO-uR%VA5Snb-E+a$fW{CSP;2BxjA>oze05R;I6jvp6{YVU|d)H1wqYC zXjHVoD>iiFPCZyfWMK23~DDkHEtAH2vAH{N$^uK_)o0VnG?l;%lz0VD+A* zzdB&N3QJ0G2R$pNzU!x({!3dpr1IEkumm2jh`W}`3)^&s(1jsr>G&=7pC@;w7xZ#G z|3ReXWgvL)j4?`04TF~lK|)G; zBccI|GD3!Ob=%)dsQH1cn$Ka-*Ee^JVC)JENl4h^he0a=GP7?&yE!1jqK1csx*%S| z19T9v^E6c;tz+rWggSS9??Wfx6N+wm{%D*FX8=ekgkyQ|n*QhBe1cjl@)mJKs&qX+ zb7KdGo|}YsX0RA0q~*Jho^0&aQK+}Jj@Gj6$sQawJyy2Vhdc{e*{_TiD{UQyJS^7u z9<0x6+ZZiO$W2N?6$uKz((2WGirarxE?mDEAeoV*Tudz_#7qiwB z761LabLM+@L|Pz~_;9{~O$_3EQ5I3xo!me3(E=qMYw6`398}Qy>BMP;15DgQBA}#1 zIo%R^dNQqg7J}!6{Lkthp7*5^Mb+M!U%9k zqghj=LxtyYi#e+aKRDqr2z{71Ftf2BC+eare&&PBhmR@UM4i|G$zWfw;Opz^B*~J0)8@~4+69)@)}G(p#WrYV zAwQ^Nb_D9!VvwMMGUtBh+OuYop|wP*1>(}+8b6MkB;mX$<;8Pn0 zV>2Ee-+J-4q8J)7qEJw>;Ala=5{(#*t!jgRrg%DBz6!gjdLA#Gc11CaE71a)UfcQL z)tX%XEUFi*K1p%^+Fhq97tflx1fRef9SzvdmQgC;xr&yC5#C;9z~wtGXg9 zlQ(GYUi}smg#HCelqykcW}Jo1QSRo}653-Q%W}Aqnr19;H<_9{AA&F+7e`pCqYrHs z{Mp)Rna4+Db??9eDi<&$rL0t5N^tR7eMWC=pVh>jqwK<&0AOHZLK4bkOc~a}cSBRq@suj` zerx~C24D9&1$^i&l%?nkt~~{%`;x+<6=q$ORhIn#6p!$}G=1=Z&A1DK4Jk0m6>=jM z{SFt?oNELK!+_O>9@D76pR;Sz_iEq&&{n<`Hval4BX_W;s8kc93X6 zF?ZzbH=W@o@DoIk2sLkM-^{4Ko$yOUVuIzJZgSn3#xxyZLVD@9gNvbd^pDX!Mk(Qzoz~Ll&Lk6^sg%k(opS*J6~8ZC~*@ zX`n#qFn|-vf^Mo8P=?urCp^H$E-NwHKO7R-ySS(;>v#&AN|hj+ceZC6%C`k04xWV1L`+NyPfpY?5M z|8pE{@Ysf3zBf9J2u&?QUJiG2bJKJS(|VLCX5QE#lS_{+Z9`<${1}g);tZYH)#STd zSFVJI_aN@muVsB48|g!eiEkwW0k5k|!VC^xrHBCoIdDTkx<%(Zx^;X7J?jx%Q4WR3 z0Fb{dNBo$Mk}_%3w!)i~Ff5$iP+DA*frpAS4{Z_Pr_Yj?lS4+f@76}bsPru-2^0I> zBEwJNz-k*3LBgIOI_MNaQE=YBIQYsW!QY9j@ZEn`MguN(XrOSupJ!bi{ZKJmt|7Lx z?Z=O{F?$FVR(wLR0G%_-01}O^zq&eDo|2eylkDZ}MbkgRq^+x3tOcgzb zOLpmqwIeitcYohla(@T#f8-9$6eDEYujBDVdWs`$d&u9(c`;^A@WD}w+ZK9`Mj0z6 z&cl8Qn$sqepL1?06hZ;S!v$PcR}t6^~-ZC;1>Cip<+N{8R;|dG`qc zv}O9apixC}f+C3=zP>iCVJN_b$6Kn6^kqq*6D| zh=?F+p`PMSqJfi8Y6!MtVj=BMo-wkppKTyMeEAKrn)GyKdd3I`HMqR@>-mo4n`u(e z?9srF>*9ppD_#%OzUqmYzD~{;br8wP=AEtOLzT220VMZBtU5jVaA_O^ zA!DgPg=_t`TT;)Y`DWA_CQb3vv%6nr?+O$?x>?7>Ar+5 zC!}9KHDTUll=4wl7RJt*H0IMqKlAtV`w7^z$_Of|Y}=N*iPP?%8h(+~S{WhUgL+07 zIJspM`uT!&#KRSMd3^STKZZP^(-Vsr7Gj;fo*!{2M#GzP6UNTqNIUQt69f>qXxZ^R7~C`#}tLcUlLm@ z%iWH^ z!5JZ!+tjH37;J@$zqJ5CcLfDJGf82PGo>Wr?eFj;Q%UopnpXtD#=IkRP&D)fR{?`@ZrTF5J2u8d8$ z7|V=dAM?Pz?r)gxtUuh_jK-{Ermi*s63YH zOoPFjCR)xcE6Z9@)$WPnt2rmhN^1$;bxi9c@JQ6_=l$Z=2nqn7vlO=7;lftqEU>b7 zP`y;QAKt~$3fdMRwQyyrbjoWZ*_-lZTib@b_G^8w>6^xC_zs9hXLyZy@4f?i94Vhg z`!BZWtEj3qhtgoyA&>jk`(1$%ouJxvqG!0 z;rmd(r(?L^UAY)oU zys`^7JnJTs5R};PJSWaN88C?;PdnmaDM=a!1zoNcbpbaG+hGcl94!OhJ%Vrc24f;U zn_Ar}JZzz$!0y;;Y1zJn{$^u+&i~oNmc|vEiS2g>$XR~m>#$2Zjz>~vW)L}pVN~0O zkWxHP3etDfsNc>^j;ATZj0=K3X?K7z4btqW^>3qpOp zTOSwMqH{g(q$a2*3+opi_FD%d5&FH04&iWLu~Dw?Oh>ut`A!!_rZ|$ly(JY0I)s2wqK zs4lnwlPS|!tHWJv_E^z8kB}JPNDm0hMdTqBB*hvX9_C3Egx|)B7T~n+-zWR51WFF~ zykOM&Gvu7d%$jn>t}qXVw-0sCx)1l4)Uvd1>qy|xNZ2tzL7cugWy?lA5^(SCVm2*j-lF52V@ z+T%x*`0$QnzCi=sQ)sQE))$@5i!5n_%E;WVC-CQKJ}4QyFA?w54K&f~&R7^d6jIU6 zPj`1xfXC^L*Jscf-{V`m$+~`0;&)~W=mb49C_HNA&mUfMHzy)W1G*D==8R-$N%7Zr zbF6;+e6*#WbR$n3w-0m&PQ^MyQ7YqO`kFbBryEFO%AgS@5>jnOMe3u_t_d?%4X*TH z{5+BTylYAX%v=|+#TsxTno;spmmLhP@5DYGb;_LLVILP@C>fFS;v)~!tu~=`PTn(w z@kq2sccr}peszs_a|jf~@0}a(6)VWFA|VbDn}oBIbW&_Bdy?$OI#a2_7$wSqVNMW8 zQ7moec)LT|o}Km&ELgd(qU71jCs@!EQ?R)buGTAc`(&6qv-!Bwc!oQ3r~BS{UR<7w zzki8DO>^bD?$zuVE?6~FS0Elv9U$D^?!mf^V8)z$rNjVY%ID;{EdFzTiE1K=;e9QkgXl#UrL)nNm{m6wV0io`SMJnp7jViK_}}T?)OW`2<^`_|QGc(qUi8*gRgx z{-!?xiX#CoA7{3v@;VAO`^mfBIAxo(5^u@`?- z)!O(Kd=k9Yde7M2WlPxo!YWbUs9DH}eX_B<*m^qYN+4D&rZb3)BF-KJ&P71fPk}$O zJEdAJIYUf+tAU{x4?>CGnbMGE@jD1gHO+dQh(lR=O z916my +#include +#include +#include /* for jmpbuf declaration in writepng.h */ +#include + +#ifdef DOS_OS2_W32 +# include /* for isatty(), setmode() prototypes */ +# include /* O_BINARY for fdopen() without text translation */ +# ifdef __EMX__ +# ifndef getch +# define getch() _read_kbd(0, 1, 0) /* need getche() */ +# endif +# else /* !__EMX__ */ +# ifdef __GO32__ +# include +# define getch() getkey() /* GRR: need getche() */ +# else +# include /* for getche() console input */ +# endif +# endif /* ?__EMX__ */ +# define FGETS(buf,len,stream) dos_kbd_gets(buf,len) +#else +# include /* for isatty() prototype */ +# define FGETS fgets +#endif + +/* #define DEBUG : this enables the Trace() macros */ + +/* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any + text that includes control characters discouraged by the PNG spec; text + that includes an escape character (27) must be re-entered regardless */ + +#include "writepng.h" /* typedefs, common macros, writepng prototypes */ + + + +/* local prototypes */ + +static int wpng_isvalid_latin1(uch *p, int len); +static void wpng_cleanup(void); + +#ifdef DOS_OS2_W32 + static char *dos_kbd_gets(char *buf, int len); +#endif + + + +static mainprog_info wpng_info; /* lone global */ + + + +int main(int argc, char **argv) +{ +#ifndef DOS_OS2_W32 + FILE *keybd; +#endif +#ifdef sgi + FILE *tmpfile; /* or we could just use keybd, since no overlap */ + char tmpline[80]; +#endif + char *inname = NULL, outname[256]; + char *p, pnmchar, pnmline[256]; + char *bgstr, *textbuf = NULL; + ulg rowbytes; + int rc, len = 0; + int error = 0; + int text = FALSE; + int maxval; + double LUT_exponent; /* just the lookup table */ + double CRT_exponent = 2.2; /* just the monitor */ + double default_display_exponent; /* whole display system */ + double default_gamma = 0.0; + + + wpng_info.infile = NULL; + wpng_info.outfile = NULL; + wpng_info.image_data = NULL; + wpng_info.row_pointers = NULL; + wpng_info.filter = FALSE; + wpng_info.interlaced = FALSE; + wpng_info.have_bg = FALSE; + wpng_info.have_time = FALSE; + wpng_info.have_text = 0; + wpng_info.gamma = 0.0; + + + /* First get the default value for our display-system exponent, i.e., + * the product of the CRT exponent and the exponent corresponding to + * the frame-buffer's lookup table (LUT), if any. If the PNM image + * looks correct on the user's display system, its file gamma is the + * inverse of this value. (Note that this is not an exhaustive list + * of LUT values--e.g., OpenStep has a lot of weird ones--but it should + * cover 99% of the current possibilities. This section must ensure + * that default_display_exponent is positive.) */ + +#if defined(NeXT) + /* third-party utilities can modify the default LUT exponent */ + LUT_exponent = 1.0 / 2.2; + /* + if (some_next_function_that_returns_gamma(&next_gamma)) + LUT_exponent = 1.0 / next_gamma; + */ +#elif defined(sgi) + LUT_exponent = 1.0 / 1.7; + /* there doesn't seem to be any documented function to + * get the "gamma" value, so we do it the hard way */ + tmpfile = fopen("/etc/config/system.glGammaVal", "r"); + if (tmpfile) { + double sgi_gamma; + + fgets(tmpline, 80, tmpfile); + fclose(tmpfile); + sgi_gamma = atof(tmpline); + if (sgi_gamma > 0.0) + LUT_exponent = 1.0 / sgi_gamma; + } +#elif defined(Macintosh) + LUT_exponent = 1.8 / 2.61; + /* + if (some_mac_function_that_returns_gamma(&mac_gamma)) + LUT_exponent = mac_gamma / 2.61; + */ +#else + LUT_exponent = 1.0; /* assume no LUT: most PCs */ +#endif + + /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ + default_display_exponent = LUT_exponent * CRT_exponent; + + + /* If the user has set the SCREEN_GAMMA environment variable as suggested + * (somewhat imprecisely) in the libpng documentation, use that; otherwise + * use the default value we just calculated. Either way, the user may + * override this via a command-line option. */ + + if ((p = getenv("SCREEN_GAMMA")) != NULL) { + double exponent = atof(p); + + if (exponent > 0.0) + default_gamma = 1.0 / exponent; + } + + if (default_gamma == 0.0) + default_gamma = 1.0 / default_display_exponent; + + + /* Now parse the command line for options and the PNM filename. */ + + while (*++argv && !error) { + if (!strncmp(*argv, "-i", 2)) { + wpng_info.interlaced = TRUE; + } else if (!strncmp(*argv, "-time", 3)) { + wpng_info.modtime = time(NULL); + wpng_info.have_time = TRUE; + } else if (!strncmp(*argv, "-text", 3)) { + text = TRUE; + } else if (!strncmp(*argv, "-gamma", 2)) { + if (!*++argv) + ++error; + else { + wpng_info.gamma = atof(*argv); + if (wpng_info.gamma <= 0.0) + ++error; + else if (wpng_info.gamma > 1.01) + fprintf(stderr, PROGNAME + " warning: file gammas are usually less than 1.0\n"); + } + } else if (!strncmp(*argv, "-bgcolor", 4)) { + if (!*++argv) + ++error; + else { + bgstr = *argv; + if (strlen(bgstr) != 7 || bgstr[0] != '#') + ++error; + else { + unsigned r, g, b; /* this way quiets compiler warnings */ + + sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); + wpng_info.bg_red = (uch)r; + wpng_info.bg_green = (uch)g; + wpng_info.bg_blue = (uch)b; + wpng_info.have_bg = TRUE; + } + } + } else { + if (**argv != '-') { + inname = *argv; + if (argv[1]) /* shouldn't be any more args after filename */ + ++error; + } else + ++error; /* not expecting any other options */ + } + } + + + /* open the input and output files, or register an error and abort */ + + if (!inname) { + if (isatty(0)) { + fprintf(stderr, PROGNAME + ": must give input filename or provide image data via stdin\n"); + ++error; + } else { +#ifdef DOS_OS2_W32 + /* some buggy C libraries require BOTH setmode() and fdopen(bin) */ + setmode(fileno(stdin), O_BINARY); + setmode(fileno(stdout), O_BINARY); +#endif + if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) { + fprintf(stderr, PROGNAME + ": unable to reopen stdin in binary mode\n"); + ++error; + } else + if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) { + fprintf(stderr, PROGNAME + ": unable to reopen stdout in binary mode\n"); + fclose(wpng_info.infile); + ++error; + } else + wpng_info.filter = TRUE; + } + } else if ((len = strlen(inname)) > 250) { + fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n", + len); + ++error; + } else if (!(wpng_info.infile = fopen(inname, "rb"))) { + fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname); + ++error; + } + + if (!error) { + fgets(pnmline, 256, wpng_info.infile); + if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' && + pnmchar != '6' && pnmchar != '8')) + { + fprintf(stderr, PROGNAME + ": input file [%s] is not a binary PGM, PPM or PAM file\n", + inname); + ++error; + } else { + wpng_info.pnmtype = (int)(pnmchar - '0'); + if (wpng_info.pnmtype != 8) + wpng_info.have_bg = FALSE; /* no need for bg if opaque */ + do { + fgets(pnmline, 256, wpng_info.infile); /* lose any comments */ + } while (pnmline[0] == '#'); + sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height); + do { + fgets(pnmline, 256, wpng_info.infile); /* more comment lines */ + } while (pnmline[0] == '#'); + sscanf(pnmline, "%d", &maxval); + if (wpng_info.width <= 0L || wpng_info.height <= 0L || + maxval != 255) + { + fprintf(stderr, PROGNAME + ": only positive width/height, maxval == 255 allowed \n"); + ++error; + } + wpng_info.sample_depth = 8; /* <==> maxval 255 */ + + if (!wpng_info.filter) { + /* make outname from inname */ + if ((p = strrchr(inname, '.')) == NULL || + (p - inname) != (len - 4)) + { + strcpy(outname, inname); + strcpy(outname+len, ".png"); + } else { + len -= 4; + strncpy(outname, inname, len); + strcpy(outname+len, ".png"); + } + /* check if outname already exists; if not, open */ + if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) { + fprintf(stderr, PROGNAME ": output file exists [%s]\n", + outname); + fclose(wpng_info.outfile); + ++error; + } else if (!(wpng_info.outfile = fopen(outname, "wb"))) { + fprintf(stderr, PROGNAME ": can't open output file [%s]\n", + outname); + ++error; + } + } + } + if (error) { + fclose(wpng_info.infile); + wpng_info.infile = NULL; + if (wpng_info.filter) { + fclose(wpng_info.outfile); + wpng_info.outfile = NULL; + } + } + } + + + /* if we had any errors, print usage and die horrible death...arrr! */ + + if (error) { + fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME); + writepng_version_info(); + fprintf(stderr, "\n" +"Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n" +"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n" + " exp \ttransfer-function exponent (``gamma'') of the image in\n" + "\t\t floating-point format (e.g., ``%.5f''); if image looks\n" + "\t\t correct on given display system, image gamma is equal to\n" + "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n" + "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n" + "\t\t first varies, second is usually 2.2, all are positive)\n" + " bg \tdesired background color for alpha-channel images, in\n" + "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n" + "\t\t same as HTML colors)\n" + " -text\tprompt interactively for text info (tEXt chunks)\n" + " -time\tinclude a tIME chunk (last modification time)\n" + " -interlace\twrite interlaced PNG image\n" + "\n" +"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n" +"unofficial and unsupported!) PAM (`P8') file. Currently it is required\n" +"to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n" +"is converted to the corresponding PNG file with the same base name but a\n" +"``.png'' extension; files read from stdin are converted and sent to stdout.\n" +"The conversion is progressive (low memory usage) unless interlacing is\n" +"requested; in that case the whole image will be buffered in memory and\n" +"written in one call.\n" + "\n", PROGNAME, PROGNAME, default_gamma); + exit(1); + } + + + /* prepare the text buffers for libpng's use; note that even though + * PNG's png_text struct includes a length field, we don't have to fill + * it out */ + + if (text && +#ifndef DOS_OS2_W32 + (keybd = fdopen(fileno(stderr), "r")) != NULL && +#endif + (textbuf = (char *)malloc((5 + 9)*75)) != NULL) + { + int i, valid, result; + + fprintf(stderr, + "Enter text info (no more than 72 characters per line);\n"); + fprintf(stderr, "to skip a field, hit the key.\n"); + /* note: just leaves len == 1 */ + + do { + valid = TRUE; + p = textbuf + TEXT_TITLE_OFFSET; + fprintf(stderr, " Title: "); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { + if (p[len-1] == '\n') + p[--len] = '\0'; + wpng_info.title = p; + wpng_info.have_text |= TEXT_TITLE; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_TITLE; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_TITLE; + valid = FALSE; + } +#endif + } + } + } while (!valid); + + do { + valid = TRUE; + p = textbuf + TEXT_AUTHOR_OFFSET; + fprintf(stderr, " Author: "); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { + if (p[len-1] == '\n') + p[--len] = '\0'; + wpng_info.author = p; + wpng_info.have_text |= TEXT_AUTHOR; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_AUTHOR; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_AUTHOR; + valid = FALSE; + } +#endif + } + } + } while (!valid); + + do { + valid = TRUE; + p = textbuf + TEXT_DESC_OFFSET; + fprintf(stderr, " Description (up to 9 lines):\n"); + for (i = 1; i < 10; ++i) { + fprintf(stderr, " [%d] ", i); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) + p += len; /* now points at NULL; char before is newline */ + else + break; + } + if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) { + if (p[-1] == '\n') { + p[-1] = '\0'; + --len; + } + wpng_info.desc = textbuf + TEXT_DESC_OFFSET; + wpng_info.have_text |= TEXT_DESC; + p = textbuf + TEXT_DESC_OFFSET; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_DESC; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_DESC; + valid = FALSE; + } +#endif + } + } + } while (!valid); + + do { + valid = TRUE; + p = textbuf + TEXT_COPY_OFFSET; + fprintf(stderr, " Copyright: "); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { + if (p[len-1] == '\n') + p[--len] = '\0'; + wpng_info.copyright = p; + wpng_info.have_text |= TEXT_COPY; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_COPY; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_COPY; + valid = FALSE; + } +#endif + } + } + } while (!valid); + + do { + valid = TRUE; + p = textbuf + TEXT_EMAIL_OFFSET; + fprintf(stderr, " E-mail: "); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { + if (p[len-1] == '\n') + p[--len] = '\0'; + wpng_info.email = p; + wpng_info.have_text |= TEXT_EMAIL; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_EMAIL; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_EMAIL; + valid = FALSE; + } +#endif + } + } + } while (!valid); + + do { + valid = TRUE; + p = textbuf + TEXT_URL_OFFSET; + fprintf(stderr, " URL: "); + fflush(stderr); + if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { + if (p[len-1] == '\n') + p[--len] = '\0'; + wpng_info.url = p; + wpng_info.have_text |= TEXT_URL; + if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { + fprintf(stderr, " " PROGNAME " warning: character code" + " %u is %sdiscouraged by the PNG\n specification " + "[first occurrence was at character position #%d]\n", + (unsigned)p[result], (p[result] == 27)? "strongly " : "", + result+1); + fflush(stderr); +#ifdef FORBID_LATIN1_CTRL + wpng_info.have_text &= ~TEXT_URL; + valid = FALSE; +#else + if (p[result] == 27) { /* escape character */ + wpng_info.have_text &= ~TEXT_URL; + valid = FALSE; + } +#endif + } + } + } while (!valid); + +#ifndef DOS_OS2_W32 + fclose(keybd); +#endif + + } else if (text) { + fprintf(stderr, PROGNAME ": unable to allocate memory for text\n"); + text = FALSE; + wpng_info.have_text = 0; + } + + + /* allocate libpng stuff, initialize transformations, write pre-IDAT data */ + + if ((rc = writepng_init(&wpng_info)) != 0) { + switch (rc) { + case 2: + fprintf(stderr, PROGNAME + ": libpng initialization problem (longjmp)\n"); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + case 11: + fprintf(stderr, PROGNAME + ": internal logic error (unexpected PNM type)\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown writepng_init() error\n"); + break; + } + exit(rc); + } + + + /* free textbuf, since it's a completely local variable and all text info + * has just been written to the PNG file */ + + if (text && textbuf) { + free(textbuf); + textbuf = NULL; + } + + + /* calculate rowbytes on basis of image type; note that this becomes much + * more complicated if we choose to support PBM type, ASCII PNM types, or + * 16-bit-per-sample binary data [currently not an official NetPBM type] */ + + if (wpng_info.pnmtype == 5) + rowbytes = wpng_info.width; + else if (wpng_info.pnmtype == 6) + rowbytes = wpng_info.width * 3; + else /* if (wpng_info.pnmtype == 8) */ + rowbytes = wpng_info.width * 4; + + + /* read and write the image, either in its entirety (if writing interlaced + * PNG) or row by row (if non-interlaced) */ + + fprintf(stderr, "Encoding image data...\n"); + fflush(stderr); + + if (wpng_info.interlaced) { + long i; + ulg bytes; + ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */ + + wpng_info.image_data = (uch *)malloc(image_bytes); + wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *)); + if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) { + fprintf(stderr, PROGNAME ": insufficient memory for image data\n"); + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(5); + } + for (i = 0; i < wpng_info.height; ++i) + wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes; + bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile); + if (bytes != image_bytes) { + fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n", + image_bytes, bytes); + fprintf(stderr, " (continuing anyway)\n"); + } + if (writepng_encode_image(&wpng_info) != 0) { + fprintf(stderr, PROGNAME + ": libpng problem (longjmp) while writing image data\n"); + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(2); + } + + } else /* not interlaced: write progressively (row by row) */ { + long j; + ulg bytes; + + wpng_info.image_data = (uch *)malloc(rowbytes); + if (wpng_info.image_data == NULL) { + fprintf(stderr, PROGNAME ": insufficient memory for row data\n"); + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(5); + } + error = 0; + for (j = wpng_info.height; j > 0L; --j) { + bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile); + if (bytes != rowbytes) { + fprintf(stderr, PROGNAME + ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes, + bytes, wpng_info.height-j); + ++error; + break; + } + if (writepng_encode_row(&wpng_info) != 0) { + fprintf(stderr, PROGNAME + ": libpng problem (longjmp) while writing row %ld\n", + wpng_info.height-j); + ++error; + break; + } + } + if (error) { + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(2); + } + if (writepng_encode_finish(&wpng_info) != 0) { + fprintf(stderr, PROGNAME ": error on final libpng call\n"); + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(2); + } + } + + + /* OK, we're done (successfully): clean up all resources and quit */ + + fprintf(stderr, "Done.\n"); + fflush(stderr); + + writepng_cleanup(&wpng_info); + wpng_cleanup(); + + return 0; +} + + + + + +static int wpng_isvalid_latin1(uch *p, int len) +{ + int i, result = -1; + + for (i = 0; i < len; ++i) { + if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160) + continue; /* character is completely OK */ + if (result < 0 || (p[result] != 27 && p[i] == 27)) + result = i; /* mark location of first questionable one */ + } /* or of first escape character (bad) */ + + return result; +} + + + + + +static void wpng_cleanup(void) +{ + if (wpng_info.outfile) { + fclose(wpng_info.outfile); + wpng_info.outfile = NULL; + } + + if (wpng_info.infile) { + fclose(wpng_info.infile); + wpng_info.infile = NULL; + } + + if (wpng_info.image_data) { + free(wpng_info.image_data); + wpng_info.image_data = NULL; + } + + if (wpng_info.row_pointers) { + free(wpng_info.row_pointers); + wpng_info.row_pointers = NULL; + } +} + + + + +#ifdef DOS_OS2_W32 + +static char *dos_kbd_gets(char *buf, int len) +{ + int ch, count=0; + + do { + buf[count++] = ch = getche(); + } while (ch != '\r' && count < len-1); + + buf[count--] = '\0'; /* terminate string */ + if (buf[count] == '\r') /* Enter key makes CR, so change to newline */ + buf[count] = '\n'; + + fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */ + fflush(stderr); + + return buf; +} + +#endif /* DOS_OS2_W32 */ diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.c b/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.c new file mode 100644 index 0000000..7e1e436 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.c @@ -0,0 +1,368 @@ +/*--------------------------------------------------------------------------- + + wpng - simple PNG-writing program writepng.c + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2000 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + + +#include /* for exit() prototype */ + +#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ +#include "writepng.h" /* typedefs, common macros, public prototypes */ + + +/* local prototype */ + +static void writepng_error_handler(png_structp png_ptr, png_const_charp msg); + + + +void writepng_version_info(void) +{ + fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", + PNG_LIBPNG_VER_STRING, png_libpng_ver); + fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", + ZLIB_VERSION, zlib_version); +} + + + + +/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for + * unexpected pnmtype; note that outfile might be stdout */ + +int writepng_init(mainprog_info *mainprog_ptr) +{ + png_structp png_ptr; /* note: temporary variables! */ + png_infop info_ptr; + int color_type, interlace_type; + + + /* could also replace libpng warning-handler (final NULL), but no need: */ + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, + writepng_error_handler, NULL); + if (!png_ptr) + return 4; /* out of memory */ + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, NULL); + return 4; /* out of memory */ + } + + + /* setjmp() must be called in every function that calls a PNG-writing + * libpng function, unless an alternate error handler was installed-- + * but compatible error handlers must either use longjmp() themselves + * (as in this program) or exit immediately, so here we go: */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + return 2; + } + + + /* make sure outfile is (re)opened in BINARY mode */ + + png_init_io(png_ptr, mainprog_ptr->outfile); + + + /* set the compression levels--in general, always want to leave filtering + * turned on (except for palette images) and allow all of the filters, + * which is the default; want 32K zlib window, unless entire image buffer + * is 16K or smaller (unknown here)--also the default; usually want max + * compression (NOT the default); and remaining compression flags should + * be left alone */ + + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); +/* + >> this is default for no filtering; Z_FILTERED is default otherwise: + png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); + >> these are all defaults: + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + */ + + + /* set the image parameters appropriately */ + + if (mainprog_ptr->pnmtype == 5) + color_type = PNG_COLOR_TYPE_GRAY; + else if (mainprog_ptr->pnmtype == 6) + color_type = PNG_COLOR_TYPE_RGB; + else if (mainprog_ptr->pnmtype == 8) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else { + png_destroy_write_struct(&png_ptr, &info_ptr); + return 11; + } + + interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 : + PNG_INTERLACE_NONE; + + png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height, + mainprog_ptr->sample_depth, color_type, interlace_type, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + if (mainprog_ptr->gamma > 0.0) + png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma); + + if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */ + png_color_16 background; + + background.red = mainprog_ptr->bg_red; + background.green = mainprog_ptr->bg_green; + background.blue = mainprog_ptr->bg_blue; + png_set_bKGD(png_ptr, info_ptr, &background); + } + + if (mainprog_ptr->have_time) { + png_time modtime; + + png_convert_from_time_t(&modtime, mainprog_ptr->modtime); + png_set_tIME(png_ptr, info_ptr, &modtime); + } + + if (mainprog_ptr->have_text) { + png_text text[6]; + int num_text = 0; + + if (mainprog_ptr->have_text & TEXT_TITLE) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "Title"; + text[num_text].text = mainprog_ptr->title; + ++num_text; + } + if (mainprog_ptr->have_text & TEXT_AUTHOR) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "Author"; + text[num_text].text = mainprog_ptr->author; + ++num_text; + } + if (mainprog_ptr->have_text & TEXT_DESC) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "Description"; + text[num_text].text = mainprog_ptr->desc; + ++num_text; + } + if (mainprog_ptr->have_text & TEXT_COPY) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "Copyright"; + text[num_text].text = mainprog_ptr->copyright; + ++num_text; + } + if (mainprog_ptr->have_text & TEXT_EMAIL) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "E-mail"; + text[num_text].text = mainprog_ptr->email; + ++num_text; + } + if (mainprog_ptr->have_text & TEXT_URL) { + text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + text[num_text].key = "URL"; + text[num_text].text = mainprog_ptr->url; + ++num_text; + } + png_set_text(png_ptr, info_ptr, text, num_text); + } + + + /* write all chunks up to (but not including) first IDAT */ + + png_write_info(png_ptr, info_ptr); + + + /* if we wanted to write any more text info *after* the image data, we + * would set up text struct(s) here and call png_set_text() again, with + * just the new data; png_set_tIME() could also go here, but it would + * have no effect since we already called it above (only one tIME chunk + * allowed) */ + + + /* set up the transformations: for now, just pack low-bit-depth pixels + * into bytes (one, two or four pixels per byte) */ + + png_set_packing(png_ptr); +/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */ + + + /* make sure we save our pointers for use in writepng_encode_image() */ + + mainprog_ptr->png_ptr = png_ptr; + mainprog_ptr->info_ptr = info_ptr; + + + /* OK, that's all we need to do for now; return happy */ + + return 0; +} + + + + + +/* returns 0 for success, 2 for libpng (longjmp) problem */ + +int writepng_encode_image(mainprog_info *mainprog_ptr) +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + + /* as always, setjmp() must be called in every function that calls a + * PNG-writing libpng function */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + mainprog_ptr->png_ptr = NULL; + mainprog_ptr->info_ptr = NULL; + return 2; + } + + + /* and now we just write the whole image; libpng takes care of interlacing + * for us */ + + png_write_image(png_ptr, mainprog_ptr->row_pointers); + + + /* since that's it, we also close out the end of the PNG file now--if we + * had any text or time info to write after the IDATs, second argument + * would be info_ptr, but we optimize slightly by sending NULL pointer: */ + + png_write_end(png_ptr, NULL); + + return 0; +} + + + + + +/* returns 0 if succeeds, 2 if libpng problem */ + +int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */ +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + + /* as always, setjmp() must be called in every function that calls a + * PNG-writing libpng function */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + mainprog_ptr->png_ptr = NULL; + mainprog_ptr->info_ptr = NULL; + return 2; + } + + + /* image_data points at our one row of image data */ + + png_write_row(png_ptr, mainprog_ptr->image_data); + + return 0; +} + + + + + +/* returns 0 if succeeds, 2 if libpng problem */ + +int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */ +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + + /* as always, setjmp() must be called in every function that calls a + * PNG-writing libpng function */ + + if (setjmp(mainprog_ptr->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + mainprog_ptr->png_ptr = NULL; + mainprog_ptr->info_ptr = NULL; + return 2; + } + + + /* close out PNG file; if we had any text or time info to write after + * the IDATs, second argument would be info_ptr: */ + + png_write_end(png_ptr, NULL); + + return 0; +} + + + + + +void writepng_cleanup(mainprog_info *mainprog_ptr) +{ + png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; + png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; + + if (png_ptr && info_ptr) + png_destroy_write_struct(&png_ptr, &info_ptr); +} + + + + + +static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) +{ + mainprog_info *mainprog_ptr; + + /* This function, aside from the extra step of retrieving the "error + * pointer" (below) and the fact that it exists within the application + * rather than within libpng, is essentially identical to libpng's + * default error handler. The second point is critical: since both + * setjmp() and longjmp() are called from the same code, they are + * guaranteed to have compatible notions of how big a jmp_buf is, + * regardless of whether _BSD_SOURCE or anything else has (or has not) + * been defined. */ + + fprintf(stderr, "writepng libpng error: %s\n", msg); + fflush(stderr); + + mainprog_ptr = png_get_error_ptr(png_ptr); + if (mainprog_ptr == NULL) { /* we are completely hosed now */ + fprintf(stderr, + "writepng severe error: jmpbuf not recoverable; terminating.\n"); + fflush(stderr); + exit(99); + } + + longjmp(mainprog_ptr->jmpbuf, 1); +} diff --git a/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.h b/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.h new file mode 100644 index 0000000..26d7117 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/gregbook/writepng.h @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------- + + wpng - simple PNG-writing program writepng.h + + --------------------------------------------------------------------------- + + Copyright (c) 1998-2000 Greg Roelofs. All rights reserved. + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall the author or contributors + be held liable for any damages arising in any way from the use of + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, disclaimer, and this list of conditions. + 2. Redistributions in binary form must reproduce the above copyright + notice, disclaimer, and this list of conditions in the documenta- + tion and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + + This product includes software developed by Greg Roelofs + and contributors for the book, "PNG: The Definitive Guide," + published by O'Reilly and Associates. + + ---------------------------------------------------------------------------*/ + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b)? (a) : (b)) +# define MIN(a,b) ((a) < (b)? (a) : (b)) +#endif + +#ifdef DEBUG +# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} +#else +# define Trace(x) ; +#endif + +#define TEXT_TITLE 0x01 +#define TEXT_AUTHOR 0x02 +#define TEXT_DESC 0x04 +#define TEXT_COPY 0x08 +#define TEXT_EMAIL 0x10 +#define TEXT_URL 0x20 + +#define TEXT_TITLE_OFFSET 0 +#define TEXT_AUTHOR_OFFSET 72 +#define TEXT_COPY_OFFSET (2*72) +#define TEXT_EMAIL_OFFSET (3*72) +#define TEXT_URL_OFFSET (4*72) +#define TEXT_DESC_OFFSET (5*72) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +typedef struct _mainprog_info { + double gamma; + long width; + long height; + time_t modtime; + FILE *infile; + FILE *outfile; + void *png_ptr; + void *info_ptr; + uch *image_data; + uch **row_pointers; + char *title; + char *author; + char *desc; + char *copyright; + char *email; + char *url; + int filter; /* command-line-filter flag, not PNG row filter! */ + int pnmtype; + int sample_depth; + int interlaced; + int have_bg; + int have_time; + int have_text; + jmp_buf jmpbuf; + uch bg_red; + uch bg_green; + uch bg_blue; +} mainprog_info; + + +/* prototypes for public functions in writepng.c */ + +void writepng_version_info(void); + +int writepng_init(mainprog_info *mainprog_ptr); + +int writepng_encode_image(mainprog_info *mainprog_ptr); + +int writepng_encode_row(mainprog_info *mainprog_ptr); + +int writepng_encode_finish(mainprog_info *mainprog_ptr); + +void writepng_cleanup(mainprog_info *mainprog_ptr); diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/README b/src/dep/src/irrlicht/libpng/contrib/pngminus/README new file mode 100644 index 0000000..b0516ec --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/README @@ -0,0 +1,153 @@ +PngMinus +-------- +(copyright Willem van Schaik, 1999) + + +License +------- + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear in +supporting documentation. This software is provided "as is" without +express or implied warranty. + + +Some history +------------ +Soon after the creation of PNG in 1995, the need was felt for a set of +pnmtopng / pngtopnm utilities. Independantly Alexander Lehmann and I +(Willem van Schaik) started such a project. Luckily we discovered this +and merged the two together into pnmtopng.tar.gz, which is available +from a/o ftp://ftp.simplesystems.org/pub/libpng/png/. + +These two utilities have many, many options and make use of most of the +features of PNG, like gamma, alpha, sbit, text-chunks, etc. This makes +the utilities quite complex and by now not anymore very maintainable. +When we wrote these programs, libpng was still in an early stage. +Therefore, lots of the functionality that we put in our software can now +be done using transform-functions in libpng. + +Finally, to compile these programs, you need to have installed and +compiled three libraries: libpng, zlib and netpbm. Especially the latter +makes the whole setup a bit bulky. But that's unavoidable given the many +features of pnmtopng. + + +What now +-------- +At this moment libpng is in a very stable state and can do much of the +work done in pnmtopng. Also, pnmtopng needs to be upgraded to the new +interface of libpng. Hence, it is time for a rewrite from the ground up +of pnmtopng and pngtopnm. This will happen in the near future (stay +tuned). The new package will get a different name to distinguish it from +the old one: PngPlus. + +To experiment a bit with the new interface of libpng, I started off with +a small prototype that contains only the basic functionality. It doesn't +have any of the options to read or write special chunks and it will do +no gamma correction. But this makes it also a simple program that is +quite easy to understand and can serve well as a template for other +software developments. (By now there are of course a couple of programs, +like Greg Roelofs' rpng/wpng, that can be used just as good.) + + +Can and can not +--------------- +As this is the small brother of the future PngPlus, I called this fellow +PngMinus. Because I started this development in good-old Turbo-C, I +avoided the use the netpbm library, which requires DOS extenders. Again, +another reason to call it PngMinus (minus netpbm :-). So, part of the +program are some elementary routines to read / write pgm- and ppm-files. +It does not read b&w pbm-files. + +The downside of this approach is that you can not use them on images +that require blocks of memory bigger than 64k (the DOS version). For +larger images you will get an out-of-memory error. + +As said before, PngMinus doesn't correct for gamma. When reading +png-files you can do this just as well by piping the output of png2pnm +to pnmgamma, one of the standard PbmPlus tools. This same scenario will +most probably also be followed in the full-blown future PngPlus, with +the addition of course of the possibility to create gamma-chunks when +writing png-files. + +On the other hand it supports alpha-channels. When reading a png-image +you can write the alpha-channel into a pgm-file. And when creating an +RGB+A png-image, you just combine a ppm-file with a corresponding +pgm-file containing the alpha-channel. When reading, transparency chunks +are converted into an alpha-channel and from there on treated the same +way. + +Finally you can opt for writing ascii or binary pgm- and ppm-files. When +the bit-depth is 16, the format will always be ascii. + + +Using it +-------- +To distinguish them from pnmtopng and PngPlus, the utilities are named +png2pnm and pnm2png (2 instead of to). The input- and output-files can +be given as parameters or through redirection. Therefore the programs +can be part of a pipe. + +To list the options type "png2pnm -h" or "pnm2png -h". + + +Just like Scandinavian furniture +-------------------------------- +You have to put it together yourself. I did test the software under +MS-DOS with Turbo-C 3.0 and under RedHat Linux 4.2 with gcc. In both +cases I used libpng-1.0.4 and zlib-1.1.3. Later versions should be OK, +however some older libpng versions have a bug in pngmem.c when using +Turbo-C 3.0 (see below). + +You can build it using one of the two makefiles (make -f makefile.###) +or use the batch/script files pngminus.bat / pngminus.sh. This assumes +that you have built the libraries in ../libpng and ../zlib. Using Linux, +make sure that you have built libpng with makefile.std and not +makefile.linux (also called .lnx in earlier versions of libpng). The +latter creates a .so shared-library, while the PngMinus makefile assumes +a normal .a static library. + +If you create a ../pngsuite directory and then store the basn####.png +files from PngSuite (http://www.schaik.com/pngsuite/) in there, you can +test in one go the proper functioning of PngMinus, see png2pnm.bat and +pnm2png.bat (or the .sh versions). + + +Warranty +------- +Please, remember that this was just a small experiment to learn a few +things. It will have many unforeseen features . Who said bugs? Use +it when you are in need for something simple or when you want to start +developing your own stuff. + + +The Turbo bug +------------- +** pngmem.old + hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); + hptr += 16L; +** pngmem.c + hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); + hptr = hptr + 16L; +** + +** pngmem.old + png_ptr->offset_table_ptr[i] = (png_bytep)hptr; + hptr += (png_uint_32)65536L; +** pngmem.c + png_ptr->offset_table_ptr[i] = (png_bytep)hptr; + hptr = hptr + 65536L; +** + + +The end +------- +Willem van Schaik +mailto:willem@schaik.com +http://www.schaik.com/png/ +------- +Oct 1999 + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.std b/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.std new file mode 100644 index 0000000..afe15c7 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.std @@ -0,0 +1,65 @@ +# Makefile for PngMinus (png2pnm and pnm2png) +# Linux / Unix + +#CC=cc +CC=gcc +LD=$(CC) + +RM=rm -f + +#PNGPATH = /usr/local +#PNGINC = -I$(PNGPATH)/include/libpng12 +#PNGLIB = -L$(PNGPATH)/lib -lpng12 +#PNGLIBS = $(PNGPATH)/lib/libpng12.a +PNGINC = -I../.. +PNGLIB = -L../.. -lpng +PNGLIBS = ../../libpng.a + +#ZPATH = /usr/local +#ZINC = -I$(ZPATH)/include +#ZLIB = -L$(ZPATH)/lib -lz +#ZLIBS = $(ZPATH)/lib/libz.a +ZINC = -I../../../zlib +ZLIB = -L../../../zlib -lz +ZLIBS = ../../../zlib/libz.a + +CFLAGS=-O3 $(PNGINC) $(ZINC) +LDFLAGS=$(PNGLIB) $(ZLIB) +LDFLAGSS=$(PNGLIBS) $(ZLIBS) +C=.c +O=.o +L=.a +E= + +# dependencies + +#all: png2pnm$(E) pnm2png$(E) +all: png2pnm$(E) pnm2png$(E) png2pnm-static$(E) pnm2png-static$(E) + +png2pnm$(O): png2pnm$(C) + $(CC) -c $(CFLAGS) png2pnm$(C) + +png2pnm$(E): png2pnm$(O) + $(LD) -o png2pnm$(E) png2pnm$(O) $(LDFLAGS) -lm + +png2pnm-static$(E): png2pnm$(O) + $(LD) -o png2pnm-static$(E) png2pnm$(O) $(LDFLAGSS) -lm + +pnm2png$(O): pnm2png$(C) + $(CC) -c $(CFLAGS) pnm2png$(C) + +pnm2png$(E): pnm2png$(O) + $(LD) -o pnm2png$(E) pnm2png$(O) $(LDFLAGS) -lm + +pnm2png-static$(E): pnm2png$(O) + $(LD) -o pnm2png-static$(E) pnm2png$(O) $(LDFLAGSS) -lm + +clean: + $(RM) png2pnm$(O) + $(RM) pnm2png$(O) + $(RM) png2pnm$(E) + $(RM) pnm2png$(E) + $(RM) png2pnm-static$(E) + $(RM) pnm2png-static$(E) + +# End of makefile for png2pnm / pnm2png diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.tc3 b/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.tc3 new file mode 100644 index 0000000..01062cc --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/makefile.tc3 @@ -0,0 +1,38 @@ +# Makefile for PngMinus (png2pnm and pnm2png) +# TurboC++ 3.0 + +CC=tcc -Ic:\tc3\inc +LD=tcc -Lc:\tc3\lib +LB=tlib +RM=del +CP=copy +MODEL=l +CCFLAGS=-O -m$(MODEL) -I..\libpng -I..\zlib +LDFLAGS=-m$(MODEL) -L..\libpng -L..\zlib +C=.c +O=.obj +L=.lib +E=.exe + +# dependencies + +all: png2pnm$(E) pnm2png$(E) + +png2pnm$(O): png2pnm$(C) + $(CC) -c $(CCFLAGS) png2pnm$(C) + +png2pnm$(E): png2pnm$(O) + $(LD) $(LDFLAGS) png2pnm$(O) libpng$(L) zlib$(L) + +pnm2png$(O): pnm2png$(C) + $(CC) -c $(CCFLAGS) pnm2png$(C) + +pnm2png$(E): pnm2png$(O) + $(LD) $(LDFLAGS) pnm2png$(O) libpng$(L) zlib$(L) + +clean: + $(RM) *$(O) + $(RM) *$(E) + +# End of makefile for png2pnm / pnm2png + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/makevms.com b/src/dep/src/irrlicht/libpng/contrib/pngminus/makevms.com new file mode 100644 index 0000000..96c3147 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/makevms.com @@ -0,0 +1,92 @@ +$!------------------------------------------------------------------------------ +$! make Contrib programs of libpng under OpenVMS +$! +$! +$! Look for the compiler used +$! +$ zlibsrc = "[---.zlib]" +$ ccopt="/include=(''zlibsrc',[--])" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" +$ then +$ comp = "__gcc__=1" +$ CC :== GCC +$ else +$ comp = "__vaxc__=1" +$ endif +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$ open/write lopt lib.opt +$ write lopt "[--]libpng.olb/lib" +$ write lopt "''zlibsrc'libz.olb/lib" +$ close lopt +$ open/write xopt x11.opt +$ write xopt "sys$library:decw$xlibshr.exe/share" +$ close xopt +$ write sys$output "Compiling PNG contrib programs ..." +$ write sys$output "Building pnm2png..." +$ CALL MAKE pnm2png.OBJ "cc ''CCOPT' pnm2png" - + pnm2png.c +$ call make pnm2png.exe - + "LINK pnm2png,lib.opt/opt" - + pnm2png.obj +$ write sys$output "Building png2pnm..." +$ CALL MAKE png2pnm.OBJ "cc ''CCOPT' png2pnm" - + png2pnm.c +$ call make png2pnm.exe - + "LINK png2pnm,lib.opt/opt" - + png2pnm.obj +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.bat b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.bat new file mode 100644 index 0000000..85abe3c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.bat @@ -0,0 +1,41 @@ +REM -- grayscale +png2pnm.exe -noraw ..\pngsuite\basn0g01.png basn0g01.pgm +png2pnm.exe -noraw ..\pngsuite\basn0g02.png basn0g02.pgm +png2pnm.exe -noraw ..\pngsuite\basn0g04.png basn0g04.pgm +png2pnm.exe -noraw ..\pngsuite\basn0g08.png basn0g08.pgm +png2pnm.exe -noraw ..\pngsuite\basn0g16.png basn0g16.pgm +REM -- full-color +png2pnm.exe -noraw ..\pngsuite\basn2c08.png basn2c08.ppm +png2pnm.exe -noraw ..\pngsuite\basn2c16.png basn2c16.ppm +REM -- palletted +png2pnm.exe -noraw ..\pngsuite\basn3p01.png basn3p01.ppm +png2pnm.exe -noraw ..\pngsuite\basn3p02.png basn3p02.ppm +png2pnm.exe -noraw ..\pngsuite\basn3p04.png basn3p04.ppm +png2pnm.exe -noraw ..\pngsuite\basn3p08.png basn3p08.ppm +REM -- gray with alpha-channel +png2pnm.exe -noraw ..\pngsuite\basn4a08.png basn4a08.pgm +png2pnm.exe -noraw ..\pngsuite\basn4a16.png basn4a16.pgm +REM -- color with alpha-channel +png2pnm.exe -noraw -alpha basn6a08.pgm ..\pngsuite\basn6a08.png basn6a08.ppm +png2pnm.exe -noraw -alpha basn6a16.pgm ..\pngsuite\basn6a16.png basn6a16.ppm +REM -- grayscale +png2pnm.exe -raw ..\pngsuite\basn0g01.png rawn0g01.pgm +png2pnm.exe -raw ..\pngsuite\basn0g02.png rawn0g02.pgm +png2pnm.exe -raw ..\pngsuite\basn0g04.png rawn0g04.pgm +png2pnm.exe -raw ..\pngsuite\basn0g08.png rawn0g08.pgm +png2pnm.exe -raw ..\pngsuite\basn0g16.png rawn0g16.pgm +REM -- full-color +png2pnm.exe -raw ..\pngsuite\basn2c08.png rawn2c08.ppm +png2pnm.exe -raw ..\pngsuite\basn2c16.png rawn2c16.ppm +REM -- palletted +png2pnm.exe -raw ..\pngsuite\basn3p01.png rawn3p01.ppm +png2pnm.exe -raw ..\pngsuite\basn3p02.png rawn3p02.ppm +png2pnm.exe -raw ..\pngsuite\basn3p04.png rawn3p04.ppm +png2pnm.exe -raw ..\pngsuite\basn3p08.png rawn3p08.ppm +REM -- gray with alpha-channel +png2pnm.exe -raw ..\pngsuite\basn4a08.png rawn4a08.pgm +png2pnm.exe -raw ..\pngsuite\basn4a16.png rawn4a16.pgm +REM -- color with alpha-channel +png2pnm.exe -noraw -alpha rawn6a08.pgm ..\pngsuite\basn6a08.png rawn6a08.ppm +png2pnm.exe -noraw -alpha rawn6a16.pgm ..\pngsuite\basn6a16.png rawn6a16.ppm + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.c b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.c new file mode 100644 index 0000000..6ed477b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.c @@ -0,0 +1,430 @@ +/* + * png2pnm.c --- conversion from PNG-file to PGM/PPM-file + * copyright (C) 1999 by Willem van Schaik + * + * version 1.0 - 1999.10.15 - First version. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation. This software is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#ifdef __TURBOC__ +#include +#include +#endif + +#ifndef BOOL +#define BOOL unsigned char +#endif +#ifndef TRUE +#define TRUE (BOOL) 1 +#endif +#ifndef FALSE +#define FALSE (BOOL) 0 +#endif + +#ifdef __TURBOC__ +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 +#endif + +/* to make png2pnm verbose so we can find problems (needs to be before png.h) */ +#ifndef PNG_DEBUG +#define PNG_DEBUG 0 +#endif + +#include "png.h" + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +/* function prototypes */ + +int main (int argc, char *argv[]); +void usage (); +BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha); + +/* + * main + */ + +int main(int argc, char *argv[]) +{ + FILE *fp_rd = stdin; + FILE *fp_wr = stdout; + FILE *fp_al = NULL; + BOOL raw = TRUE; + BOOL alpha = FALSE; + int argi; + + for (argi = 1; argi < argc; argi++) + { + if (argv[argi][0] == '-') + { + switch (argv[argi][1]) + { + case 'n': + raw = FALSE; + break; + case 'r': + raw = TRUE; + break; + case 'a': + alpha = TRUE; + argi++; + if ((fp_al = fopen (argv[argi], "wb")) == NULL) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: can not create alpha-channel file %s\n", argv[argi]); + exit (1); + } + break; + case 'h': + case '?': + usage(); + exit(0); + break; + default: + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: unknown option %s\n", argv[argi]); + usage(); + exit(1); + break; + } /* end switch */ + } + else if (fp_rd == stdin) + { + if ((fp_rd = fopen (argv[argi], "rb")) == NULL) + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: file %s does not exist\n", argv[argi]); + exit (1); + } + } + else if (fp_wr == stdout) + { + if ((fp_wr = fopen (argv[argi], "wb")) == NULL) + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: can not create file %s\n", argv[argi]); + exit (1); + } + } + else + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: too many parameters\n"); + usage(); + exit(1); + } + } /* end for */ + +#ifdef __TURBOC__ + /* set stdin/stdout if required to binary */ + if (fp_rd == stdin) + { + setmode (STDIN, O_BINARY); + } + if ((raw) && (fp_wr == stdout)) + { + setmode (STDOUT, O_BINARY); + } +#endif + + /* call the conversion program itself */ + if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE) + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: unsuccessful convertion of PNG-image\n"); + exit(1); + } + + /* close input file */ + fclose (fp_rd); + /* close output file */ + fclose (fp_wr); + /* close alpha file */ + if (alpha) + fclose (fp_al); + + return 0; +} + +/* + * usage + */ + +void usage() +{ + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, " by Willem van Schaik, 1999\n"); +#ifdef __TURBOC__ + fprintf (stderr, " for Turbo-C and Borland-C compilers\n"); +#else + fprintf (stderr, " for Linux (and Unix) compilers\n"); +#endif + fprintf (stderr, "Usage: png2pnm [options] .png [.pnm]\n"); + fprintf (stderr, " or: ... | png2pnm [options]\n"); + fprintf (stderr, "Options:\n"); + fprintf (stderr, " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n"); + fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n"); + fprintf (stderr, " -a[lpha] .pgm write PNG alpha channel as pgm-file\n"); + fprintf (stderr, " -h | -? print this help-information\n"); +} + +/* + * png2pnm + */ + +BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha) +{ + png_struct *png_ptr = NULL; + png_info *info_ptr = NULL; + png_byte buf[8]; + png_byte *png_pixels = NULL; + png_byte **row_pointers = NULL; + png_byte *pix_ptr = NULL; + png_uint_32 row_bytes; + + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int channels; + int color_type; + int alpha_present; + int row, col; + int ret; + int i; + long dep_16; + + /* read and check signature in PNG file */ + ret = fread (buf, 1, 8, png_file); + if (ret != 8) + return FALSE; + + ret = png_check_sig (buf, 8); + if (!ret) + return FALSE; + + /* create png and info structures */ + + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + if (!png_ptr) + return FALSE; /* out of memory */ + + info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) + { + png_destroy_read_struct (&png_ptr, NULL, NULL); + return FALSE; /* out of memory */ + } + + if (setjmp (png_jmpbuf(png_ptr))) + { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return FALSE; + } + + /* set up the input control for C streams */ + png_init_io (png_ptr, png_file); + png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */ + + /* read the file information */ + png_read_info (png_ptr, info_ptr); + + /* get size and bit-depth of the PNG-image */ + png_get_IHDR (png_ptr, info_ptr, + &width, &height, &bit_depth, &color_type, + NULL, NULL, NULL); + + /* set-up the transformations */ + + /* transform paletted images into full-color rgb */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand (png_ptr); + /* expand images to bit-depth 8 (only applicable for grayscale images) */ + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand (png_ptr); + /* transform transparency maps into full alpha-channel */ + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand (png_ptr); + +#ifdef NJET + /* downgrade 16-bit images to 8 bit */ + if (bit_depth == 16) + png_set_strip_16 (png_ptr); + /* transform grayscale images into full-color */ + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb (png_ptr); + /* only if file has a file gamma, we do a correction */ + if (png_get_gAMA (png_ptr, info_ptr, &file_gamma)) + png_set_gamma (png_ptr, (double) 2.2, file_gamma); +#endif + + /* all transformations have been registered; now update info_ptr data, + * get rowbytes and channels, and allocate image memory */ + + png_read_update_info (png_ptr, info_ptr); + + /* get the new color-type and bit-depth (after expansion/stripping) */ + png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + NULL, NULL, NULL); + + /* check for 16-bit files */ + if (bit_depth == 16) + { + raw = FALSE; +#ifdef __TURBOC__ + pnm_file->flags &= ~((unsigned) _F_BIN); +#endif + } + + /* calculate new number of channels and store alpha-presence */ + if (color_type == PNG_COLOR_TYPE_GRAY) + channels = 1; + else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + channels = 2; + else if (color_type == PNG_COLOR_TYPE_RGB) + channels = 3; + else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + channels = 4; + else + channels = 0; /* should never happen */ + alpha_present = (channels - 1) % 2; + + /* check if alpha is expected to be present in file */ + if (alpha && !alpha_present) + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n"); + exit (1); + } + + /* row_bytes is the width x number of channels x (bit-depth / 8) */ + row_bytes = png_get_rowbytes (png_ptr, info_ptr); + + if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return FALSE; + } + + if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) + { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + free (png_pixels); + png_pixels = NULL; + return FALSE; + } + + /* set the individual row_pointers to point at the correct offsets */ + for (i = 0; i < (height); i++) + row_pointers[i] = png_pixels + i * row_bytes; + + /* now we can go ahead and just read the whole image */ + png_read_image (png_ptr, row_pointers); + + /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end (png_ptr, info_ptr); + + /* clean up after the read, and free any memory allocated - REQUIRED */ + png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL); + + /* write header of PNM file */ + + if ((color_type == PNG_COLOR_TYPE_GRAY) || + (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + { + fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2"); + fprintf (pnm_file, "%d %d\n", (int) width, (int) height); + fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); + } + else if ((color_type == PNG_COLOR_TYPE_RGB) || + (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) + { + fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3"); + fprintf (pnm_file, "%d %d\n", (int) width, (int) height); + fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); + } + + /* write header of PGM file with alpha channel */ + + if ((alpha) && + ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) || + (color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + { + fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2"); + fprintf (alpha_file, "%d %d\n", (int) width, (int) height); + fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L)); + } + + /* write data to PNM file */ + pix_ptr = png_pixels; + + for (row = 0; row < height; row++) + { + for (col = 0; col < width; col++) + { + for (i = 0; i < (channels - alpha_present); i++) + { + if (raw) + fputc ((int) *pix_ptr++ , pnm_file); + else + if (bit_depth == 16){ + dep_16 = (long) *pix_ptr++; + fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++)); + } + else + fprintf (pnm_file, "%ld ", (long) *pix_ptr++); + } + if (alpha_present) + { + if (!alpha) + { + pix_ptr++; /* alpha */ + if (bit_depth == 16) + pix_ptr++; + } + else /* output alpha-channel as pgm file */ + { + if (raw) + fputc ((int) *pix_ptr++ , alpha_file); + else + if (bit_depth == 16){ + dep_16 = (long) *pix_ptr++; + fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++); + } + else + fprintf (alpha_file, "%ld ", (long) *pix_ptr++); + } + } /* if alpha_present */ + + if (!raw) + if (col % 4 == 3) + fprintf (pnm_file, "\n"); + } /* end for col */ + + if (!raw) + if (col % 4 != 0) + fprintf (pnm_file, "\n"); + } /* end for row */ + + if (row_pointers != (unsigned char**) NULL) + free (row_pointers); + if (png_pixels != (unsigned char*) NULL) + free (png_pixels); + + return TRUE; + +} /* end of source */ + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.sh b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.sh new file mode 100644 index 0000000..ee39664 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/png2pnm.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# -- grayscale +./png2pnm -noraw ../pngsuite/basn0g01.png basn0g01.pgm +./png2pnm -noraw ../pngsuite/basn0g02.png basn0g02.pgm +./png2pnm -noraw ../pngsuite/basn0g04.png basn0g04.pgm +./png2pnm -noraw ../pngsuite/basn0g08.png basn0g08.pgm +./png2pnm -noraw ../pngsuite/basn0g16.png basn0g16.pgm +# -- full-color +./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm +./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm +# -- palletted +./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm +./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm +./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm +./png2pnm -noraw ../pngsuite/basn3p08.png basn3p08.ppm +# -- gray with alpha-channel +./png2pnm -noraw ../pngsuite/basn4a08.png basn4a08.pgm +./png2pnm -noraw ../pngsuite/basn4a16.png basn4a16.pgm +# -- color with alpha-channel +./png2pnm -noraw -alpha basn6a08.pgm ../pngsuite/basn6a08.png basn6a08.ppm +./png2pnm -noraw -alpha basn6a16.pgm ../pngsuite/basn6a16.png basn6a16.ppm +# -- grayscale +./png2pnm -raw ../pngsuite/basn0g01.png rawn0g01.pgm +./png2pnm -raw ../pngsuite/basn0g02.png rawn0g02.pgm +./png2pnm -raw ../pngsuite/basn0g04.png rawn0g04.pgm +./png2pnm -raw ../pngsuite/basn0g08.png rawn0g08.pgm +./png2pnm -raw ../pngsuite/basn0g16.png rawn0g16.pgm +# -- full-color +./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm +./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm +# -- palletted +./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm +./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm +./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm +./png2pnm -raw ../pngsuite/basn3p08.png rawn3p08.ppm +# -- gray with alpha-channel +./png2pnm -raw ../pngsuite/basn4a08.png rawn4a08.pgm +./png2pnm -raw ../pngsuite/basn4a16.png rawn4a16.pgm +# -- color with alpha-channel +./png2pnm -noraw -alpha rawn6a08.pgm ../pngsuite/basn6a08.png rawn6a08.ppm +./png2pnm -noraw -alpha rawn6a16.pgm ../pngsuite/basn6a16.png rawn6a16.ppm + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.bat b/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.bat new file mode 100644 index 0000000..5f8d2d4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.bat @@ -0,0 +1,4 @@ +make -f makefile.tc3 +call png2pnm.bat +call pnm2png.bat + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.sh b/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.sh new file mode 100644 index 0000000..adcef55 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/pngminus.sh @@ -0,0 +1,5 @@ +#!/bin/sh +make -f makefile.std +sh png2pnm.sh +sh pnm2png.sh + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.bat b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.bat new file mode 100644 index 0000000..5b9977a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.bat @@ -0,0 +1,41 @@ +REM -- grayscale +pnm2png.exe basn0g01.pgm basn0g01.png +pnm2png.exe basn0g02.pgm basn0g02.png +pnm2png.exe basn0g04.pgm basn0g04.png +pnm2png.exe basn0g08.pgm basn0g08.png +pnm2png.exe basn0g16.pgm basn0g16.png +REM -- full-color +pnm2png.exe basn2c08.ppm basn2c08.png +pnm2png.exe basn2c16.ppm basn2c16.png +REM -- palletted +pnm2png.exe basn3p01.ppm basn3p01.png +pnm2png.exe basn3p02.ppm basn3p02.png +pnm2png.exe basn3p04.ppm basn3p04.png +pnm2png.exe basn3p08.ppm basn3p08.png +REM -- gray with alpha-channel +pnm2png.exe -alpha basn6a08.pgm basn4a08.pgm basn4a08.png +pnm2png.exe -alpha basn6a16.pgm basn4a16.pgm basn4a16.png +REM -- color with alpha-channel +pnm2png.exe -alpha basn6a08.pgm basn6a08.ppm basn6a08.png +pnm2png.exe -alpha basn6a16.pgm basn6a16.ppm basn6a16.png +REM -- grayscale +pnm2png.exe rawn0g01.pgm rawn0g01.png +pnm2png.exe rawn0g02.pgm rawn0g02.png +pnm2png.exe rawn0g04.pgm rawn0g04.png +pnm2png.exe rawn0g08.pgm rawn0g08.png +pnm2png.exe rawn0g16.pgm rawn0g16.png +REM -- full-color +pnm2png.exe rawn2c08.ppm rawn2c08.png +pnm2png.exe rawn2c16.ppm rawn2c16.png +REM -- palletted +pnm2png.exe rawn3p01.ppm rawn3p01.png +pnm2png.exe rawn3p02.ppm rawn3p02.png +pnm2png.exe rawn3p04.ppm rawn3p04.png +pnm2png.exe rawn3p08.ppm rawn3p08.png +REM -- gray with alpha-channel +pnm2png.exe -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png +pnm2png.exe -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png +REM -- color with alpha-channel +pnm2png.exe -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png +pnm2png.exe -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.c b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.c new file mode 100644 index 0000000..2f321cc --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.c @@ -0,0 +1,533 @@ +/* + * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file + * copyright (C) 1999 by Willem van Schaik + * + * version 1.0 - 1999.10.15 - First version. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation. This software is provided "as is" without + * express or implied warranty. + */ + +#include +#include +#ifdef __TURBOC__ +#include +#include +#endif + +#ifndef BOOL +#define BOOL unsigned char +#endif +#ifndef TRUE +#define TRUE (BOOL) 1 +#endif +#ifndef FALSE +#define FALSE (BOOL) 0 +#endif + +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +/* to make pnm2png verbose so we can find problems (needs to be before png.h) */ +#ifndef PNG_DEBUG +#define PNG_DEBUG 0 +#endif + +#include "png.h" + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +/* function prototypes */ + +int main (int argc, char *argv[]); +void usage (); +BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); +void get_token(FILE *pnm_file, char *token); +png_uint_32 get_data (FILE *pnm_file, int depth); +png_uint_32 get_value (FILE *pnm_file, int depth); + +/* + * main + */ + +int main(int argc, char *argv[]) +{ + FILE *fp_rd = stdin; + FILE *fp_al = NULL; + FILE *fp_wr = stdout; + BOOL interlace = FALSE; + BOOL alpha = FALSE; + int argi; + + for (argi = 1; argi < argc; argi++) + { + if (argv[argi][0] == '-') + { + switch (argv[argi][1]) + { + case 'i': + interlace = TRUE; + break; + case 'a': + alpha = TRUE; + argi++; + if ((fp_al = fopen (argv[argi], "rb")) == NULL) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: alpha-channel file %s does not exist\n", + argv[argi]); + exit (1); + } + break; + case 'h': + case '?': + usage(); + exit(0); + break; + default: + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: unknown option %s\n", argv[argi]); + usage(); + exit(1); + break; + } /* end switch */ + } + else if (fp_rd == stdin) + { + if ((fp_rd = fopen (argv[argi], "rb")) == NULL) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: file %s does not exist\n", argv[argi]); + exit (1); + } + } + else if (fp_wr == stdout) + { + if ((fp_wr = fopen (argv[argi], "wb")) == NULL) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: can not create PNG-file %s\n", argv[argi]); + exit (1); + } + } + else + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: too many parameters\n"); + usage(); + exit (1); + } + } /* end for */ + +#ifdef __TURBOC__ + /* set stdin/stdout to binary, we're reading the PNM always! in binary format */ + if (fp_rd == stdin) + { + setmode (STDIN, O_BINARY); + } + if (fp_wr == stdout) + { + setmode (STDOUT, O_BINARY); + } +#endif + + /* call the conversion program itself */ + if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: unsuccessful converting to PNG-image\n"); + exit (1); + } + + /* close input file */ + fclose (fp_rd); + /* close output file */ + fclose (fp_wr); + /* close alpha file */ + if (alpha) + fclose (fp_al); + + return 0; +} + +/* + * usage + */ + +void usage() +{ + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, " by Willem van Schaik, 1999\n"); +#ifdef __TURBOC__ + fprintf (stderr, " for Turbo-C and Borland-C compilers\n"); +#else + fprintf (stderr, " for Linux (and Unix) compilers\n"); +#endif + fprintf (stderr, "Usage: pnm2png [options] . [.png]\n"); + fprintf (stderr, " or: ... | pnm2png [options]\n"); + fprintf (stderr, "Options:\n"); + fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n"); + fprintf (stderr, " -a[lpha] .pgm read PNG alpha channel as pgm-file\n"); + fprintf (stderr, " -h | -? print this help-information\n"); +} + +/* + * pnm2png + */ + +BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) +{ + png_struct *png_ptr = NULL; + png_info *info_ptr = NULL; + png_byte *png_pixels = NULL; + png_byte **row_pointers = NULL; + png_byte *pix_ptr = NULL; + png_uint_32 row_bytes; + + char type_token[16]; + char width_token[16]; + char height_token[16]; + char maxval_token[16]; + int color_type; + png_uint_32 width, alpha_width; + png_uint_32 height, alpha_height; + png_uint_32 maxval; + int bit_depth = 0; + int channels; + int alpha_depth = 0; + int alpha_present; + int row, col; + BOOL raw, alpha_raw = FALSE; + png_uint_32 tmp16; + int i; + + /* read header of PNM file */ + + get_token(pnm_file, type_token); + if (type_token[0] != 'P') + { + return FALSE; + } + else if ((type_token[1] == '1') || (type_token[1] == '4')) + { + raw = (type_token[1] == '4'); + color_type = PNG_COLOR_TYPE_GRAY; + bit_depth = 1; + } + else if ((type_token[1] == '2') || (type_token[1] == '5')) + { + raw = (type_token[1] == '5'); + color_type = PNG_COLOR_TYPE_GRAY; + get_token(pnm_file, width_token); + sscanf (width_token, "%lu", &width); + get_token(pnm_file, height_token); + sscanf (height_token, "%lu", &height); + get_token(pnm_file, maxval_token); + sscanf (maxval_token, "%lu", &maxval); + if (maxval <= 1) + bit_depth = 1; + else if (maxval <= 3) + bit_depth = 2; + else if (maxval <= 15) + bit_depth = 4; + else if (maxval <= 255) + bit_depth = 8; + else /* if (maxval <= 65535) */ + bit_depth = 16; + } + else if ((type_token[1] == '3') || (type_token[1] == '6')) + { + raw = (type_token[1] == '6'); + color_type = PNG_COLOR_TYPE_RGB; + get_token(pnm_file, width_token); + sscanf (width_token, "%lu", &width); + get_token(pnm_file, height_token); + sscanf (height_token, "%lu", &height); + get_token(pnm_file, maxval_token); + sscanf (maxval_token, "%lu", &maxval); + if (maxval <= 1) + bit_depth = 1; + else if (maxval <= 3) + bit_depth = 2; + else if (maxval <= 15) + bit_depth = 4; + else if (maxval <= 255) + bit_depth = 8; + else /* if (maxval <= 65535) */ + bit_depth = 16; + } + else + { + return FALSE; + } + + /* read header of PGM file with alpha channel */ + + if (alpha) + { + if (color_type == PNG_COLOR_TYPE_GRAY) + color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + if (color_type == PNG_COLOR_TYPE_RGB) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + + get_token(alpha_file, type_token); + if (type_token[0] != 'P') + { + return FALSE; + } + else if ((type_token[1] == '2') || (type_token[1] == '5')) + { + alpha_raw = (type_token[1] == '5'); + get_token(alpha_file, width_token); + sscanf (width_token, "%lu", &alpha_width); + if (alpha_width != width) + return FALSE; + get_token(alpha_file, height_token); + sscanf (height_token, "%lu", &alpha_height); + if (alpha_height != height) + return FALSE; + get_token(alpha_file, maxval_token); + sscanf (maxval_token, "%lu", &maxval); + if (maxval <= 1) + alpha_depth = 1; + else if (maxval <= 3) + alpha_depth = 2; + else if (maxval <= 15) + alpha_depth = 4; + else if (maxval <= 255) + alpha_depth = 8; + else /* if (maxval <= 65535) */ + alpha_depth = 16; + if (alpha_depth != bit_depth) + return FALSE; + } + else + { + return FALSE; + } + } /* end if alpha */ + + /* calculate the number of channels and store alpha-presence */ + if (color_type == PNG_COLOR_TYPE_GRAY) + channels = 1; + else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + channels = 2; + else if (color_type == PNG_COLOR_TYPE_RGB) + channels = 3; + else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + channels = 4; + else + channels = 0; /* should not happen */ + + alpha_present = (channels - 1) % 2; + + /* row_bytes is the width x number of channels x (bit-depth / 8) */ + row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); + + if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) + return FALSE; + + /* read data from PNM file */ + pix_ptr = png_pixels; + + for (row = 0; row < height; row++) + { + for (col = 0; col < width; col++) + { + for (i = 0; i < (channels - alpha_present); i++) + { + if (raw) + *pix_ptr++ = get_data (pnm_file, bit_depth); + else + if (bit_depth <= 8) + *pix_ptr++ = get_value (pnm_file, bit_depth); + else + { + tmp16 = get_value (pnm_file, bit_depth); + *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); + pix_ptr++; + *pix_ptr = (png_byte) (tmp16 & 0xFF); + pix_ptr++; + } + } + + if (alpha) /* read alpha-channel from pgm file */ + { + if (alpha_raw) + *pix_ptr++ = get_data (alpha_file, alpha_depth); + else + if (alpha_depth <= 8) + *pix_ptr++ = get_value (alpha_file, bit_depth); + else + { + tmp16 = get_value (alpha_file, bit_depth); + *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF); + *pix_ptr++ = (png_byte) (tmp16 & 0xFF); + } + } /* if alpha */ + + } /* end for col */ + } /* end for row */ + + /* prepare the standard PNG structures */ + png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + return FALSE; + } + info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) + { + png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + return FALSE; + } + + /* setjmp() must be called in every function that calls a PNG-reading libpng function */ + if (setjmp (png_jmpbuf(png_ptr))) + { + png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + return FALSE; + } + + /* initialize the png structure */ + png_init_io (png_ptr, png_file); + + /* we're going to write more or less the same PNG as the input file */ + png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, + (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* write the file header information */ + png_write_info (png_ptr, info_ptr); + + /* if needed we will allocate memory for an new array of row-pointers */ + if (row_pointers == (unsigned char**) NULL) + { + if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) + { + png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + return FALSE; + } + } + + /* set the individual row_pointers to point at the correct offsets */ + for (i = 0; i < (height); i++) + row_pointers[i] = png_pixels + i * row_bytes; + + /* write out the entire image data in one call */ + png_write_image (png_ptr, row_pointers); + + /* write the additional chuncks to the PNG file (not really needed) */ + png_write_end (png_ptr, info_ptr); + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + + if (row_pointers != (unsigned char**) NULL) + free (row_pointers); + if (png_pixels != (unsigned char*) NULL) + free (png_pixels); + + return TRUE; +} /* end of pnm2png */ + +/* + * get_token() - gets the first string after whitespace + */ + +void get_token(FILE *pnm_file, char *token) +{ + int i = 0; + + /* remove white-space */ + do + { + token[i] = (unsigned char) fgetc (pnm_file); + } + while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' ')); + + /* read string */ + do + { + i++; + token[i] = (unsigned char) fgetc (pnm_file); + } + while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' ')); + + token[i] = '\0'; + + return; +} + +/* + * get_data() - takes first byte and converts into next pixel value, + * taking as much bits as defined by bit-depth and + * using the bit-depth to fill up a byte (0Ah -> AAh) + */ + +png_uint_32 get_data (FILE *pnm_file, int depth) +{ + static int bits_left = 0; + static int old_value = 0; + static int mask = 0; + int i; + png_uint_32 ret_value; + + if (mask == 0) + for (i = 0; i < depth; i++) + mask = (mask >> 1) | 0x80; + + if (bits_left <= 0) + { + old_value = fgetc (pnm_file); + bits_left = 8; + } + + ret_value = old_value & mask; + for (i = 1; i < (8 / depth); i++) + ret_value = ret_value || (ret_value >> depth); + + old_value = (old_value << depth) & 0xFF; + bits_left -= depth; + + return ret_value; +} + +/* + * get_value() - takes first (numeric) string and converts into number, + * using the bit-depth to fill up a byte (0Ah -> AAh) + */ + +png_uint_32 get_value (FILE *pnm_file, int depth) +{ + static png_uint_32 mask = 0; + png_byte token[16]; + png_uint_32 ret_value; + int i = 0; + + if (mask == 0) + for (i = 0; i < depth; i++) + mask = (mask << 1) | 0x01; + + get_token (pnm_file, (char *) token); + sscanf ((const char *) token, "%lu", &ret_value); + + ret_value &= mask; + + if (depth < 8) + for (i = 0; i < (8 / depth); i++) + ret_value = (ret_value << depth) || ret_value; + + return ret_value; +} + +/* end of source */ + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.sh b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.sh new file mode 100644 index 0000000..975f047 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/pngminus/pnm2png.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# -- grayscale +./pnm2png basn0g01.pgm basn0g01.png +./pnm2png basn0g02.pgm basn0g02.png +./pnm2png basn0g04.pgm basn0g04.png +./pnm2png basn0g08.pgm basn0g08.png +./pnm2png basn0g16.pgm basn0g16.png +# -- full-color +./pnm2png basn2c08.ppm basn2c08.png +./pnm2png basn2c16.ppm basn2c16.png +# -- palletted +./pnm2png basn3p01.ppm basn3p01.png +./pnm2png basn3p02.ppm basn3p02.png +./pnm2png basn3p04.ppm basn3p04.png +./pnm2png basn3p08.ppm basn3p08.png +# -- gray with alpha-channel +./pnm2png -alpha basn6a08.pgm basn4a08.pgm basn4a08.png +./pnm2png -alpha basn6a16.pgm basn4a16.pgm basn4a16.png +# -- color with alpha-channel +./pnm2png -alpha basn6a08.pgm basn6a08.ppm basn6a08.png +./pnm2png -alpha basn6a16.pgm basn6a16.ppm basn6a16.png +# -- grayscale +./pnm2png rawn0g01.pgm rawn0g01.png +./pnm2png rawn0g02.pgm rawn0g02.png +./pnm2png rawn0g04.pgm rawn0g04.png +./pnm2png rawn0g08.pgm rawn0g08.png +./pnm2png rawn0g16.pgm rawn0g16.png +# -- full-color +./pnm2png rawn2c08.ppm rawn2c08.png +./pnm2png rawn2c16.ppm rawn2c16.png +# -- palletted +./pnm2png rawn3p01.ppm rawn3p01.png +./pnm2png rawn3p02.ppm rawn3p02.png +./pnm2png rawn3p04.ppm rawn3p04.png +./pnm2png rawn3p08.ppm rawn3p08.png +# -- gray with alpha-channel +./pnm2png -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png +./pnm2png -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png +# -- color with alpha-channel +./pnm2png -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png +./pnm2png -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png + diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g01.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g01.png new file mode 100644 index 0000000000000000000000000000000000000000..e31e1c7a635b50e22b6d02ab8ba21f8099b39faa GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk~Bp9L@-6Me%OS+@4BLidG0>c;6;z7cmE{-7_ zGj-2wzopr084i?r2qf` literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g02.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g02.png new file mode 100644 index 0000000000000000000000000000000000000000..68809dd8fc0993ddebce8aa9c7bf9bbecbd36cfc GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk`Bp75C+I9jdmUKs7M+U~W1%@xC#RK{Bo-U3d y5>t~CIAXub_k1+y2sp$L+}6)%%qgEdVJADoUeEf*_U-^?kP)7)elF{r5}E*i=NeZ4 literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g04.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g04.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa089cb8a4ba0e8421ea05d33676856f0cac93c GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk^Bp4c;6;(>fePZ!4! zi{9jv1QiAmjuV@CSXq1cIW&KKm$y%-G>{Q7I3+kCJ!Mg43=bP?PydHg|Nfu<(f+K^ hPy#6PU}|a#3q!!ue}#oBxm7@xc)I$ztaD0e0szfSD4qZS literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g16.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn0g16.png new file mode 100644 index 0000000000000000000000000000000000000000..318ebcadf4fd0b64fb9b824e81c0cc8e3dfd2d82 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^3Lq>1BpBEle`W(ImUKs7M+U~W1%@xC#RK_qo-U3d z9-UV&8FC#k;BgMLjDBB#?9PJ82Q;dUu4=I?zS(bY(Xf0+xUg{Y0;{G3S&o?ucbmRB zoML$)c8ASL&0+fj+X+UDyI8k3PT;(to58=tC&50S{f++@NsIIK3}QFDZ^ZA8J8=o* N0#8>zmvv4FO#l#XIHLdn literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn2c08.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..21d2f91a868fc637fdae4fba6c87bfd09b158815 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={WSkfJR9T^zg78t&m77yfmc)B=- zcyzwKdXSUBfQQMU_07b;+lz#)U9`U}{BiD~_7+|i>jo~7A2JKxKB@JoaA;)W_iC3v r)WR;J@nJ!Uh4M;=#@z+wiw`h1ZTuN$cYX2NTxus~-YE?|ew94KIo9tHTv?hhRR zwrA%J^h9UxCeRmyPjW#d?oxNFL9(uFDZ1gBle+D$rIj`J+5;}Xa zfF63WfGT3xy1iYa$zve>zUQQss#Q*>R07*qoM6N<$g1`fR ASpWb4 literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p01.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn3p01.png new file mode 100644 index 0000000000000000000000000000000000000000..a21db5977462c4c0985a0ca1ac2d67ec572d3d17 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;SkfJR9T^zg78t&m77ygJ1^9%x zzWcAFl=eSI>XI5zMAXy8F@$4g@&k4zHj_up0tD0@h%3W?AY}Lt#0>va?X`CSX(dk=#}J9B$v@Vz>816FsF9(VN75txh7sS~8e>Vez z3y|e5zLEEca@?OO&kPSTILuD+yidi?7W^QF z0=7twg95}IGPB`0p){BIDdQnXEGb?R1lBYr!w>|Li8PIP)G{}a$YQ`p%(`K)LO3UD z6M@=IHq>+iwp~U6B7p@ho9?k)W)s^cNfJ5alp|5o3vi!RBHkmgX}UWIuw)VII#g=d z$04w7jssURBxceP_z6C6HW{SZU_uGkHHZpyqy!k&kY2+c1*akQFoehhD3_nQ9ng;b z0F#8v3ad!gP>4LFqCR|KhXmq>PACHhpyFVSOH8CTvPiZqN$iqqnyfQJ&?bvale$n1 zTv^)Th9oKqsKIPjfKCD1Cd3{VRFz%0i$*94z+D%LEeH_80824wDGaq4ThALK_0kH^LL!W!ET%TWXjP zf+UjIVU&gj2dkjg55o;~Er9W|;Xj52QG;=_Fb4{JL{~@@LhLOJ3noJ*c>^l+tMCGO zCYz+He>Pl<|Ld_f zqkm1#%jMM-%}evv+<)~($raC^D<>wy%g2N5PX<@DWeyA$O75|=jlHcE2YqXoq<-r^ zSF~%HYo3ID?48vDt>55dBr2eB{o9GWV*`fG5Jx3PvhgDLYTpZ#Qi+|CPMFK>V8kJOfm z#*Z=w{NC;LVI4^y_wGIZ+0l95T|3etXWUAydp~nc!u}QYkLn)pJU@Hlx;E!j?tzqu zY2yX+->z>?3??Uzz4BVazO+Xz%j8eHAEZy_UHonH-GsLIpF6E1$sG&stX%!v*c@Yf zL&of5NeNZAyW0FGPYv%K9`*NV3kUPJUh!4N^d%dUzFDUR&e(zJm#a=^UXXnc(yA(I z-;o2p70nAqE-$V851jZH`@`rk4UEa{HEjtq=#3k+XOiwE*eJzX3_ zJUWyAoIh}Yv2{*{iJ{UQo%@m+%sTdM`xqA|8c4B)7$%qqxF2rNV(Vdhlpzstn1SKG XmO|}<{e=-g0~kDA{an^LB{Ts5zRx3; literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn4a16.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn4a16.png new file mode 100644 index 0000000000000000000000000000000000000000..6dbee9fbdb93f3535be23326a52fb4d3ac60711e GIT binary patch literal 2206 zcmV;P2x0e$P)kEEkx>-b1@Qb$y-ohUek5*oTfx-A#6y^c`Q zE+sS)yU66wLTO83iFXm5i(N>*n3Idp^rFd-7Fe(v0)u8Hg(Rko(t3o_;+1WoY3fR? z;u%**k?mvsIhJ?vei@;3*EJZKPsh^xKJW8B&+`FbWnox{J*QyQf)~!hu>m;#N5~Gr z*+0X@UGUyz_~;4v=U?IOURb{_zjyb_*+);vGZ%Ns|73^cGmZ_&XO3F(9mBeOCxB*U zp=MjTt{LzZp}PWF5dym*a0v7!gx-ecb!ZpC(_mu+I?n=c$cJ>2a^`8!UXW*-DOjHb z_YkaIf>i_R6{x46R)AUxtZXgQHLOFeVC9@tBpY?%Ar~H6|39xka0c+50pEqb_xeL; z>a}V>WX7?rbSB#R07d+ApMY-yAH>T3O$tpzVWT4D`KV9D#5e8fT$B0UQ0W`4d&ZJhZPsBMV$%MrM45S^qKLL>pn6E&%2tD%( zfxsaMlx61rFQs$e8K{_6R*OS$5R5?x4}vuajX`MdfzF^5&@Mrv1ZyRz{~eqXESKOv zC8(4kRQ&NCC3e`!t zTZ4s<;Z`0-CLBBdHEi7qkvf2J|EZXCOGP5NH>n6_-74c*6GZ37L6suXG-K z4CW`TtWk#kGCXQS`*SIvW& ze;)x)gZ678GOZ6~)z<4mILi{)`)Xj6VJ;rYMiMZbfJQTN3< z-w!`MDg}Ig4z9ir2NE@VR~cfbAbJpyzjJG1I)@lji+);sjI05nfaPE90J3cN2oI4LMzvS4Dmtmj`)-)Kipf5lm0R9Eg z($KwIiQO+n{(bK$1b72BlcMdLkBGu;UX?xXbcF5RDVcdAA)Swp!;446R4=_#v$t=D zz6+p#1O8K>O@QxD;PZj64qX$_)dyW8(DgUyDgtM~$B+D@)ok(ejv=nLaagq78xe(T zwPerTQDOVyHJSOj^U^uMi$~z)m*DX-4D18zgc`veH3Ac~yc)q}HG(AgY|tG00TSjE z39l#;mV|^Wv$E%vxUl`|`!e(G+og+_Uy_0jBw$w@Vv`WfKS07T1Ph9UIYq+fpnH!( z;D2j4rPeSn#&p)`Qj5U(Rr4MKU)UxPqX ztzk;7p<_#oYK2so@RX&V5M!xUMP3&^7LnOocI;h>?fN%Tz`#D~+=;_n9NcNR_n;7s zK<_CC-2h!vLX-smkV2q&9h#r2B=eN=^OCsQ(voQVt-L7Q&L?Hht!ZI9$joDt(z!bg z^OMk=0QYNHU4=*(%mVbj1IA4y#YrW_j;#XZ?^TR?UBZO(f>>&$BE~W@;n+h@D`@Wu z$+QV6z?hYpZ?mNH=7bd79)?B(Toc^9GNU(@8Kod-D+Jaj!40VlcSDlQ@=@{gQdwLr z{7&Zb}S~Y7L5w23`5q-r&J^mkTcViXI59GbI+3oJQLb^Xa=CM0~+5#BMC-O zA+UA{R^F8K>THn=w^)!Q^Kf1Hd0kwsr!Ly=Ul4@@*>gQCY&S<_=B_E7dnQy&=%m3* zDCd0zS}ADFD+E>zs2dWUs|O`O4x}A>>t~W=B5CF4X>qmStD@~)iUV3+_B@mqwwnc+ zd9xs$chb^OXB50E(5^x|39aW80`&^qb0xPgtMuBRkPK&4ggm`H%Fo9{P`Y=EwuAib zKPY=1x*=>g=Va#1fOOs&mBuk$A(S{Hf;FuuV#)d7sbeoV@Fcz z#`3Pp?K3L97A3<4ijriy)kU_eC)4|}U(UH||907*qoM6N<$f-(OD1poj5 literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn6a08.png b/src/dep/src/irrlicht/libpng/contrib/pngsuite/basn6a08.png new file mode 100644 index 0000000000000000000000000000000000000000..61062308548bc3a5255e3e8dbb7f97932f00eb1c GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+U~W1%@xC#RK{Io-U3d z5v^~p8FDok@VGrxPs#9K_}xB~rC;&L-J`A*vOzBbH2%o@YTWE%G>EINoAZB{akFeG zt2^^4wiQ2lBNnjxnaU~EHpDcAJeJR?S{LDp`Fk}h0vV{=c>|`0F zY}t2XhO#pw*@@4+-}ija_s93gIp?4AJnwVP`=0Zh6Lm*li-YYn8vpunKbAURdar&!F_@9SoS%FU_nL5v4bhxdo;qYV}(%9Z85QFC@Q_IDD58Vx)&SPd#1 z&_z21b`BlfZb@Z16}%Yv2Xg?CHRMe7qkJ)iJY&NQ*3GZeU+ur74iHv1P36E6yN%N5 zpV$8~7z8Rae`?A#-PAcaas4$5zYproUQo8+k=bWG?@3hw>tAT`15|X+#pzBR*EFaZTfujS2W+R%rAX5GszY`8KG_1tm1wxz^bYuH^_iu1 z#`8Dkd|UXn0~66IH5Y)%1^wg@FJA3z9$T7YRh1FE(o z&iHoiEcavc!3({fssSC{c=<uH$6|lJ`Cw^#7+?9Oeh5*sk;TrZA_sxq|m5T=dEMGV0i z^PYDhxn{(1ZN~3SMiq)&y^i@u;6U{BWs8VI#ZOVtSIoPu#Uy>G@F^}60slpM% z4fg4f0@c(&o=lnNB5(wh%7VCL!-EVW2Z|!o{aAn*D%&65S@(Uw9aQtxwD)dfkbS0D zN4fECZ9%?vJvB6eQZ4WGA92VxeEjiXK}uR*cR55gZ_cQBgwFlZzlpoCI^@-;A(;$?Ag&)@JLm6Q6RE$C5WB$XVqD_cH4>}=w0RmK|UFq zqT&JFo{xshQhkO07xrmHL>wC3kOr5B~p#zX7$p_c_}QIK>i^mAbP z(RxI|(i~*Q0#6E}svtMT(M} zh+aH!wG#=NVm~3Dv%@S5-kh)W{c#dFYEqq2IfIFM+s<@5JzKFU(kzGaEKDY05{~)y z&m>r1+fS3X-!8#9ZC}|9nR|zJTO|nFEi^1Tfpt@Ll^mIY?oP}|^w=aDOTn=uec<16y1Ij2viXQ-skm0LAjJTsD=F!#DdRhpGW%{rtjIuduzuQ<{wdf>RTZ$_*JNG)(wu0^Ec6FbT<6xqSx? z_!3zIUUfCS)6fLwA!%9Yvs}RFb1bBZaM#FX`Dt@6LHtQA1;AaBd4qVKP{nI32V#wJ z&XhLUx0p{l^jo|vK~SZ`ptJ4mne>h=EQ)IBapSiJu{K;#J#&J6T*;znj93+*IlB6?-&YMGi|#xn!fR)W?0*~Y-v zJb%t6l>}jz9_AsI@@RuRW(OUfTdY%wuhTG}3Ve9pnfH+Qw4C3B8)Pv=6}W4d99_e^ z#9AT03q=Y1K=%(%UJPCeUhitoH`-hON*?knX(%Hos$uAK073oP!1*Xq-mClxyor$@ z}heD;=s0m{le|mRTbo3Wp+E$278tBRf$HlP|fM)?++96CPyL1+wsjf zVk53I^h-S=*7nAhx<|s)bJ8w@jBPCFcgym*E9ryTcW-vs2fn~wpR?z?3`C&?_rYej3k<^}V2IPiv-8;{mgi2hH ztlSGT$s1@-?Cm1cFWbX9F{sRWv(?cibljVBrb znh0Bb)h@WE8=d#nxg!?mgZ_jv{v*Mtb>{rWq@mQ%GO4pYbYY3NhtwS%vk@F6@Cv0q z;32kUm2%K;GCpIm7nY^O2baB-b57D+>*@DbC6}<(k6UKuV_t7>0Ad1l2vQK9%E7Iu z&(5t^!vq|;yR##&(?y9Bxh>PK;x24md0z_`OZ&EXN0znDnHMLgT0vE z_yTz|TbH$rwir9{GXE3${#InnMxfp1xrN`krccn6rI*N0fJ7fVs@lf)c+k@Bj%@7x zn2jh^(!=IcnGPq-s=mA+pAQRc3WQ}3(CFdc(eD`%-gjE}`d9j0woiiIO||T#+v6=j zd(Vm%BvEfmcrs6v+tJ!B*r>Oomj6Yn^vw~qcjX^|m%*OM51be;(%YN8T!+aSl}jzO z!y8LjI?!s%Jnta+*LWjuuoDMp8d{FnQWAsFx^5}~^aqjGKt--Tz&i+DWSigz|HVB- z?p9v``EK^JY(aBjc6TFYcV~A?IDo|@Q%5w24{w**chBHLlrK0ny!nC(PsT1>Hqnih z{Bkl=fi=xu0ZFjuFh^xM2sQ&sXR~!_Qd=m2&L2Axw6>g3OQD`iWxG zSjeAUfi`M4@n+JdMglmRaM{EnaIoCk%7r&sK1kSNCR{49-Ta zj?6y#Lz!(+99uqME>10f)qmtbigTu-hI=Xb4zcPc{eH2y_7vv*s( z*^3PwpUJg-5C=DiVuy>>a!|8$e5K?M)}J02FLf0O{QRMti|gU9yM zpsH)mY4IMnhuI +#include +#include +#include + +#include "png.h" +#include "pngfile.h" +#include "cexcept.h" + +define_exception_type(const char *); +extern struct exception_context the_exception_context[1]; +struct exception_context the_exception_context[1]; +png_const_charp msg; + +static OPENFILENAME ofn; + +static png_structp png_ptr = NULL; +static png_infop info_ptr = NULL; + + +// cexcept interface + +static void +png_cexcept_error(png_structp png_ptr, png_const_charp msg) +{ + if(png_ptr) + ; +#ifndef PNG_NO_CONSOLE_IO + fprintf(stderr, "libpng error: %s\n", msg); +#endif + { + Throw msg; + } +} + +// Windows open-file functions + +void PngFileInitialize (HWND hwnd) +{ + static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0") + TEXT ("All Files (*.*)\0*.*\0\0"); + + ofn.lStructSize = sizeof (OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.hInstance = NULL; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 0; + ofn.lpstrFile = NULL; // Set in Open and Close functions + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; // Set in Open and Close functions + ofn.nMaxFileTitle = MAX_PATH; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = NULL; + ofn.Flags = 0; // Set in Open and Close functions + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = TEXT ("png"); + ofn.lCustData = 0; + ofn.lpfnHook = NULL; + ofn.lpTemplateName = NULL; +} + +BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) +{ + ofn.hwndOwner = hwnd; + ofn.lpstrFile = pstrFileName; + ofn.lpstrFileTitle = pstrTitleName; + ofn.Flags = OFN_HIDEREADONLY; + + return GetOpenFileName (&ofn); +} + +BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) +{ + ofn.hwndOwner = hwnd; + ofn.lpstrFile = pstrFileName; + ofn.lpstrFileTitle = pstrTitleName; + ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + return GetSaveFileName (&ofn); +} + +// PNG image handler functions + +BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, + int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor) +{ + static FILE *pfFile; + png_byte pbSig[8]; + int iBitDepth; + int iColorType; + double dGamma; + png_color_16 *pBackground; + png_uint_32 ulChannels; + png_uint_32 ulRowBytes; + png_byte *pbImageData = *ppbImageData; + static png_byte **ppbRowPointers = NULL; + int i; + + // open the PNG input file + + if (!pstrFileName) + { + *ppbImageData = pbImageData = NULL; + return FALSE; + } + + if (!(pfFile = fopen(pstrFileName, "rb"))) + { + *ppbImageData = pbImageData = NULL; + return FALSE; + } + + // first check the eight byte PNG signature + + fread(pbSig, 1, 8, pfFile); + if (!png_check_sig(pbSig, 8)) + { + *ppbImageData = pbImageData = NULL; + return FALSE; + } + + // create the two png(-info) structures + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, + (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); + if (!png_ptr) + { + *ppbImageData = pbImageData = NULL; + return FALSE; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + *ppbImageData = pbImageData = NULL; + return FALSE; + } + + Try + { + + // initialize the png structure + +#if !defined(PNG_NO_STDIO) + png_init_io(png_ptr, pfFile); +#else + png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data); +#endif + + png_set_sig_bytes(png_ptr, 8); + + // read all PNG info up to image data + + png_read_info(png_ptr, info_ptr); + + // get width, height, bit-depth and color-type + + png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, + &iColorType, NULL, NULL, NULL); + + // expand images of all color-type and bit-depth to 3x8 bit RGB images + // let the library process things like alpha, transparency, background + + if (iBitDepth == 16) + png_set_strip_16(png_ptr); + if (iColorType == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (iBitDepth < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (iColorType == PNG_COLOR_TYPE_GRAY || + iColorType == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + // set the background color to draw transparent and alpha images over. + if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) + { + png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + pBkgColor->red = (byte) pBackground->red; + pBkgColor->green = (byte) pBackground->green; + pBkgColor->blue = (byte) pBackground->blue; + } + else + { + pBkgColor = NULL; + } + + // if required set gamma conversion + if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) + png_set_gamma(png_ptr, (double) 2.2, dGamma); + + // after the transformations have been registered update info_ptr data + + png_read_update_info(png_ptr, info_ptr); + + // get again width, height and the new bit-depth and color-type + + png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, + &iColorType, NULL, NULL, NULL); + + + // row_bytes is the width x number of channels + + ulRowBytes = png_get_rowbytes(png_ptr, info_ptr); + ulChannels = png_get_channels(png_ptr, info_ptr); + + *piChannels = ulChannels; + + // now we can allocate memory to store the image + + if (pbImageData) + { + free (pbImageData); + pbImageData = NULL; + } + if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight) + * sizeof(png_byte))) == NULL) + { + png_error(png_ptr, "Visual PNG: out of memory"); + } + *ppbImageData = pbImageData; + + // and allocate memory for an array of row-pointers + + if ((ppbRowPointers = (png_bytepp) malloc((*piHeight) + * sizeof(png_bytep))) == NULL) + { + png_error(png_ptr, "Visual PNG: out of memory"); + } + + // set the individual row-pointers to point at the correct offsets + + for (i = 0; i < (*piHeight); i++) + ppbRowPointers[i] = pbImageData + i * ulRowBytes; + + // now we can go ahead and just read the whole image + + png_read_image(png_ptr, ppbRowPointers); + + // read the additional chunks in the PNG file (not really needed) + + png_read_end(png_ptr, NULL); + + // and we're done + + free (ppbRowPointers); + ppbRowPointers = NULL; + + // yepp, done + } + + Catch (msg) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + *ppbImageData = pbImageData = NULL; + + if(ppbRowPointers) + free (ppbRowPointers); + + fclose(pfFile); + + return FALSE; + } + + fclose (pfFile); + + return TRUE; +} + + +BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, + int iWidth, int iHeight, png_color bkgColor) +{ + const int ciBitDepth = 8; + const int ciChannels = 3; + + static FILE *pfFile; + png_uint_32 ulRowBytes; + static png_byte **ppbRowPointers = NULL; + int i; + + // open the PNG output file + + if (!pstrFileName) + return FALSE; + + if (!(pfFile = fopen(pstrFileName, "wb"))) + return FALSE; + + // prepare the standard PNG structures + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, + (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); + if (!png_ptr) + { + fclose(pfFile); + return FALSE; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + fclose(pfFile); + png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + return FALSE; + } + + Try + { + // initialize the png structure + +#if !defined(PNG_NO_STDIO) + png_init_io(png_ptr, pfFile); +#else + png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush); +#endif + + // we're going to write a very simple 3x8 bit RGB image + + png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + // write the file header information + + png_write_info(png_ptr, info_ptr); + + // swap the BGR pixels in the DiData structure to RGB + + png_set_bgr(png_ptr); + + // row_bytes is the width x number of channels + + ulRowBytes = iWidth * ciChannels; + + // we can allocate memory for an array of row-pointers + + if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL) + Throw "Visualpng: Out of memory"; + + // set the individual row-pointers to point at the correct offsets + + for (i = 0; i < iHeight; i++) + ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2); + + // write out the entire image data in one call + + png_write_image (png_ptr, ppbRowPointers); + + // write the additional chunks to the PNG file (not really needed) + + png_write_end(png_ptr, info_ptr); + + // and we're done + + free (ppbRowPointers); + ppbRowPointers = NULL; + + // clean up after the write, and free any memory allocated + + png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + + // yepp, done + } + + Catch (msg) + { + png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + + if(ppbRowPointers) + free (ppbRowPointers); + + fclose(pfFile); + + return FALSE; + } + + fclose (pfFile); + + return TRUE; +} + +#ifdef PNG_NO_STDIO + +static void +png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = (png_size_t)fread(data, (png_size_t)1, length, + (FILE *)png_ptr->io_ptr); + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} + +static void +png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + + check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +static void +png_flush(png_structp png_ptr) +{ + FILE *io_ptr; + io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +} + +#endif + +//----------------- +// end of source +//----------------- diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/PngFile.h b/src/dep/src/irrlicht/libpng/contrib/visupng/PngFile.h new file mode 100644 index 0000000..f46cd59 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/PngFile.h @@ -0,0 +1,27 @@ +//------------------------------------------ +// PNGFILE.H -- Header File for pngfile.c +//------------------------------------------ + +// Copyright 2000, Willem van Schaik. For conditions of distribution and +// use, see the copyright/license/disclaimer notice in png.h + +#include +#include +#include +#include + +void PngFileInitialize (HWND hwnd) ; +BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ; +BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ; + +BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, + int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor); +BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, + int iWidth, int iHeight, png_color BkgColor); + +#if defined(PNG_NO_STDIO) +static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +static void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); +static void png_flush(png_structp png_ptr); +#endif + diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/README.txt b/src/dep/src/irrlicht/libpng/contrib/visupng/README.txt new file mode 100644 index 0000000..7150473 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/README.txt @@ -0,0 +1,58 @@ +Microsoft Developer Studio Build File, Format Version 6.00 for VisualPng +------------------------------------------------------------------------ + +Copyright 2000, Willem van Schaik. For conditions of distribution and +use, see the copyright/license/disclaimer notice in png.h + +As a PNG .dll demo VisualPng is finished. More features would only hinder +the program's objective. However, further extensions (like support for other +graphics formats) are in development. To get these, or for pre-compiled +binaries, go to "http://www.schaik.com/png/visualpng.html". + +------------------------------------------------------------------------ + +Assumes that + + libpng DLLs and LIBs are in ..\..\projects\msvc\win32\libpng + zlib DLLs and LIBs are in ..\..\projects\msvc\win32\zlib + libpng header files are in ..\..\..\libpng + zlib header files are in ..\..\..\zlib + the pngsuite images are in ..\pngsuite + +To build: + +1) On the main menu Select "Build|Set Active configuration". + Choose the configuration that corresponds to the library you want to test. + This library must have been built using the libpng MS project located in + the "..\..\mscv" subdirectory. + +2) Select "Build|Clean" + +3) Select "Build|Rebuild All" + +4) After compiling and linking VisualPng will be started to view an image + from the PngSuite directory. Press Ctrl-N (and Ctrl-V) for other images. + + +To install: + +When distributing VisualPng (or a further development) the following options +are available: + +1) Build the program with the configuration "Win32 LIB" and you only need to + include the executable from the ./lib directory in your distribution. + +2) Build the program with the configuration "Win32 DLL" and you need to put + in your distribution the executable from the ./dll directory and the dll's + libpng1.dll, zlib.dll and msvcrt.dll. These need to be in the user's PATH. + + +Willem van Schaik +Calgary, June 6th 2000 + +P.S. VisualPng was written based on preliminary work of: + + - Simon-Pierre Cadieux + - Glenn Randers-Pehrson + - Greg Roelofs + diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.c b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.c new file mode 100644 index 0000000..df3e4cd --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.c @@ -0,0 +1,961 @@ +//------------------------------------ +// VisualPng.C -- Shows a PNG image +//------------------------------------ + +// Copyright 2000, Willem van Schaik. For conditions of distribution and +// use, see the copyright/license/disclaimer notice in png.h + +// switches + +// defines + +#define PROGNAME "VisualPng" +#define LONGNAME "Win32 Viewer for PNG-files" +#define VERSION "1.0 of 2000 June 07" + +// constants + +#define MARGIN 8 + +// standard includes + +#include +#include +#include +#include + +// application includes + +#include "png.h" +#include "pngfile.h" +#include "resource.h" + +// macros + +// function prototypes + +LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); +BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; + +BOOL CenterAbout (HWND hwndChild, HWND hwndParent); + +BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, + int *pFileIndex); + +BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex, + PTSTR pstrPrevName, PTSTR pstrNextName); + +BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName, + png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels, + png_color *pBkgColor); + +BOOL DisplayImage (HWND hwnd, BYTE **ppDib, + BYTE **ppDiData, int cxWinSize, int cyWinSize, + BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, + BOOL bStretched); + +BOOL InitBitmap ( + BYTE *pDiData, int cxWinSize, int cyWinSize); + +BOOL FillBitmap ( + BYTE *pDiData, int cxWinSize, int cyWinSize, + BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, + BOOL bStretched); + +// a few global variables + +static char *szProgName = PROGNAME; +static char *szAppName = LONGNAME; +static char *szIconName = PROGNAME; +static char szCmdFileName [MAX_PATH]; + +// MAIN routine + +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, + PSTR szCmdLine, int iCmdShow) +{ + HACCEL hAccel; + HWND hwnd; + MSG msg; + WNDCLASS wndclass; + int ixBorders, iyBorders; + + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon (hInstance, szIconName) ; + wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); + wndclass.hbrBackground = NULL; // (HBRUSH) GetStockObject (GRAY_BRUSH); + wndclass.lpszMenuName = szProgName; + wndclass.lpszClassName = szProgName; + + if (!RegisterClass (&wndclass)) + { + MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"), + szProgName, MB_ICONERROR); + return 0; + } + + // if filename given on commandline, store it + if ((szCmdLine != NULL) && (*szCmdLine != '\0')) + if (szCmdLine[0] == '"') + strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2); + else + strcpy (szCmdFileName, szCmdLine); + else + strcpy (szCmdFileName, ""); + + // calculate size of window-borders + ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) + + GetSystemMetrics (SM_CXDLGFRAME)); + iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) + + GetSystemMetrics (SM_CYDLGFRAME)) + + GetSystemMetrics (SM_CYCAPTION) + + GetSystemMetrics (SM_CYMENUSIZE) + + 1; /* WvS: don't ask me why? */ + + hwnd = CreateWindow (szProgName, szAppName, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + 512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders, +// CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, hInstance, NULL); + + ShowWindow (hwnd, iCmdShow); + UpdateWindow (hwnd); + + hAccel = LoadAccelerators (hInstance, szProgName); + + while (GetMessage (&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator (hwnd, hAccel, &msg)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + return msg.wParam; +} + +LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, + LPARAM lParam) +{ + static HINSTANCE hInstance ; + static HDC hdc; + static PAINTSTRUCT ps; + static HMENU hMenu; + + static BITMAPFILEHEADER *pbmfh; + static BITMAPINFOHEADER *pbmih; + static BYTE *pbImage; + static int cxWinSize, cyWinSize; + static int cxImgSize, cyImgSize; + static int cImgChannels; + static png_color bkgColor = {127, 127, 127}; + + static BOOL bStretched = TRUE; + + static BYTE *pDib = NULL; + static BYTE *pDiData = NULL; + + static TCHAR szImgPathName [MAX_PATH]; + static TCHAR szTitleName [MAX_PATH]; + + static TCHAR *pPngFileList = NULL; + static int iPngFileCount; + static int iPngFileIndex; + + BOOL bOk; + + switch (message) + { + case WM_CREATE: + hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; + PngFileInitialize (hwnd); + + strcpy (szImgPathName, ""); + + // in case we process file given on command-line + + if (szCmdFileName[0] != '\0') + { + strcpy (szImgPathName, szCmdFileName); + + // read the other png-files in the directory for later + // next/previous commands + + BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, + &iPngFileIndex); + + // load the image from file + + if (!LoadImageFile (hwnd, szImgPathName, + &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) + return 0; + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + } + + return 0; + + case WM_SIZE: + cxWinSize = LOWORD (lParam); + cyWinSize = HIWORD (lParam); + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + + return 0; + + case WM_INITMENUPOPUP: + hMenu = GetMenu (hwnd); + + if (pbImage) + EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED); + else + EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED); + + return 0; + + case WM_COMMAND: + hMenu = GetMenu (hwnd); + + switch (LOWORD (wParam)) + { + case IDM_FILE_OPEN: + + // show the File Open dialog box + + if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName)) + return 0; + + // read the other png-files in the directory for later + // next/previous commands + + BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount, + &iPngFileIndex); + + // load the image from file + + if (!LoadImageFile (hwnd, szImgPathName, + &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) + return 0; + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + + return 0; + + case IDM_FILE_SAVE: + + // show the File Save dialog box + + if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName)) + return 0; + + // save the PNG to a disk file + + SetCursor (LoadCursor (NULL, IDC_WAIT)); + ShowCursor (TRUE); + + bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize, + bkgColor); + + ShowCursor (FALSE); + SetCursor (LoadCursor (NULL, IDC_ARROW)); + + if (!bOk) + MessageBox (hwnd, TEXT ("Error in saving the PNG image"), + szProgName, MB_ICONEXCLAMATION | MB_OK); + return 0; + + case IDM_FILE_NEXT: + + // read next entry in the directory + + if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, + NULL, szImgPathName)) + { + if (strcmp (szImgPathName, "") == 0) + return 0; + + // load the image from file + + if (!LoadImageFile (hwnd, szImgPathName, &pbImage, + &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor)) + return 0; + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + } + + return 0; + + case IDM_FILE_PREVIOUS: + + // read previous entry in the directory + + if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex, + szImgPathName, NULL)) + { + + if (strcmp (szImgPathName, "") == 0) + return 0; + + // load the image from file + + if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize, + &cyImgSize, &cImgChannels, &bkgColor)) + return 0; + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + } + + return 0; + + case IDM_FILE_EXIT: + + // more cleanup needed... + + // free image buffer + + if (pDib != NULL) + { + free (pDib); + pDib = NULL; + } + + // free file-list + + if (pPngFileList != NULL) + { + free (pPngFileList); + pPngFileList = NULL; + } + + // let's go ... + + exit (0); + + return 0; + + case IDM_OPTIONS_STRETCH: + bStretched = !bStretched; + if (bStretched) + CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED); + else + CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED); + + // invalidate the client area for later update + + InvalidateRect (hwnd, NULL, TRUE); + + // display the PNG into the DIBitmap + + DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched); + + return 0; + + case IDM_HELP_ABOUT: + DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; + return 0; + + } // end switch + + break; + + case WM_PAINT: + hdc = BeginPaint (hwnd, &ps); + + if (pDib) + SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0, + 0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS); + + EndPaint (hwnd, &ps); + return 0; + + case WM_DESTROY: + if (pbmfh) + { + free (pbmfh); + pbmfh = NULL; + } + + PostQuitMessage (0); + return 0; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + +BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG : + ShowWindow (hDlg, SW_HIDE); + CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER)); + ShowWindow (hDlg, SW_SHOW); + return TRUE ; + + case WM_COMMAND : + switch (LOWORD (wParam)) + { + case IDOK : + case IDCANCEL : + EndDialog (hDlg, 0) ; + return TRUE ; + } + break ; + } + return FALSE ; +} + +//--------------- +// CenterAbout +//--------------- + +BOOL CenterAbout (HWND hwndChild, HWND hwndParent) +{ + RECT rChild, rParent, rWorkArea; + int wChild, hChild, wParent, hParent; + int xNew, yNew; + BOOL bResult; + + // Get the Height and Width of the child window + GetWindowRect (hwndChild, &rChild); + wChild = rChild.right - rChild.left; + hChild = rChild.bottom - rChild.top; + + // Get the Height and Width of the parent window + GetWindowRect (hwndParent, &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + + // Get the limits of the 'workarea' + bResult = SystemParametersInfo( + SPI_GETWORKAREA, // system parameter to query or set + sizeof(RECT), + &rWorkArea, + 0); + if (!bResult) { + rWorkArea.left = rWorkArea.top = 0; + rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); + rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); + } + + // Calculate new X position, then adjust for workarea + xNew = rParent.left + ((wParent - wChild) /2); + if (xNew < rWorkArea.left) { + xNew = rWorkArea.left; + } else if ((xNew+wChild) > rWorkArea.right) { + xNew = rWorkArea.right - wChild; + } + + // Calculate new Y position, then adjust for workarea + yNew = rParent.top + ((hParent - hChild) /2); + if (yNew < rWorkArea.top) { + yNew = rWorkArea.top; + } else if ((yNew+hChild) > rWorkArea.bottom) { + yNew = rWorkArea.bottom - hChild; + } + + // Set it, and return + return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | + SWP_NOZORDER); +} + +//---------------- +// BuildPngList +//---------------- + +BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount, + int *pFileIndex) +{ + static TCHAR szImgPathName [MAX_PATH]; + static TCHAR szImgFileName [MAX_PATH]; + static TCHAR szImgFindName [MAX_PATH]; + + WIN32_FIND_DATA finddata; + HANDLE hFind; + + static TCHAR szTmp [MAX_PATH]; + BOOL bOk; + int i, ii; + int j, jj; + + // free previous file-list + + if (*ppFileList != NULL) + { + free (*ppFileList); + *ppFileList = NULL; + } + + // extract foldername, filename and search-name + + strcpy (szImgPathName, pstrPathName); + strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1); + + strcpy (szImgFindName, szImgPathName); + *(strrchr (szImgFindName, '\\') + 1) = '\0'; + strcat (szImgFindName, "*.png"); + + // first cycle: count number of files in directory for memory allocation + + *pFileCount = 0; + + hFind = FindFirstFile(szImgFindName, &finddata); + bOk = (hFind != (HANDLE) -1); + + while (bOk) + { + *pFileCount += 1; + bOk = FindNextFile(hFind, &finddata); + } + FindClose(hFind); + + // allocation memory for file-list + + *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH); + + // second cycle: read directory and store filenames in file-list + + hFind = FindFirstFile(szImgFindName, &finddata); + bOk = (hFind != (HANDLE) -1); + + i = 0; + ii = 0; + while (bOk) + { + strcpy (*ppFileList + ii, szImgPathName); + strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName); + + if (strcmp(pstrPathName, *ppFileList + ii) == 0) + *pFileIndex = i; + + ii += MAX_PATH; + i++; + + bOk = FindNextFile(hFind, &finddata); + } + FindClose(hFind); + + // finally we must sort the file-list + + for (i = 0; i < *pFileCount - 1; i++) + { + ii = i * MAX_PATH; + for (j = i+1; j < *pFileCount; j++) + { + jj = j * MAX_PATH; + if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0) + { + strcpy (szTmp, *ppFileList + jj); + strcpy (*ppFileList + jj, *ppFileList + ii); + strcpy (*ppFileList + ii, szTmp); + + // check if this was the current image that we moved + + if (*pFileIndex == i) + *pFileIndex = j; + else + if (*pFileIndex == j) + *pFileIndex = i; + } + } + } + + return TRUE; +} + +//---------------- +// SearchPngList +//---------------- + +BOOL SearchPngList ( + TCHAR *pFileList, int FileCount, int *pFileIndex, + PTSTR pstrPrevName, PTSTR pstrNextName) +{ + if (FileCount > 0) + { + // get previous entry + + if (pstrPrevName != NULL) + { + if (*pFileIndex > 0) + *pFileIndex -= 1; + else + *pFileIndex = FileCount - 1; + + strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH)); + } + + // get next entry + + if (pstrNextName != NULL) + { + if (*pFileIndex < FileCount - 1) + *pFileIndex += 1; + else + *pFileIndex = 0; + + strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH)); + } + + return TRUE; + } + else + { + return FALSE; + } +} + +//----------------- +// LoadImageFile +//----------------- + +BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName, + png_byte **ppbImage, int *pxImgSize, int *pyImgSize, + int *piChannels, png_color *pBkgColor) +{ + static TCHAR szTmp [MAX_PATH]; + + // if there's an existing PNG, free the memory + + if (*ppbImage) + { + free (*ppbImage); + *ppbImage = NULL; + } + + // Load the entire PNG into memory + + SetCursor (LoadCursor (NULL, IDC_WAIT)); + ShowCursor (TRUE); + + PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels, + pBkgColor); + + ShowCursor (FALSE); + SetCursor (LoadCursor (NULL, IDC_ARROW)); + + if (*ppbImage != NULL) + { + sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1); + SetWindowText (hwnd, szTmp); + } + else + { + MessageBox (hwnd, TEXT ("Error in loading the PNG image"), + szProgName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + + return TRUE; +} + +//---------------- +// DisplayImage +//---------------- + +BOOL DisplayImage (HWND hwnd, BYTE **ppDib, + BYTE **ppDiData, int cxWinSize, int cyWinSize, + BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, + BOOL bStretched) +{ + BYTE *pDib = *ppDib; + BYTE *pDiData = *ppDiData; + // BITMAPFILEHEADER *pbmfh; + BITMAPINFOHEADER *pbmih; + WORD wDIRowBytes; + png_color bkgBlack = {0, 0, 0}; + png_color bkgGray = {127, 127, 127}; + png_color bkgWhite = {255, 255, 255}; + + // allocate memory for the Device Independant bitmap + + wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2; + + if (pDib) + { + free (pDib); + pDib = NULL; + } + + if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) + + wDIRowBytes * cyWinSize))) + { + MessageBox (hwnd, TEXT ("Error in displaying the PNG image"), + szProgName, MB_ICONEXCLAMATION | MB_OK); + *ppDib = pDib = NULL; + return FALSE; + } + *ppDib = pDib; + memset (pDib, 0, sizeof(BITMAPINFOHEADER)); + + // initialize the dib-structure + + pbmih = (BITMAPINFOHEADER *) pDib; + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biWidth = cxWinSize; + pbmih->biHeight = -((long) cyWinSize); + pbmih->biPlanes = 1; + pbmih->biBitCount = 24; + pbmih->biCompression = 0; + pDiData = pDib + sizeof(BITMAPINFOHEADER); + *ppDiData = pDiData; + + // first fill bitmap with gray and image border + + InitBitmap (pDiData, cxWinSize, cyWinSize); + + // then fill bitmap with image + + if (pbImage) + { + FillBitmap ( + pDiData, cxWinSize, cyWinSize, + pbImage, cxImgSize, cyImgSize, cImgChannels, + bStretched); + } + + return TRUE; +} + +//-------------- +// InitBitmap +//-------------- + +BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize) +{ + BYTE *dst; + int x, y, col; + + // initialize the background with gray + + dst = pDiData; + for (y = 0; y < cyWinSize; y++) + { + col = 0; + for (x = 0; x < cxWinSize; x++) + { + // fill with GRAY + *dst++ = 127; + *dst++ = 127; + *dst++ = 127; + col += 3; + } + // rows start on 4 byte boundaries + while ((col % 4) != 0) + { + dst++; + col++; + } + } + + return TRUE; +} + +//-------------- +// FillBitmap +//-------------- + +BOOL FillBitmap ( + BYTE *pDiData, int cxWinSize, int cyWinSize, + BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels, + BOOL bStretched) +{ + BYTE *pStretchedImage; + BYTE *pImg; + BYTE *src, *dst; + BYTE r, g, b, a; + const int cDIChannels = 3; + WORD wImgRowBytes; + WORD wDIRowBytes; + int cxNewSize, cyNewSize; + int cxImgPos, cyImgPos; + int xImg, yImg; + int xWin, yWin; + int xOld, yOld; + int xNew, yNew; + + if (bStretched) + { + cxNewSize = cxWinSize - 2 * MARGIN; + cyNewSize = cyWinSize - 2 * MARGIN; + + // stretch the image to it's window determined size + + // the following two are the same, but the first has side-effects + // because of rounding +// if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) + if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize)) + { + cyNewSize = cxNewSize * cyImgSize / cxImgSize; + cxImgPos = MARGIN; + cyImgPos = (cyWinSize - cyNewSize) / 2; + } + else + { + cxNewSize = cyNewSize * cxImgSize / cyImgSize; + cyImgPos = MARGIN; + cxImgPos = (cxWinSize - cxNewSize) / 2; + } + + pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize); + pImg = pStretchedImage; + + for (yNew = 0; yNew < cyNewSize; yNew++) + { + yOld = yNew * cyImgSize / cyNewSize; + for (xNew = 0; xNew < cxNewSize; xNew++) + { + xOld = xNew * cxImgSize / cxNewSize; + + r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0); + g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1); + b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2); + *pImg++ = r; + *pImg++ = g; + *pImg++ = b; + if (cImgChannels == 4) + { + a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + + 3); + *pImg++ = a; + } + } + } + + // calculate row-bytes + + wImgRowBytes = cImgChannels * cxNewSize; + wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2; + + // copy image to screen + + for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++) + { + if (yWin >= cyWinSize - cyImgPos) + break; + src = pStretchedImage + yImg * wImgRowBytes; + dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels; + + for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++) + { + if (xWin >= cxWinSize - cxImgPos) + break; + r = *src++; + g = *src++; + b = *src++; + *dst++ = b; /* note the reverse order */ + *dst++ = g; + *dst++ = r; + if (cImgChannels == 4) + { + a = *src++; + } + } + } + + // free memory + + if (pStretchedImage != NULL) + { + free (pStretchedImage); + pStretchedImage = NULL; + } + + } + + // process the image not-stretched + + else + { + // calculate the central position + + cxImgPos = (cxWinSize - cxImgSize) / 2; + cyImgPos = (cyWinSize - cyImgSize) / 2; + + // check for image larger than window + + if (cxImgPos < MARGIN) + cxImgPos = MARGIN; + if (cyImgPos < MARGIN) + cyImgPos = MARGIN; + + // calculate both row-bytes + + wImgRowBytes = cImgChannels * cxImgSize; + wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2; + + // copy image to screen + + for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++) + { + if (yWin >= cyWinSize - MARGIN) + break; + src = pbImage + yImg * wImgRowBytes; + dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels; + + for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++) + { + if (xWin >= cxWinSize - MARGIN) + break; + r = *src++; + g = *src++; + b = *src++; + *dst++ = b; /* note the reverse order */ + *dst++ = g; + *dst++ = r; + if (cImgChannels == 4) + { + a = *src++; + } + } + } + } + + return TRUE; +} + +//----------------- +// end of source +//----------------- diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsp b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsp new file mode 100644 index 0000000..53ef5a2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsp @@ -0,0 +1,147 @@ +# Microsoft Developer Studio Project File - Name="VisualPng" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=VisualPng - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "VisualPng.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "VisualPng.mak" CFG="VisualPng - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "VisualPng - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "VisualPng - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "VisualPng - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 ..\..\projects\visualc6\Win32_LIB_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Release\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# Begin Special Build Tool +OutDir=.\Release +SOURCE="$(InputPath)" +PostBuild_Cmds=$(outdir)\VisualPng.exe ..\..\contrib\pngsuite\basn6a16.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "VisualPng - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\..\projects\visualc6\Win32_LIB_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Release\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept +# Begin Special Build Tool +OutDir=.\Debug +SOURCE="$(InputPath)" +PostBuild_Cmds=$(outdir)\VisualPng.exe ..\..\contrib\pngsuite\basn6a16.png +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "VisualPng - Win32 Release" +# Name "VisualPng - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\PngFile.c +# End Source File +# Begin Source File + +SOURCE=.\VisualPng.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\cexcept.h +# End Source File +# Begin Source File + +SOURCE=.\PngFile.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\VisualPng.ico +# End Source File +# Begin Source File + +SOURCE=.\VisualPng.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsw b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsw new file mode 100644 index 0000000..a30e1cc --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "VisualPng"=.\VisualPng.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.ico b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.ico new file mode 100644 index 0000000000000000000000000000000000000000..68aa3719fb523eccd4c4a706e4198ca1be2b4c62 GIT binary patch literal 766 zcmb_ayGjE=6ul!BJ4Il&5f%%#i;YeE0sqBX?6q(TQ7j^}Bh9<%xts4i6 zkcy&!=Yp>fdCw6P!YMX?g~S3@L(=jS0+)s|NiKlEgL>VOVf)WTfR)85V$RN>JwSV-vWY^X3AQl6o~-A`A21P`H#(L`ua zC6p2|SPTx|B;lEdR<4J97z(@|!YJx7#d!1r3hTe|MU4YoP< Ob-aH+fF44>&V2wPTAUpK literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.png b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.png new file mode 100644 index 0000000000000000000000000000000000000000..c6aa80a9bfa275137e429498bc785cb2dbcdb382 GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;SkfJR9T^xl_H+M9WCils0(?ST zf%J9`j>RRx2|yNONswPKgTu2MX+Tbfr;B5V#O34!2UcDl9v_~y3Xga?K0NvO|~WI+Z?ismL3#z>)ClO+n69&&Pt@)((moHOva6OfZ2FlX_Z0}8s!jvZ1^ zUz2uRL2<>QLkbEXTG%~o9y17?WOH!($Y?g1Vbg3Ozf`fCd_X%HJYD@<);T3K0RUGo BL5BbU literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.rc b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.rc new file mode 100644 index 0000000..6e0623a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/VisualPng.rc @@ -0,0 +1,152 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +VISUALPNG MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open Image...\tCtrl+O", IDM_FILE_OPEN + MENUITEM "Save &As...", IDM_FILE_SAVE + MENUITEM SEPARATOR + MENUITEM "&Next Image\tCtrl+N", IDM_FILE_NEXT + MENUITEM "Pre&vious Image\tCtrl+V", IDM_FILE_PREVIOUS + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+X", IDM_FILE_EXIT + END + POPUP "&Options" + BEGIN + MENUITEM "&Stretch", IDM_OPTIONS_STRETCH, CHECKED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", IDM_HELP_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +VISUALPNG ACCELERATORS DISCARDABLE +BEGIN + "N", IDM_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT + "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT + "V", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT + "X", IDM_FILE_EXIT, VIRTKEY, ALT, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +VISUALPNG ICON DISCARDABLE "VisualPng.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +ABOUTBOX DIALOG DISCARDABLE 0, 0, 186, 94 +STYLE DS_MODALFRAME | WS_POPUP +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,68,67,50,14 + CTEXT "VisualPng 1.0 - June 2000",IDC_STATIC,49,14,88,8 + LTEXT "a PNG image viewer",IDC_STATIC,60,30,66,8 + LTEXT "(c) Willem van Schaik, 2000",IDC_STATIC,48,52,90,8 + LTEXT "to demonstrate the use of libpng in Visual C", + IDC_STATIC,25,38,136,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "ABOUTBOX", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 87 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/cexcept.h b/src/dep/src/irrlicht/libpng/contrib/visupng/cexcept.h new file mode 100644 index 0000000..a1a4f83 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/cexcept.h @@ -0,0 +1,243 @@ +/*=== +cexcept.h 2.0.0 (2001-Jul-12-Thu) +Adam M. Costello + +An interface for exception-handling in ANSI C (C89 and subsequent ISO +standards), developed jointly with Cosmin Truta . + + Copyright (c) 2001 Adam M. Costello and Cosmin Truta. Everyone + is hereby granted permission to do whatever they like with this + file, provided that if they modify it they take reasonable steps to + avoid confusing or misleading people about the authors, version, + and terms of use of the derived file. The copyright holders make + no guarantees regarding this file, and are not responsible for any + damage resulting from its use. + +Only user-defined exceptions are supported, not "real" exceptions like +division by zero or memory segmentation violations. + +If this interface is used by multiple .c files, they shouldn't include +this header file directly. Instead, create a wrapper header file that +includes this header file and then invokes the define_exception_type +macro (see below), and let your .c files include that header file. + +The interface consists of one type, one well-known name, and six macros. + + +define_exception_type(type_name); + + This macro is used like an external declaration. It specifies + the type of object that gets copied from the exception thrower to + the exception catcher. The type_name can be any type that can be + assigned to, that is, a non-constant arithmetic type, struct, union, + or pointer. Examples: + + define_exception_type(int); + + enum exception { out_of_memory, bad_arguments, disk_full }; + define_exception_type(enum exception); + + struct exception { int code; const char *msg; }; + define_exception_type(struct exception); + + Because throwing an exception causes the object to be copied (not + just once, but twice), programmers may wish to consider size when + choosing the exception type. + + +struct exception_context; + + This type may be used after the define_exception_type() macro has + been invoked. A struct exception_context must be known to both + the thrower and the catcher. It is expected that there be one + context for each thread that uses exceptions. It would certainly + be dangerous for multiple threads to access the same context. + One thread can use multiple contexts, but that is likely to be + confusing and not typically useful. The application can allocate + this structure in any way it pleases--automatic, static, or dynamic. + The application programmer should pretend not to know the structure + members, which are subject to change. + + +struct exception_context *the_exception_context; + + The Try/Catch and Throw statements (described below) implicitly + refer to a context, using the name the_exception_context. It is + the application's responsibility to make sure that this name yields + the address of a mutable (non-constant) struct exception_context + wherever those statements are used. Subject to that constraint, the + application may declare a variable of this name anywhere it likes + (inside a function, in a parameter list, or externally), and may + use whatever storage class specifiers (static, extern, etc) or type + qualifiers (const, volatile, etc) it likes. Examples: + + static struct exception_context + * const the_exception_context = &foo; + + { struct exception_context *the_exception_context = bar; ... } + + int blah(struct exception_context *the_exception_context, ...); + + extern struct exception_context the_exception_context[1]; + + The last example illustrates a trick that avoids creating a pointer + object separate from the structure object. + + The name could even be a macro, for example: + + struct exception_context ec_array[numthreads]; + #define the_exception_context (ec_array + thread_id) + + Be aware that the_exception_context is used several times by the + Try/Catch/Throw macros, so it shouldn't be expensive or have side + effects. The expansion must be a drop-in replacement for an + identifier, so it's safest to put parentheses around it. + + +void init_exception_context(struct exception_context *ec); + + For context structures allocated statically (by an external + definition or using the "static" keyword), the implicit + initialization to all zeros is sufficient, but contexts allocated + by other means must be initialized using this macro before they + are used by a Try/Catch statement. It does no harm to initialize + a context more than once (by using this macro on a statically + allocated context, or using this macro twice on the same context), + but a context must not be re-initialized after it has been used by a + Try/Catch statement. + + +Try statement +Catch (expression) statement + + The Try/Catch/Throw macros are capitalized in order to avoid + confusion with the C++ keywords, which have subtly different + semantics. + + A Try/Catch statement has a syntax similar to an if/else statement, + except that the parenthesized expression goes after the second + keyword rather than the first. As with if/else, there are two + clauses, each of which may be a simple statement ending with a + semicolon or a brace-enclosed compound statement. But whereas + the else clause is optional, the Catch clause is required. The + expression must be a modifiable lvalue (something capable of being + assigned to) of the same type (disregarding type qualifiers) that + was passed to define_exception_type(). + + If a Throw that uses the same exception context as the Try/Catch is + executed within the Try clause (typically within a function called + by the Try clause), and the exception is not caught by a nested + Try/Catch statement, then a copy of the exception will be assigned + to the expression, and control will jump to the Catch clause. If no + such Throw is executed, then the assignment is not performed, and + the Catch clause is not executed. + + The expression is not evaluated unless and until the exception is + caught, which is significant if it has side effects, for example: + + Try foo(); + Catch (p[++i].e) { ... } + + IMPORTANT: Jumping into or out of a Try clause (for example via + return, break, continue, goto, longjmp) is forbidden--the compiler + will not complain, but bad things will happen at run-time. Jumping + into or out of a Catch clause is okay, and so is jumping around + inside a Try clause. In many cases where one is tempted to return + from a Try clause, it will suffice to use Throw, and then return + from the Catch clause. Another option is to set a flag variable and + use goto to jump to the end of the Try clause, then check the flag + after the Try/Catch statement. + + IMPORTANT: The values of any non-volatile automatic variables + changed within the Try clause are undefined after an exception is + caught. Therefore, variables modified inside the Try block whose + values are needed later outside the Try block must either use static + storage or be declared with the "volatile" type qualifier. + + +Throw expression; + + A Throw statement is very much like a return statement, except that + the expression is required. Whereas return jumps back to the place + where the current function was called, Throw jumps back to the Catch + clause of the innermost enclosing Try clause. The expression must + be compatible with the type passed to define_exception_type(). The + exception must be caught, otherwise the program may crash. + + Slight limitation: If the expression is a comma-expression it must + be enclosed in parentheses. + + +Try statement +Catch_anonymous statement + + When the value of the exception is not needed, a Try/Catch statement + can use Catch_anonymous instead of Catch (expression). + + +Everything below this point is for the benefit of the compiler. The +application programmer should pretend not to know any of it, because it +is subject to change. + +===*/ + + +#ifndef CEXCEPT_H +#define CEXCEPT_H + + +#include + +#define define_exception_type(etype) \ +struct exception_context { \ + jmp_buf *penv; \ + int caught; \ + volatile struct { etype etmp; } v; \ +} + +/* etmp must be volatile because the application might use automatic */ +/* storage for the_exception_context, and etmp is modified between */ +/* the calls to setjmp() and longjmp(). A wrapper struct is used to */ +/* avoid warnings about a duplicate volatile qualifier in case etype */ +/* already includes it. */ + +#define init_exception_context(ec) ((void)((ec)->penv = 0)) + +#define Try \ + { \ + jmp_buf *exception__prev, exception__env; \ + exception__prev = the_exception_context->penv; \ + the_exception_context->penv = &exception__env; \ + if (setjmp(exception__env) == 0) { \ + if (&exception__prev) + +#define exception__catch(action) \ + else { } \ + the_exception_context->caught = 0; \ + } \ + else { \ + the_exception_context->caught = 1; \ + } \ + the_exception_context->penv = exception__prev; \ + } \ + if (!the_exception_context->caught || action) { } \ + else + +#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0)) +#define Catch_anonymous exception__catch(0) + +/* Try ends with if(), and Catch begins and ends with else. This */ +/* ensures that the Try/Catch syntax is really the same as the */ +/* if/else syntax. */ +/* */ +/* We use &exception__prev instead of 1 to appease compilers that */ +/* warn about constant expressions inside if(). Most compilers */ +/* should still recognize that &exception__prev is never zero and */ +/* avoid generating test code. */ + +#define Throw \ + for (;; longjmp(*the_exception_context->penv, 1)) \ + the_exception_context->v.etmp = + + +#endif /* CEXCEPT_H */ diff --git a/src/dep/src/irrlicht/libpng/contrib/visupng/resource.h b/src/dep/src/irrlicht/libpng/contrib/visupng/resource.h new file mode 100644 index 0000000..e222d35 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/contrib/visupng/resource.h @@ -0,0 +1,23 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by VisualPng.rc +// +#define IDM_FILE_OPEN 40001 +#define IDM_FILE_SAVE 40002 +#define IDM_FILE_NEXT 40003 +#define IDM_FILE_PREVIOUS 40004 +#define IDM_FILE_EXIT 40005 +#define IDM_OPTIONS_BACKGROUND 40006 +#define IDM_OPTIONS_STRETCH 40007 +#define IDM_HELP_ABOUT 40008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40009 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/dep/src/irrlicht/libpng/example.c b/src/dep/src/irrlicht/libpng/example.c new file mode 100644 index 0000000..2db293a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/example.c @@ -0,0 +1,814 @@ + +#if 0 /* in case someone actually tries to compile this */ + +/* example.c - an example of using libpng + * Last changed in libpng 1.2.1 December 7, 2001. + * This file has been placed in the public domain by the authors. + * Maintained 1998-2007 Glenn Randers-Pehrson + * Maintained 1996, 1997 Andreas Dilger) + * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* This is an example of how to use libpng to read and write PNG files. + * The file libpng.txt is much more verbose then this. If you have not + * read it, do so first. This was designed to be a starting point of an + * implementation. This is not officially part of libpng, is hereby placed + * in the public domain, and therefore does not require a copyright notice. + * + * This file does not currently compile, because it is missing certain + * parts, like allocating memory to hold an image. You will have to + * supply these parts to get it to compile. For an example of a minimal + * working PNG reader/writer, see pngtest.c, included in this distribution; + * see also the programs in the contrib directory. + */ + +#include "png.h" + + /* The png_jmpbuf() macro, used in error handling, became available in + * libpng version 1.0.6. If you want to be able to run your code with older + * versions of libpng, you must define the macro yourself (but only if it + * is not already defined by libpng!). + */ + +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp() + * returns zero if the image is a PNG and nonzero if it isn't a PNG. + * + * The function check_if_png() shown here, but not used, returns nonzero (true) + * if the file can be opened and is a PNG, 0 (false) otherwise. + * + * If this call is successful, and you are going to keep the file open, + * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once + * you have created the png_ptr, so that libpng knows your application + * has read that many bytes from the start of the file. Make sure you + * don't call png_set_sig_bytes() with more than 8 bytes read or give it + * an incorrect number of bytes read, or you will either have read too + * many bytes (your fault), or you are telling libpng to read the wrong + * number of magic bytes (also your fault). + * + * Many applications already read the first 2 or 4 bytes from the start + * of the image to determine the file type, so it would be easiest just + * to pass the bytes to png_sig_cmp() or even skip that if you know + * you have a PNG file, and call png_set_sig_bytes(). + */ +#define PNG_BYTES_TO_CHECK 4 +int check_if_png(char *file_name, FILE **fp) +{ + char buf[PNG_BYTES_TO_CHECK]; + + /* Open the prospective PNG file. */ + if ((*fp = fopen(file_name, "rb")) == NULL) + return 0; + + /* Read in some of the signature bytes */ + if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK) + return 0; + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + Return nonzero (true) if they match */ + + return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)); +} + +/* Read a PNG file. You may want to return an error code if the read + * fails (depending upon the failure). There are two "prototypes" given + * here - one where we are given the filename, and we need to open the + * file, and the other where we are given an open file (possibly with + * some or all of the magic bytes read - see comments above). + */ +#ifdef open_file /* prototype 1 */ +void read_png(char *file_name) /* We need to open the file */ +{ + png_structp png_ptr; + png_infop info_ptr; + unsigned int sig_read = 0; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + FILE *fp; + + if ((fp = fopen(file_name, "rb")) == NULL) + return (ERROR); +#else no_open_file /* prototype 2 */ +void read_png(FILE *fp, unsigned int sig_read) /* file is already open */ +{ + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; +#endif no_open_file /* only use one prototype! */ + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also supply the + * the compiler header file version, so that we know if the application + * was compiled with a compatible version of the library. REQUIRED + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (png_ptr == NULL) + { + fclose(fp); + return (ERROR); + } + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); + return (ERROR); + } + + /* Set error handling if you are using the setjmp/longjmp method (this is + * the normal method of doing things with libpng). REQUIRED unless you + * set up your own error handlers in the png_create_read_struct() earlier. + */ + + if (setjmp(png_jmpbuf(png_ptr))) + { + /* Free all of the memory associated with the png_ptr and info_ptr */ + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + fclose(fp); + /* If we get here, we had a problem reading the file */ + return (ERROR); + } + + /* One of the following I/O initialization methods is REQUIRED */ +#ifdef streams /* PNG file I/O method 1 */ + /* Set up the input control if you are using standard C streams */ + png_init_io(png_ptr, fp); + +#else no_streams /* PNG file I/O method 2 */ + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call: + */ + png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); + /* where user_io_ptr is a structure you want available to the callbacks */ +#endif no_streams /* Use only one I/O method! */ + + /* If we have already read some of the signature */ + png_set_sig_bytes(png_ptr, sig_read); + +#ifdef hilevel + /* + * If you have enough memory to read in the entire image at once, + * and you need to specify only transforms that can be controlled + * with one of the PNG_TRANSFORM_* bits (this presently excludes + * dithering, filling, setting background, and doing gamma + * adjustment), then you can read the entire image (including + * pixels) into the info structure with this call: + */ + png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); +#else + /* OK, you're doing it the hard way, with the lower-level functions */ + + /* The call to png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). REQUIRED + */ + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_type, int_p_NULL, int_p_NULL); + +/* Set up the data transformations you want. Note that these are all + * optional. Only call them if you want/need them. Many of the + * transformations only work on specific types of images, and many + * are mutually exclusive. + */ + + /* tell libpng to strip 16 bit/color files down to 8 bits/color */ + png_set_strip_16(png_ptr); + + /* Strip alpha bytes from the input data without combining with the + * background (not recommended). + */ + png_set_strip_alpha(png_ptr); + + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). */ + png_set_packswap(png_ptr); + + /* Expand paletted colors into true RGB triplets */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_gray_1_2_4_to_8(png_ptr); + + /* Expand paletted or RGB images with transparency to full alpha channels + * so the data will be available as RGBA quartets. + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + + /* Set the background color to draw transparent and alpha images over. + * It is possible to set the red, green, and blue components directly + * for paletted images instead of supplying a palette index. Note that + * even if the PNG file supplies a background, you are not required to + * use it - you should use the (solid) application background if it has one. + */ + + png_color_16 my_background, *image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + + /* Some suggestions as to how to get a screen gamma value */ + + /* Note that screen gamma is the display_exponent, which includes + * the CRT_exponent and any correction for viewing conditions */ + if (/* We have a user-defined screen gamma value */) + { + screen_gamma = user-defined screen_gamma; + } + /* This is one way that applications share the same screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) + { + screen_gamma = atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly + lit room */ + screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ + } + + /* Tell libpng to handle the gamma conversion for you. The final call + * is a good guess for PC generated images, but it should be configurable + * by the user at run time by the user. It is strongly suggested that + * your application support gamma correction. + */ + + int intent; + + if (png_get_sRGB(png_ptr, info_ptr, &intent)) + png_set_gamma(png_ptr, screen_gamma, 0.45455); + else + { + double image_gamma; + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) + png_set_gamma(png_ptr, screen_gamma, image_gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + } + + /* Dither RGB files down to 8 bit palette or reduce palettes + * to the number of colors available on your screen. + */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + int num_palette; + png_colorp palette; + + /* This reduces the image to the application supplied palette */ + if (/* we have our own palette */) + { + /* An array of colors to which the image should be dithered */ + png_color std_color_cube[MAX_SCREEN_COLORS]; + + png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, + MAX_SCREEN_COLORS, png_uint_16p_NULL, 0); + } + /* This reduces the image to the palette supplied in the file */ + else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, &histogram); + + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 0); + } + } + + /* invert monochrome files to have 0 as white and 1 as black */ + png_set_invert_mono(png_ptr); + + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) + { + png_color_8p sig_bit; + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, sig_bit); + } + + /* flip the RGB pixels to BGR (or RGBA to BGRA) */ + if (color_type & PNG_COLOR_MASK_COLOR) + png_set_bgr(png_ptr); + + /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ + png_set_swap_alpha(png_ptr); + + /* swap bytes of 16 bit files to least significant byte first */ + png_set_swap(png_ptr); + + /* Add filler (or alpha) byte (before/after each RGB triplet) */ + png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); + + /* Turn on interlace handling. REQUIRED if you are not using + * png_read_image(). To see how to handle interlacing passes, + * see the png_read_row() method below: + */ + number_passes = png_set_interlace_handling(png_ptr); + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (ie you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* Allocate the memory to hold the image using the fields of info_ptr. */ + + /* The easiest way to read the image: */ + png_bytep row_pointers[height]; + + for (row = 0; row < height; row++) + { + row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, + info_ptr)); + } + + /* Now it's time to read the image. One of these methods is REQUIRED */ +#ifdef entire /* Read the entire image in one go */ + png_read_image(png_ptr, row_pointers); + +#else no_entire /* Read the image one or more scanlines at a time */ + /* The other way to read images - deal with interlacing: */ + + for (pass = 0; pass < number_passes; pass++) + { +#ifdef single /* Read the image a single row at a time */ + for (y = 0; y < height; y++) + { + png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1); + } + +#else no_single /* Read the image several rows at a time */ + for (y = 0; y < height; y += number_of_rows) + { +#ifdef sparkle /* Read the image using the "sparkle" effect. */ + png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, + number_of_rows); +#else no_sparkle /* Read the image using the "rectangle" effect */ + png_read_rows(png_ptr, png_bytepp_NULL, &row_pointers[y], + number_of_rows); +#endif no_sparkle /* use only one of these two methods */ + } + + /* if you want to display the image after every pass, do + so here */ +#endif no_single /* use only one of these two methods */ + } +#endif no_entire /* use only one of these two methods */ + + /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); +#endif hilevel + + /* At this point you have read the entire image */ + + /* clean up after the read, and free any memory allocated - REQUIRED */ + png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); + + /* close the file */ + fclose(fp); + + /* that's it */ + return (OK); +} + +/* progressively read a file */ + +int +initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) +{ + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible in case we are using dynamically + * linked libraries. + */ + *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (*png_ptr == NULL) + { + *info_ptr = NULL; + return (ERROR); + } + + *info_ptr = png_create_info_struct(png_ptr); + + if (*info_ptr == NULL) + { + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf((*png_ptr)))) + { + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + /* This one's new. You will need to provide all three + * function callbacks, even if you aren't using them all. + * If you aren't using all functions, you can specify NULL + * parameters. Even when all three functions are NULL, + * you need to call png_set_progressive_read_fn(). + * These functions shouldn't be dependent on global or + * static variables if you are decoding several images + * simultaneously. You should store stream specific data + * in a separate struct, given as the second parameter, + * and retrieve the pointer from inside the callbacks using + * the function png_get_progressive_ptr(png_ptr). + */ + png_set_progressive_read_fn(*png_ptr, (void *)stream_data, + info_callback, row_callback, end_callback); + + return (OK); +} + +int +process_data(png_structp *png_ptr, png_infop *info_ptr, + png_bytep buffer, png_uint_32 length) +{ + if (setjmp(png_jmpbuf((*png_ptr)))) + { + /* Free the png_ptr and info_ptr memory on error */ + png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); + return (ERROR); + } + + /* This one's new also. Simply give it chunks of data as + * they arrive from the data stream (in order, of course). + * On Segmented machines, don't give it any more than 64K. + * The library seems to run fine with sizes of 4K, although + * you can give it much less if necessary (I assume you can + * give it chunks of 1 byte, but I haven't tried with less + * than 256 bytes yet). When this function returns, you may + * want to display any rows that were generated in the row + * callback, if you aren't already displaying them there. + */ + png_process_data(*png_ptr, *info_ptr, buffer, length); + return (OK); +} + +info_callback(png_structp png_ptr, png_infop info) +{ +/* do any setup here, including setting any of the transformations + * mentioned in the Reading PNG files section. For now, you _must_ + * call either png_start_read_image() or png_read_update_info() + * after all the transformations are set (even if you don't set + * any). You may start getting rows before png_process_data() + * returns, so this is your last chance to prepare for that. + */ +} + +row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) +{ +/* + * This function is called for every row in the image. If the + * image is interlaced, and you turned on the interlace handler, + * this function will be called for every row in every pass. + * + * In this function you will receive a pointer to new row data from + * libpng called new_row that is to replace a corresponding row (of + * the same data format) in a buffer allocated by your application. + * + * The new row data pointer new_row may be NULL, indicating there is + * no new data to be replaced (in cases of interlace loading). + * + * If new_row is not NULL then you need to call + * png_progressive_combine_row() to replace the corresponding row as + * shown below: + */ + /* Check if row_num is in bounds. */ + if((row_num >= 0) && (row_num < height)) + { + /* Get pointer to corresponding row in our + * PNG read buffer. + */ + png_bytep old_row = ((png_bytep *)our_data)[row_num]; + + /* If both rows are allocated then copy the new row + * data to the corresponding row data. + */ + if((old_row != NULL) && (new_row != NULL)) + png_progressive_combine_row(png_ptr, old_row, new_row); + } +/* + * The rows and passes are called in order, so you don't really + * need the row_num and pass, but I'm supplying them because it + * may make your life easier. + * + * For the non-NULL rows of interlaced images, you must call + * png_progressive_combine_row() passing in the new row and the + * old row, as demonstrated above. You can call this function for + * NULL rows (it will just return) and for non-interlaced images + * (it just does the png_memcpy for you) if it will make the code + * easier. Thus, you can just do this for all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, new_row); + +/* where old_row is what was displayed for previous rows. Note + * that the first pass (pass == 0 really) will completely cover + * the old row, so the rows do not have to be initialized. After + * the first pass (and only for interlaced images), you will have + * to pass the current row as new_row, and the function will combine + * the old row and the new row. + */ +} + +end_callback(png_structp png_ptr, png_infop info) +{ +/* this function is called when the whole image has been read, + * including any chunks after the image (up to and including + * the IEND). You will usually have the same info chunk as you + * had in the header, although some data may have been added + * to the comments and time fields. + * + * Most people won't do much here, perhaps setting a flag that + * marks the image as finished. + */ +} + +/* write a png file */ +void write_png(char *file_name /* , ... other image information ... */) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_colorp palette; + + /* open the file */ + fp = fopen(file_name, "wb"); + if (fp == NULL) + return (ERROR); + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. + */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (png_ptr == NULL) + { + fclose(fp); + return (ERROR); + } + + /* Allocate/initialize the image information data. REQUIRED */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_write_struct(&png_ptr, png_infopp_NULL); + return (ERROR); + } + + /* Set error handling. REQUIRED if you aren't supplying your own + * error handling functions in the png_create_write_struct() call. + */ + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem reading the file */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return (ERROR); + } + + /* One of the following I/O initialization functions is REQUIRED */ +#ifdef streams /* I/O initialization method 1 */ + /* set up the output control if you are using standard C streams */ + png_init_io(png_ptr, fp); +#else no_streams /* I/O initialization method 2 */ + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call */ + png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn, + user_IO_flush_function); + /* where user_io_ptr is a structure you want available to the callbacks */ +#endif no_streams /* only use one initialization method */ + +#ifdef hilevel + /* This is the easy way. Use it if you already have all the + * image info living info in the structure. You could "|" many + * PNG_TRANSFORM flags into the png_transforms integer here. + */ + png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); +#else + /* This is the hard way */ + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED + */ + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???, + PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* set the palette if there is one. REQUIRED for indexed-color images */ + palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH + * png_sizeof (png_color)); + /* ... set palette colors ... */ + png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); + /* You must not free palette here, because png_set_PLTE only makes a link to + the palette that you malloced. Wait until you are about to destroy + the png structure. */ + + /* optional significant bit chunk */ + /* if we are dealing with a grayscale image then */ + sig_bit.gray = true_bit_depth; + /* otherwise, if we are dealing with a color image then */ + sig_bit.red = true_red_bit_depth; + sig_bit.green = true_green_bit_depth; + sig_bit.blue = true_blue_bit_depth; + /* if the image has an alpha channel then */ + sig_bit.alpha = true_alpha_bit_depth; + png_set_sBIT(png_ptr, info_ptr, sig_bit); + + + /* Optional gamma chunk is strongly suggested if you have any guess + * as to the correct gamma of the image. + */ + png_set_gAMA(png_ptr, info_ptr, gamma); + + /* Optionally write comments into the image */ + text_ptr[0].key = "Title"; + text_ptr[0].text = "Mona Lisa"; + text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[1].key = "Author"; + text_ptr[1].text = "Leonardo DaVinci"; + text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[2].key = "Description"; + text_ptr[2].text = ""; + text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; +#ifdef PNG_iTXt_SUPPORTED + text_ptr[0].lang = NULL; + text_ptr[1].lang = NULL; + text_ptr[2].lang = NULL; +#endif + png_set_text(png_ptr, info_ptr, text_ptr, 3); + + /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ + /* note that if sRGB is present the gAMA and cHRM chunks must be ignored + * on read and must be written in accordance with the sRGB profile */ + + /* Write the file header information. REQUIRED */ + png_write_info(png_ptr, info_ptr); + + /* If you want, you can write the info in two steps, in case you need to + * write your private chunk ahead of PLTE: + * + * png_write_info_before_PLTE(write_ptr, write_info_ptr); + * write_my_chunk(); + * png_write_info(png_ptr, info_ptr); + * + * However, given the level of known- and unknown-chunk support in 1.1.0 + * and up, this should no longer be necessary. + */ + + /* Once we write out the header, the compression type on the text + * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or + * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again + * at the end. + */ + + /* set up the transformations you want. Note that these are + * all optional. Only call them if you want them. + */ + + /* invert monochrome pixels */ + png_set_invert_mono(png_ptr); + + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + png_set_shift(png_ptr, &sig_bit); + + /* pack pixels into bytes */ + png_set_packing(png_ptr); + + /* swap location of alpha bytes from ARGB to RGBA */ + png_set_swap_alpha(png_ptr); + + /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into + * RGB (4 channels -> 3 channels). The second parameter is not used. + */ + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + + /* flip BGR pixels to RGB */ + png_set_bgr(png_ptr); + + /* swap bytes of 16-bit files to most significant byte first */ + png_set_swap(png_ptr); + + /* swap bits of 1, 2, 4 bit packed pixel formats */ + png_set_packswap(png_ptr); + + /* turn on interlace handling if you are not using png_write_image() */ + if (interlacing) + number_passes = png_set_interlace_handling(png_ptr); + else + number_passes = 1; + + /* The easiest way to write the image (you may have a different memory + * layout, however, so choose what fits your needs best). You need to + * use the first method if you aren't handling interlacing yourself. + */ + png_uint_32 k, height, width; + png_byte image[height][width*bytes_per_pixel]; + png_bytep row_pointers[height]; + + if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) + png_error (png_ptr, "Image is too tall to process in memory"); + + for (k = 0; k < height; k++) + row_pointers[k] = image + k*width*bytes_per_pixel; + + /* One of the following output methods is REQUIRED */ +#ifdef entire /* write out the entire image data in one call */ + png_write_image(png_ptr, row_pointers); + + /* the other way to write the image - deal with interlacing */ + +#else no_entire /* write out the image data by one or more scanlines */ + /* The number of passes is either 1 for non-interlaced images, + * or 7 for interlaced images. + */ + for (pass = 0; pass < number_passes; pass++) + { + /* Write a few rows at a time. */ + png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows); + + /* If you are only writing one row at a time, this works */ + for (y = 0; y < height; y++) + { + png_write_rows(png_ptr, &row_pointers[y], 1); + } + } +#endif no_entire /* use only one output method */ + + /* You can write optional chunks like tEXt, zTXt, and tIME at the end + * as well. Shouldn't be necessary in 1.1.0 and up as all the public + * chunks are supported and you can use png_set_unknown_chunks() to + * register unknown chunks into the info structure to be written out. + */ + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); +#endif hilevel + + /* If you png_malloced a palette, free it here (don't free info_ptr->palette, + as recommended in versions 1.0.5m and earlier of this example; if + libpng mallocs info_ptr->palette, libpng will free it). If you + allocated it with malloc() instead of png_malloc(), use free() instead + of png_free(). */ + png_free(png_ptr, palette); + palette=NULL; + + /* Similarly, if you png_malloced any data that you passed in with + png_set_something(), such as a hist or trans array, free it here, + when you can be sure that libpng is through with it. */ + png_free(png_ptr, trans); + trans=NULL; + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + /* close the file */ + fclose(fp); + + /* that's it */ + return (OK); +} + +#endif /* if 0 */ diff --git a/src/dep/src/irrlicht/libpng/libpng-1.2.18.txt b/src/dep/src/irrlicht/libpng/libpng-1.2.18.txt new file mode 100644 index 0000000..04c5e88 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/libpng-1.2.18.txt @@ -0,0 +1,2976 @@ +libpng.txt - A description on how to use and modify libpng + + libpng version 1.2.18 - May 15, 2007 + Updated and distributed by Glenn Randers-Pehrson + + Copyright (c) 1998-2007 Glenn Randers-Pehrson + For conditions of distribution and use, see copyright + notice in png.h. + + based on: + + libpng 1.0 beta 6 version 0.96 May 28, 1997 + Updated and distributed by Andreas Dilger + Copyright (c) 1996, 1997 Andreas Dilger + + libpng 1.0 beta 2 - version 0.88 January 26, 1996 + For conditions of distribution and use, see copyright + notice in png.h. Copyright (c) 1995, 1996 Guy Eric + Schalnat, Group 42, Inc. + + Updated/rewritten per request in the libpng FAQ + Copyright (c) 1995, 1996 Frank J. T. Wojcik + December 18, 1995 & January 20, 1996 + +I. Introduction + +This file describes how to use and modify the PNG reference library +(known as libpng) for your own use. There are five sections to this +file: introduction, structures, reading, writing, and modification and +configuration notes for various special platforms. In addition to this +file, example.c is a good starting point for using the library, as +it is heavily commented and should include everything most people +will need. We assume that libpng is already installed; see the +INSTALL file for instructions on how to install libpng. + +For examples of libpng usage, see the files "example.c", "pngtest.c", +and the files in the "contrib" directory, all of which are included in the +libpng distribution. + +Libpng was written as a companion to the PNG specification, as a way +of reducing the amount of time and effort it takes to support the PNG +file format in application programs. + +The PNG specification (second edition), November 2003, is available as +a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at + + +The PNG-1.0 specification is available +as RFC 2083 and as a +W3C Recommendation . Some +additional chunks are described in the special-purpose public chunks +documents at . + +Other information +about PNG, and the latest version of libpng, can be found at the PNG home +page, . + +Most users will not have to modify the library significantly; advanced +users may want to modify it more. All attempts were made to make it as +complete as possible, while keeping the code easy to understand. +Currently, this library only supports C. Support for other languages +is being considered. + +Libpng has been designed to handle multiple sessions at one time, +to be easily modifiable, to be portable to the vast majority of +machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy +to use. The ultimate goal of libpng is to promote the acceptance of +the PNG file format in whatever way possible. While there is still +work to be done (see the TODO file), libpng should cover the +majority of the needs of its users. + +Libpng uses zlib for its compression and decompression of PNG files. +Further information about zlib, and the latest version of zlib, can +be found at the zlib home page, . +The zlib compression utility is a general purpose utility that is +useful for more than PNG files, and can be used without libpng. +See the documentation delivered with zlib for more details. +You can usually find the source files for the zlib utility wherever you +find the libpng source files. + +Libpng is thread safe, provided the threads are using different +instances of the structures. Each thread should have its own +png_struct and png_info instances, and thus its own image. +Libpng does not protect itself against two threads using the +same instance of a structure. Note: thread safety may be defeated +by use of some of the MMX assembler code in pnggccrd.c, which is only +compiled when the user defines PNG_THREAD_UNSAFE_OK. + +II. Structures + +There are two main structures that are important to libpng, png_struct +and png_info. The first, png_struct, is an internal structure that +will not, for the most part, be used by a user except as the first +variable passed to every libpng function call. + +The png_info structure is designed to provide information about the +PNG file. At one time, the fields of png_info were intended to be +directly accessible to the user. However, this tended to cause problems +with applications using dynamically loaded libraries, and as a result +a set of interface functions for png_info (the png_get_*() and png_set_*() +functions) was developed. The fields of png_info are still available for +older applications, but it is suggested that applications use the new +interfaces if at all possible. + +Applications that do make direct access to the members of png_struct (except +for png_ptr->jmpbuf) must be recompiled whenever the library is updated, +and applications that make direct access to the members of png_info must +be recompiled if they were compiled or loaded with libpng version 1.0.6, +in which the members were in a different order. In version 1.0.7, the +members of the png_info structure reverted to the old order, as they were +in versions 0.97c through 1.0.5. Starting with version 2.0.0, both +structures are going to be hidden, and the contents of the structures will +only be accessible through the png_get/png_set functions. + +The png.h header file is an invaluable reference for programming with libpng. +And while I'm on the topic, make sure you include the libpng header file: + +#include + +III. Reading + +We'll now walk you through the possible functions to call when reading +in a PNG file sequentially, briefly explaining the syntax and purpose +of each one. See example.c and png.h for more detail. While +progressive reading is covered in the next section, you will still +need some of the functions discussed in this section to read a PNG +file. + +Setup + +You will want to do the I/O initialization(*) before you get into libpng, +so if it doesn't work, you don't have much to undo. Of course, you +will also want to insure that you are, in fact, dealing with a PNG +file. Libpng provides a simple check to see if a file is a PNG file. +To use it, pass in the first 1 to 8 bytes of the file to the function +png_sig_cmp(), and it will return 0 if the bytes match the corresponding +bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes +you pass in, the greater the accuracy of the prediction. + +If you are intending to keep the file pointer open for use in libpng, +you must ensure you don't read more than 8 bytes from the beginning +of the file, and you also have to make a call to png_set_sig_bytes_read() +with the number of bytes you read from the beginning. Libpng will +then only check the bytes (if any) that your program didn't read. + +(*): If you are not using the standard I/O functions, you will need +to replace them with custom functions. See the discussion under +Customizing libpng. + + + FILE *fp = fopen(file_name, "rb"); + if (!fp) + { + return (ERROR); + } + fread(header, 1, number, fp); + is_png = !png_sig_cmp(header, 0, number); + if (!is_png) + { + return (NOT_PNG); + } + + +Next, png_struct and png_info need to be allocated and initialized. In +order to ensure that the size of these structures is correct even with a +dynamically linked libpng, there are functions to initialize and +allocate the structures. We also pass the library version, optional +pointers to error handling functions, and a pointer to a data struct for +use by the error functions, if necessary (the pointer and functions can +be NULL if the default error handlers are to be used). See the section +on Changes to Libpng below regarding the old initialization functions. +The structure allocation functions quietly return NULL if they fail to +create the structure, so your application should check for that. + + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, + (png_infopp)NULL, (png_infopp)NULL); + return (ERROR); + } + + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_read_struct_2() instead of png_create_read_struct(): + + png_structp png_ptr = png_create_read_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +The error handling routines passed to png_create_read_struct() +and the memory alloc/free routines passed to png_create_struct_2() +are only necessary if you are not using the libpng supplied error +handling and memory alloc/free functions. + +When libpng encounters an error, it expects to longjmp back +to your routine. Therefore, you will need to call setjmp and pass +your png_jmpbuf(png_ptr). If you read the file from different +routines, you will need to update the jmpbuf field every time you enter +a new routine that will call a png_*() function. + +See your documentation of setjmp/longjmp for your compiler for more +information on setjmp/longjmp. See the discussion on libpng error +handling in the Customizing Libpng section below for more information +on the libpng error handling. If an error occurs, and libpng longjmp's +back to your setjmp, you will want to call png_destroy_read_struct() to +free any memory. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + fclose(fp); + return (ERROR); + } + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the input code. The default for libpng is to +use the C function fread(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. If you wish to handle reading data in another +way, you need not call the png_init_io() function, but you must then +implement the libpng I/O methods discussed in the Customizing Libpng +section below. + + png_init_io(png_ptr, fp); + +If you had previously opened the file and read any of the signature from +the beginning in order to see if this was a PNG file, you need to let +libpng know that there are some bytes missing from the start of the file. + + png_set_sig_bytes(png_ptr, number); + +Setting up callback code + +You can set up a callback function to handle any unknown chunks in the +input stream. You must supply the function + + read_chunk_callback(png_ptr ptr, + png_unknown_chunkp chunk); + { + /* The unknown chunk structure contains your + chunk data: */ + png_byte name[5]; + png_byte *data; + png_size_t size; + /* Note that libpng has already taken care of + the CRC handling */ + + /* put your code here. Return one of the + following: */ + + return (-n); /* chunk had an error */ + return (0); /* did not recognize */ + return (n); /* success */ + } + +(You can give your function another name that you like instead of +"read_chunk_callback") + +To inform libpng about your function, use + + png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, + read_chunk_callback); + +This names not only the callback function, but also a user pointer that +you can retrieve with + + png_get_user_chunk_ptr(png_ptr); + +At this point, you can set up a callback function that will be +called after each row has been read, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void read_row_callback(png_ptr ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "read_row_callback") + +To inform libpng about your function, use + + png_set_read_status_fn(png_ptr, read_row_callback); + +Width and height limits + +The PNG specification allows the width and height of an image to be as +large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. +Since very few applications really need to process such large images, +we have imposed an arbitrary 1-million limit on rows and columns. +Larger images will be rejected immediately with a png_error() call. If +you wish to override this limit, you can use + + png_set_user_limits(png_ptr, width_max, height_max); + +to set your own limits, or use width_max = height_max = 0x7fffffffL +to allow all valid dimensions (libpng may reject some very large images +anyway because of potential buffer overflow conditions). + +You should put this statement after you create the PNG structure and +before calling png_read_info(), png_read_png(), or png_process_data(). +If you need to retrieve the limits that are being applied, use + + width_max = png_get_user_width_max(png_ptr); + height_max = png_get_user_height_max(png_ptr); + +Unknown-chunk handling + +Now you get to set the way the library processes unknown chunks in the +input PNG stream. Both known and unknown chunks will be read. Normal +behavior is that known chunks will be parsed into information in +various info_ptr members; unknown chunks will be discarded. To change +this, you can call: + + png_set_keep_unknown_chunks(png_ptr, keep, + chunk_list, num_chunks); + keep - 0: do not handle as unknown + 1: do not keep + 2: keep only if safe-to-copy + 3: keep even if unsafe-to-copy + You can use these definitions: + PNG_HANDLE_CHUNK_AS_DEFAULT 0 + PNG_HANDLE_CHUNK_NEVER 1 + PNG_HANDLE_CHUNK_IF_SAFE 2 + PNG_HANDLE_CHUNK_ALWAYS 3 + chunk_list - list of chunks affected (a byte string, + five bytes per chunk, NULL or '\0' if + num_chunks is 0) + num_chunks - number of chunks affected; if 0, all + unknown chunks are affected. If nonzero, + only the chunks in the list are affected + +Unknown chunks declared in this way will be saved as raw data onto a +list of png_unknown_chunk structures. If a chunk that is normally +known to libpng is named in the list, it will be handled as unknown, +according to the "keep" directive. If a chunk is named in successive +instances of png_set_keep_unknown_chunks(), the final instance will +take precedence. The IHDR and IEND chunks should not be named in +chunk_list; if they are, libpng will process them normally anyway. + +The high-level read interface + +At this point there are two ways to proceed; through the high-level +read interface, or through a sequence of low-level read operations. +You can use the high-level interface if (a) you are willing to read +the entire image into memory, and (b) the input transformations +you want to do are limited to the following set: + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to + 8 bits + PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel + PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit + samples to bytes + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_EXPAND Perform set_expand() + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + +(This excludes setting a background color, doing gamma transformation, +dithering, and setting filler.) If this is the case, simply do this: + + png_read_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the bitwise OR of +some set of transformation flags. This call is equivalent to png_read_info(), +followed the set of transformations indicated by the transform mask, +then png_read_image(), and finally png_read_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future input transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_read_png(). + +After you have called png_read_png(), you can retrieve the image data +with + + row_pointers = png_get_rows(png_ptr, info_ptr); + +where row_pointers is an array of pointers to the pixel data for each row: + + png_bytep row_pointers[height]; + +If you know your image size and pixel size ahead of time, you can allocate +row_pointers prior to calling png_read_png() with + + if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) + png_error (png_ptr, + "Image is too tall to process in memory"); + if (width > PNG_UINT_32_MAX/pixel_size) + png_error (png_ptr, + "Image is too wide to process in memory"); + row_pointers = png_malloc(png_ptr, + height*png_sizeof(png_bytep)); + for (int i=0; i) and +png_get_(png_ptr, info_ptr, ...) functions return non-zero if the +data has been read, or zero if it is missing. The parameters to the +png_get_ are set directly if they are simple data types, or a pointer +into the info_ptr is returned for any complex types. + + png_get_PLTE(png_ptr, info_ptr, &palette, + &num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_get_gAMA(png_ptr, info_ptr, &gamma); + gamma - the gamma the file is written + at (PNG_INFO_gAMA) + + png_get_sRGB(png_ptr, info_ptr, &srgb_intent); + srgb_intent - the rendering intent (PNG_INFO_sRGB) + The presence of the sRGB chunk + means that the pixel data is in the + sRGB color space. This chunk also + implies specific values of gAMA and + cHRM. + + png_get_iCCP(png_ptr, info_ptr, &name, + &compression_type, &profile, &proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, + red, green, and blue channels, + whichever are appropriate for the + given color type (png_color_16) + + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, + &trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_get_hIST(png_ptr, info_ptr, &hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_get_tIME(png_ptr, info_ptr, &mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_get_bKGD(png_ptr, info_ptr, &background); + background - background color (PNG_VALID_bKGD) + valid 16-bit red, green and blue + values, regardless of color_type + + num_comments = png_get_text(png_ptr, info_ptr, + &text_ptr, &num_text); + num_comments - number of comments + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (empty + string for unknown). + text_ptr[i].lang_key - keyword in UTF-8 + (empty string for unknown). + num_text - number of comments (same as + num_comments; you can put NULL here + to avoid the duplication) + Note while png_set_text() will accept text, language, + and translated keywords that can be NULL pointers, the + structure returned by png_get_text will always contain + regular zero-terminated C strings. They might be + empty strings but they will never be NULL pointers. + + num_spalettes = png_get_sPLT(png_ptr, info_ptr, + &palette_ptr); + palette_ptr - array of palette structures holding + contents of one or more sPLT chunks + read. + num_spalettes - number of sPLT chunks read. + + png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, + &unit_type); + offset_x - positive offset from the left edge + of the screen + offset_y - positive offset from the top edge + of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, + &unit_type); + res_x - pixels/unit physical resolution in + x direction + res_y - pixels/unit physical resolution in + x direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_get_sCAL(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + num_unknown_chunks = png_get_unknown_chunks(png_ptr, + info_ptr, &unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position of chunk in file + + The value of "i" corresponds to the order in which the + chunks were read from the PNG file or inserted with the + png_set_unknown_chunks() function. + +The data from the pHYs chunk can be retrieved in several convenient +forms: + + res_x = png_get_x_pixels_per_meter(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_meter(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_meter(png_ptr, + info_ptr) + res_x = png_get_x_pixels_per_inch(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_inch(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_inch(png_ptr, + info_ptr) + aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, + info_ptr) + + (Each of these returns 0 [signifying "unknown"] if + the data is not present or if res_x is 0; + res_x_and_y is 0 if res_x != res_y) + +The data from the oFFs chunk can be retrieved in several convenient +forms: + + x_offset = png_get_x_offset_microns(png_ptr, info_ptr); + y_offset = png_get_y_offset_microns(png_ptr, info_ptr); + x_offset = png_get_x_offset_inches(png_ptr, info_ptr); + y_offset = png_get_y_offset_inches(png_ptr, info_ptr); + + (Each of these returns 0 [signifying "unknown" if both + x and y are 0] if the data is not present or if the + chunk is present but the unit is the pixel) + +For more information, see the png_info definition in png.h and the +PNG specification for chunk contents. Be careful with trusting +rowbytes, as some of the transformations could increase the space +needed to hold a row (expand, filler, gray_to_rgb, etc.). +See png_read_update_info(), below. + +A quick word about text_ptr and num_text. PNG stores comments in +keyword/text pairs, one pair per chunk, with no limit on the number +of text chunks, and a 2^31 byte limit on their size. While there are +suggested keywords, there is no requirement to restrict the use to these +strings. It is strongly suggested that keywords and text be sensible +to humans (that's the point), so don't use abbreviations. Non-printing +symbols are not allowed. See the PNG specification for more details. +There is also no requirement to have text after the keyword. + +Keywords should be limited to 79 Latin-1 characters without leading or +trailing spaces, but non-consecutive spaces are allowed within the +keyword. It is possible to have the same keyword any number of times. +The text_ptr is an array of png_text structures, each holding a +pointer to a language string, a pointer to a keyword and a pointer to +a text string. The text string, language code, and translated +keyword may be empty or NULL pointers. The keyword/text +pairs are put into the array in the order that they are received. +However, some or all of the text chunks may be after the image, so, to +make sure you have read all the text chunks, don't mess with these +until after you read the stuff after the image. This will be +mentioned again below in the discussion that goes with png_read_end(). + +Input transformations + +After you've read the header information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +The colors used for the background and transparency values should be +supplied in the same format/depth as the current image data. They +are stored in the same format/depth as the image data in a bKGD or tRNS +chunk, so this is what libpng expects for this data. The colors are +transformed to keep in sync with the image data when an application +calls the png_read_update_info() routine (see below). + +Data will be decoded into the supplied row buffers packed into bytes +unless the library has been told to transform it into another format. +For example, 4 bit/pixel paletted or grayscale data will be returned +2 pixels/byte with the leftmost pixel in the high-order bits of the +byte, unless png_set_packing() is called. 8-bit RGB data will be stored +in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() +is called to insert filler bytes, either before or after each RGB triplet. +16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant +byte of the color value first, unless png_set_strip_16() is called to +transform it to regular RGB RGB triplets, or png_set_filler() or +png_set_add alpha() is called to insert filler bytes, either before or +after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can +be modified with +png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). + +The following code transforms grayscale images of less than 8 to 8 bits, +changes paletted images to RGB, and adds a full alpha channel if there is +transparency information in a tRNS chunk. This is most useful on +grayscale images with bit depths of 2 or 4 or if there is a multiple-image +viewing application that wishes to treat all images in the same way. + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && + bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); + +These three functions are actually aliases for png_set_expand(), added +in libpng version 1.0.4, with the function names expanded to improve code +readability. In some future version they may actually do different +things. + +As of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was +added. It expands the sample depth without changing tRNS to alpha. +At the same time, png_set_gray_1_2_4_to_8() was deprecated, and it +will be removed from a future version. + +PNG can have files with 16 bits per channel. If you only can handle +8 bits per channel, this will strip the pixels down to 8 bit. + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + +If, for some reason, you don't need the alpha channel on an image, +and you want to remove it rather than combining it with the background +(but the image author certainly had in mind that you *would* combine +it with the background, so that's what you should probably do): + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); + +In PNG files, the alpha channel in an image +is the level of opacity. If you need the alpha channel in an image to +be the level of transparency instead of opacity, you can invert the +alpha channel (or the tRNS chunk data) after it's read, so that 0 is +fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit +images) is fully transparent, with + + png_set_invert_alpha(png_ptr); + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit +files. This code expands to 1 pixel per byte without changing the +values of the pixels: + + if (bit_depth < 8) + png_set_packing(png_ptr); + +PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels +stored in a PNG image have been "scaled" or "shifted" up to the next +higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to +8 bits/sample in the range [0, 255]). However, it is also possible to +convert the PNG pixel data back to the original bit depth of the image. +This call reduces the pixels back down to the original bit depth: + + png_color_8p sig_bit; + + if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) + png_set_shift(png_ptr, sig_bit); + +PNG files store 3-color pixels in red, green, blue order. This code +changes the storage of the pixels to blue, green, red: + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + +PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them +into 4 or 8 bytes for windowing systems that need them in this format: + + if (color_type == PNG_COLOR_TYPE_RGB) + png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); + +where "filler" is the 8 or 16-bit number to fill with, and the location is +either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether +you want the filler before the RGB or after. This transformation +does not affect images that already have full alpha channels. To add an +opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which +will generate RGBA pixels. + +Note that png_set_filler() does not change the color type. If you want +to do that, you can add a true alpha channel with + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY) + png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); + +where "filler" contains the alpha value to assign to each pixel. +This function was added in libpng-1.2.7. + +If you are reading an image with an alpha channel, and you need the +data as ARGB instead of the normal PNG format RGBA: + + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_swap_alpha(png_ptr); + +For some uses, you may want a grayscale image to be represented as +RGB. This code will do that conversion: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + +Conversely, you can convert an RGB or RGBA image to grayscale or grayscale +with alpha. + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_rgb_to_gray_fixed(png_ptr, error_action, + int red_weight, int green_weight); + + error_action = 1: silently do the conversion + error_action = 2: issue a warning if the original + image has any pixel where + red != green or red != blue + error_action = 3: issue an error and abort the + conversion if the original + image has any pixel where + red != green or red != blue + + red_weight: weight of red component times 100000 + green_weight: weight of green component times 100000 + If either weight is negative, default + weights (21268, 71514) are used. + +If you have set error_action = 1 or 2, you can +later check whether the image really was gray, after processing +the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. +It will return a png_byte that is zero if the image was gray or +1 if there were any non-gray pixels. bKGD and sBIT data +will be silently converted to grayscale, using the green channel +data, regardless of the error_action setting. + +With red_weight+green_weight<=100000, +the normalized graylevel is computed: + + int rw = red_weight * 65536; + int gw = green_weight * 65536; + int bw = 65536 - (rw + gw); + gray = (rw*red + gw*green + bw*blue)/65536; + +The default values approximate those recommended in the Charles +Poynton's Color FAQ, +Copyright (c) 1998-01-04 Charles Poynton + + Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + +Libpng approximates this with + + Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + +which can be expressed with integers as + + Y = (6969 * R + 23434 * G + 2365 * B)/32768 + +The calculation is done in a linear colorspace, if the image gamma +is known. + +If you have a grayscale and you are using png_set_expand_depth(), +png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to +a higher bit-depth, you must either supply the background color as a gray +value at the original file bit-depth (need_expand = 1) or else supply the +background color as an RGB triplet at the final, expanded bit depth +(need_expand = 0). Similarly, if you are reading a paletted image, you +must either supply the background color as a palette index (need_expand = 1) +or as an RGB triplet that may or may not be in the palette (need_expand = 0). + + png_color_16 my_background; + png_color_16p image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + +The png_set_background() function tells libpng to composite images +with alpha or simple transparency against the supplied background +color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), +you may use this color, or supply another color more suitable for +the current display (e.g., the background color from a web page). You +need to tell libpng whether the color is in the gamma space of the +display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file +(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one +that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't +know why anyone would use this, but it's here). + +To properly display PNG images on any kind of system, the application needs +to know what the display gamma is. Ideally, the user will know this, and +the application will allow them to set it. One method of allowing the user +to set the display gamma separately for each system is to check for a +SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be +correctly set. + +Note that display_gamma is the overall gamma correction required to produce +pleasing results, which depends on the lighting conditions in the surrounding +environment. In a dim or brightly lit room, no compensation other than +the physical gamma exponent of the monitor is needed, while in a dark room +a slightly smaller exponent is better. + + double gamma, screen_gamma; + + if (/* We have a user-defined screen + gamma value */) + { + screen_gamma = user_defined_screen_gamma; + } + /* One way that applications can share the same + screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) + != NULL) + { + screen_gamma = (double)atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a + PC monitor in a bright office or a dim room */ + screen_gamma = 2.0; /* A good guess for a + PC monitor in a dark room */ + screen_gamma = 1.7 or 1.0; /* A good + guess for Mac systems */ + } + +The png_set_gamma() function handles gamma transformations of the data. +Pass both the file gamma and the current screen_gamma. If the file does +not have a gamma value, you can pass one anyway if you have an idea what +it is (usually 0.45455 is a good guess for GIF images on PCs). Note +that file gammas are inverted from screen gammas. See the discussions +on gamma in the PNG specification for an excellent description of what +gamma is, and why all applications should support it. It is strongly +recommended that PNG viewers support gamma correction. + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, screen_gamma, gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + +If you need to reduce an RGB file to a paletted file, or if a paletted +file has more entries then will fit on your screen, png_set_dither() +will do that. Note that this is a simple match dither that merely +finds the closest color available. This should work fairly well with +optimized palettes, and fairly badly with linear color cubes. If you +pass a palette that is larger then maximum_colors, the file will +reduce the number of colors in the palette so it will fit into +maximum_colors. If there is a histogram, it will use it to make +more intelligent choices when reducing the palette. If there is no +histogram, it may not do as good a job. + + if (color_type & PNG_COLOR_MASK_COLOR) + { + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_PLTE)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, + &histogram); + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 1); + } + else + { + png_color std_color_cube[MAX_SCREEN_COLORS] = + { ... colors ... }; + + png_set_dither(png_ptr, std_color_cube, + MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, + NULL,0); + } + } + +PNG files describe monochrome as black being zero and white being one. +The following code will reverse this (make black be one and white be +zero): + + if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) + png_set_invert_mono(png_ptr); + +This function can also be used to invert grayscale and gray-alpha images: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_invert_mono(png_ptr); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code changes the storage to the +other way (little-endian, i.e. least significant bits first, the +way PCs store them): + + if (bit_depth == 16) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_read_user_transform_fn(png_ptr, + read_transform_fn); + +You must supply the function + + void read_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +after all of the other transformations have been processed. + +You can also set up a pointer to a user structure for use by your +callback function, and you can inform libpng that your transform +function will change the number of channels or bit depth with the +function + + png_set_user_transform_info(png_ptr, user_ptr, + user_depth, user_channels); + +The user's application, not libpng, is responsible for allocating and +freeing any memory required for the user structure. + +You can retrieve the pointer via the function +png_get_user_transform_ptr(). For example: + + voidp read_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +The last thing to handle is interlacing; this is covered in detail below, +but you must call the function here if you want libpng to handle expansion +of the interlaced image. + + number_of_passes = png_set_interlace_handling(png_ptr); + +After setting the transformations, libpng can update your png_info +structure to reflect any transformations you've requested with this +call. This is most useful to update the info structure's rowbytes +field so you can use it to allocate your image memory. This function +will also update your palette with the correct screen_gamma and +background if these have been given with the calls above. + + png_read_update_info(png_ptr, info_ptr); + +After you call png_read_update_info(), you can allocate any +memory you need to hold the image. The row data is simply +raw byte data for all forms of images. As the actual allocation +varies among applications, no example will be given. If you +are allocating one large chunk, you will need to build an +array of pointers to each row, as it will be needed for some +of the functions below. + +Reading image data + +After you've allocated memory, you can read the image data. +The simplest way to do this is in one function call. If you are +allocating enough memory to hold the whole image, you can just +call png_read_image() and libpng will read in all the image data +and put it in the memory area supplied. You will need to pass in +an array of pointers to each row. + +This function automatically handles interlacing, so you don't need +to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_read_rows(). + + png_read_image(png_ptr, row_pointers); + +where row_pointers is: + + png_bytep row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to read in the whole image at once, you can +use png_read_rows() instead. If there is no interlacing (check +interlace_type == PNG_INTERLACE_NONE), this is simple: + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +where row_pointers is the same as in the png_read_image() call. + +If you are doing this just one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + png_read_row(png_ptr, row_pointer, NULL); + +If the file is interlaced (interlace_type != 0 in the IHDR chunk), things +get somewhat harder. The only current (PNG Specification version 1.2) +interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) +is a somewhat complicated 2D interlace scheme, known as Adam7, that +breaks down an image into seven smaller images of varying size, based +on an 8x8 grid. + +libpng can fill out those images or it can give them to you "as is". +If you want them filled out, there are two ways to do that. The one +mentioned in the PNG specification is to expand each pixel to cover +those pixels that have not been read yet (the "rectangle" method). +This results in a blocky image for the first pass, which gradually +smooths out as more pixels are read. The other method is the "sparkle" +method, where pixels are drawn only in their final locations, with the +rest of the image remaining whatever colors they were initialized to +before the start of the read. The first method usually looks better, +but tends to be slower, as there are more pixels to put in the rows. + +If you don't want libpng to handle the interlacing details, just call +png_read_rows() seven times to read in all seven images. Each of the +images is a valid image by itself, or they can all be combined on an +8x8 grid to form a single image (although if you intend to combine them +you would be far better off using the libpng interlace handling). + +The first pass will return an image 1/8 as wide as the entire image +(every 8th column starting in column 0) and 1/8 as high as the original +(every 8th row starting in row 0), the second will be 1/8 as wide +(starting in column 4) and 1/8 as high (also starting in row 0). The +third pass will be 1/4 as wide (every 4th pixel starting in column 0) and +1/8 as high (every 8th row starting in row 4), and the fourth pass will +be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, +and every 4th row starting in row 0). The fifth pass will return an +image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), +while the sixth pass will be 1/2 as wide and 1/2 as high as the original +(starting in column 1 and row 0). The seventh and final pass will be as +wide as the original, and 1/2 as high, containing all of the odd +numbered scanlines. Phew! + +If you want libpng to expand the images, call this before calling +png_start_read_image() or png_read_update_info(): + + if (interlace_type == PNG_INTERLACE_ADAM7) + number_of_passes + = png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. +This function can be called even if the file is not interlaced, +where it will return one pass. + +If you are not going to display the image after each pass, but are +going to wait until the entire image is read in, use the sparkle +effect. This effect is faster and the end result of either method +is exactly the same. If you are planning on displaying the image +after each pass, the "rectangle" effect is generally considered the +better looking one. + +If you only want the "sparkle" effect, just call png_read_rows() as +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 +rows between calls. You can change the locations of the data, just +not the data. Each pass only writes the pixels appropriate for that +pass, and assumes the data from previous passes is still valid. + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +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 +the second parameter NULL. + + png_read_rows(png_ptr, NULL, row_pointers, + number_of_rows); + +Finishing a sequential read + +After you are finished reading the image through the +low-level interface, you can finish reading the file. If you are +interested in comments or time, which may be stored either before or +after the image data, you should pass the separate png_info struct if +you want to keep the comments from before and after the image +separate. If you are not interested, you can pass NULL. + + png_read_end(png_ptr, end_info); + +When you are done, you can free all memory allocated by libpng like this: + + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the bitwise OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +This function only affects data that has already been allocated. +You can call this function after reading the PNG data but before calling +any png_set_*() functions, to control whether the user or the png_set_*() +function is responsible for freeing any existing data that might be present, +and again after the png_set_*() functions to control whether the user +or png_destroy_*() is supposed to free the data. When the user assumes +responsibility for libpng-allocated data, the application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated your row_pointers in a single block, as suggested above in +the description of the high level read interface, you must not transfer +responsibility for freeing it to the png_set_rows or png_read_destroy function, +because they would also try to free the individual row_pointers[i]. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. + +The png_free_data() function will turn off the "valid" flag for anything +it frees. If you need to turn the flag off for a chunk that was freed by your +application instead of by libpng, you can use + + png_set_invalid(png_ptr, info_ptr, mask); + mask - identifies the chunks to be made invalid, + containing the bitwise OR of one or + more of + PNG_INFO_gAMA, PNG_INFO_sBIT, + PNG_INFO_cHRM, PNG_INFO_PLTE, + PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_hIST, PNG_INFO_pHYs, + PNG_INFO_oFFs, PNG_INFO_tIME, + PNG_INFO_pCAL, PNG_INFO_sRGB, + PNG_INFO_iCCP, PNG_INFO_sPLT, + PNG_INFO_sCAL, PNG_INFO_IDAT + +For a more compact example of reading a PNG image, see the file example.c. + +Reading PNG files progressively + +The progressive reader is slightly different then the non-progressive +reader. Instead of calling png_read_info(), png_read_rows(), and +png_read_end(), you make one call to png_process_data(), which calls +callbacks when it has the info, a row, or the end of the image. You +set up these callbacks with png_set_progressive_read_fn(). You don't +have to worry about the input/output functions of libpng, as you are +giving the library the data directly in png_process_data(). I will +assume that you have read the section on reading PNG files above, +so I will only highlight the differences (although I will show +all of the code). + +png_structp png_ptr; +png_infop info_ptr; + + /* An example code fragment of how you would + initialize the progressive reader in your + application. */ + int + initialize_png_reader() + { + png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, + (png_infopp)NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new. You can provide functions + to be called when the header info is valid, + when each row is completed, and when the image + is finished. If you aren't using all functions, + you can specify NULL parameters. Even when all + three functions are NULL, you need to call + png_set_progressive_read_fn(). You can use + any struct as the user_ptr (cast to a void pointer + for the function call), and retrieve the pointer + from inside the callbacks using the function + + png_get_progressive_ptr(png_ptr); + + which will return a void pointer, which you have + to cast appropriately. + */ + png_set_progressive_read_fn(png_ptr, (void *)user_ptr, + info_callback, row_callback, end_callback); + + return 0; + } + + /* A code fragment that you call as you receive blocks + of data */ + int + process_data(png_bytep buffer, png_uint_32 length) + { + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new also. Simply give it a chunk + of data from the file stream (in order, of + course). On machines with segmented memory + models machines, don't give it any more than + 64K. The library seems to run fine with sizes + of 4K. Although you can give it much less if + necessary (I assume you can give it chunks of + 1 byte, I haven't tried less then 256 bytes + yet). When this function returns, you may + want to display any rows that were generated + in the row callback if you don't already do + so there. + */ + png_process_data(png_ptr, info_ptr, buffer, length); + return 0; + } + + /* This function is called (as set by + png_set_progressive_read_fn() above) when enough data + has been supplied so all of the header has been + read. + */ + void + info_callback(png_structp png_ptr, png_infop info) + { + /* Do any setup here, including setting any of + the transformations mentioned in the Reading + PNG files section. For now, you _must_ call + either png_start_read_image() or + png_read_update_info() after all the + transformations are set (even if you don't set + any). You may start getting rows before + png_process_data() returns, so this is your + last chance to prepare for that. + */ + } + + /* This function is called when each row of image + data is complete */ + void + row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) + { + /* If the image is interlaced, and you turned + on the interlace handler, this function will + be called for every row in every pass. Some + of these rows will not be changed from the + previous pass. When the row is not changed, + the new_row variable will be NULL. The rows + and passes are called in order, so you don't + really need the row_num and pass, but I'm + supplying them because it may make your life + easier. + + For the non-NULL rows of interlaced images, + you must call png_progressive_combine_row() + passing in the row and the old row. You can + call this function for NULL rows (it will just + return) and for non-interlaced images (it just + does the memcpy for you) if it will make the + code easier. Thus, you can just do this for + all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, + new_row); + + /* where old_row is what was displayed for + previously for the row. Note that the first + pass (pass == 0, really) will completely cover + the old row, so the rows do not have to be + initialized. After the first pass (and only + for interlaced images), you will have to pass + the current row, and the function will combine + the old row and the new row. + */ + } + + void + end_callback(png_structp png_ptr, png_infop info) + { + /* This function is called after the whole image + has been read, including any chunks after the + image (up to and including the IEND). You + will usually have the same info chunk as you + had in the header, although some data may have + been added to the comments and time fields. + + Most people won't do much here, perhaps setting + a flag that marks the image as finished. + */ + } + + + +IV. Writing + +Much of this is very similar to reading. However, everything of +importance is repeated here, so you won't have to constantly look +back up in the reading section to understand writing. + +Setup + +You will want to do the I/O initialization before you get into libpng, +so if it doesn't work, you don't have anything to undo. If you are not +using the standard I/O functions, you will need to replace them with +custom writing functions. See the discussion under Customizing libpng. + + FILE *fp = fopen(file_name, "wb"); + if (!fp) + { + return (ERROR); + } + +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 +on the stack, unless you have stack space to spare. Of course, you +will want to check if they return NULL. If you are also reading, +you won't want to name your read structure and your write structure +both "png_ptr"; you can call them anything you like, such as +"read_ptr" and "write_ptr". Look at pngtest.c, for example. + + png_structp png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_write_struct(&png_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_write_struct_2() instead of png_create_write_struct(): + + png_structp png_ptr = png_create_write_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +After you have these structures, you will need to set up the +error handling. When libpng encounters an error, it expects to +longjmp() back to your routine. Therefore, you will need to call +setjmp() and pass the png_jmpbuf(png_ptr). If you +write the file from different routines, you will need to update +the png_jmpbuf(png_ptr) every time you enter a new routine that will +call a png_*() function. See your documentation of setjmp/longjmp +for your compiler for more information on setjmp/longjmp. See +the discussion on libpng error handling in the Customizing Libpng +section below for more information on the libpng error handling. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (ERROR); + } + ... + return; + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the output code. The default for libpng is to +use the C function fwrite(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. Again, if you wish to handle writing data in +another way, see the discussion on libpng I/O handling in the Customizing +Libpng section below. + + png_init_io(png_ptr, fp); + +If you are embedding your PNG into a datastream such as MNG, and don't +want libpng to write the 8-byte signature, or if you have already +written the signature in your application, use + + png_set_sig_bytes(png_ptr, 8); + +to inform libpng that it should not write a signature. + +Write callbacks + +At this point, you can set up a callback function that will be +called after each row has been written, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void write_row_callback(png_ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "write_row_callback") + +To inform libpng about your function, use + + png_set_write_status_fn(png_ptr, write_row_callback); + +You now have the option of modifying how the compression library will +run. The following functions are mainly for testing, but may be useful +in some cases, like if you need to write PNG files extremely fast and +are willing to give up some compression, or if you want to get the +maximum possible compression at the expense of slower writing. If you +have no special needs in this area, let the library do what it wants by +not calling this function at all, as it has been tuned to deliver a good +speed/compression ratio. The second parameter to png_set_filter() is +the filter method, for which the only valid values are 0 (as of the +July 1999 PNG specification, version 1.2) or 64 (if you are writing +a PNG datastream that is to be embedded in a MNG datastream). The third +parameter is a flag that indicates which filter type(s) are to be tested +for each scanline. See the PNG specification for details on the specific filter +types. + + + /* turn on or off filtering, and/or choose + specific filters. You can use either a single + PNG_FILTER_VALUE_NAME or the bitwise OR of one + or more PNG_FILTER_NAME masks. */ + png_set_filter(png_ptr, 0, + PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | + PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | + PNG_FILTER_UP | PNG_FILTER_VALUE_UP | + PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | + PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| + PNG_ALL_FILTERS); + +If an application +wants to start and stop using particular filters during compression, +it should start out with all of the filters (to ensure that the previous +row of pixels will be stored in case it's needed later), and then add +and remove them after the start of compression. + +If you are writing a PNG datastream that is to be embedded in a MNG +datastream, the second parameter can be either 0 or 64. + +The png_set_compression_*() functions interface to the zlib compression +library, and should mostly be ignored unless you really know what you are +doing. The only generally useful call is png_set_compression_level() +which changes how much time zlib spends on trying to compress the image +data. See the Compression Library (zlib.h and algorithm.txt, distributed +with zlib) for details on the compression levels. + + /* set the zlib compression level */ + png_set_compression_level(png_ptr, + Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr, + Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192) + +extern PNG_EXPORT(void,png_set_zbuf_size) + +Setting the contents of info for output + +You now need to fill in the png_info structure with all the data you +wish to write before the actual image. Note that the only thing you +are allowed to write after the image is the text chunks and the time +chunk (as of PNG Specification 1.2, anyway). See png_write_end() and +the latest PNG specification for more information on that. If you +wish to write them before the image, fill them in now, and flag that +data as being valid. If you want to wait until after the data, don't +fill them until png_write_end(). For all the fields in png_info and +their data types, see png.h. For explanations of what the fields +contain, see the PNG specification. + +Some of the more important parts of the png_info are: + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace_type, + compression_type, filter_method) + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. + (valid values are 1, 2, 4, 8, 16 + and depend also on the + color_type. See also significant + bits (sBIT) below). + color_type - describes which color/alpha + channels are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + interlace_type - PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7 + compression_type - (must be + PNG_COMPRESSION_TYPE_DEFAULT) + filter_method - (must be PNG_FILTER_TYPE_DEFAULT + or, if you are writing a PNG to + be embedded in a MNG datastream, + can also be + PNG_INTRAPIXEL_DIFFERENCING) + + png_set_PLTE(png_ptr, info_ptr, palette, + num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_set_gAMA(png_ptr, info_ptr, gamma); + gamma - the gamma the image was created + at (PNG_INFO_gAMA) + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of + the sRGB chunk means that the pixel + data is in the sRGB color space. + This chunk also implies specific + values of gAMA and cHRM. Rendering + intent is the CSS-1 property that + has been defined by the International + Color Consortium + (http://www.color.org). + It can be one of + PNG_sRGB_INTENT_SATURATION, + PNG_sRGB_INTENT_PERCEPTUAL, + PNG_sRGB_INTENT_ABSOLUTE, or + PNG_sRGB_INTENT_RELATIVE. + + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, + srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of the + sRGB chunk means that the pixel + data is in the sRGB color space. + This function also causes gAMA and + cHRM chunks with the specific values + that are consistent with sRGB to be + written. + + png_set_iCCP(png_ptr, info_ptr, name, compression_type, + profile, proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_set_sBIT(png_ptr, info_ptr, sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, red, + green, and blue channels, whichever are + appropriate for the given color type + (png_color_16) + + png_set_tRNS(png_ptr, info_ptr, trans, num_trans, + trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_set_hIST(png_ptr, info_ptr, hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_set_tIME(png_ptr, info_ptr, mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_set_bKGD(png_ptr, info_ptr, background); + background - background color (PNG_VALID_bKGD) + + png_set_text(png_ptr, info_ptr, text_ptr, num_text); + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be NULL or empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (NULL or + empty for unknown). + text_ptr[i].translated_keyword - keyword in UTF-8 (NULL + or empty for unknown). + num_text - number of comments + + png_set_sPLT(png_ptr, info_ptr, &palette_ptr, + num_spalettes); + palette_ptr - array of png_sPLT_struct structures + to be added to the list of palettes + in the info structure. + num_spalettes - number of palette structures to be + added. + + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, + unit_type); + offset_x - positive offset from the left + edge of the screen + offset_y - positive offset from the top + edge of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, + unit_type); + res_x - pixels/unit physical resolution + in x direction + res_y - pixels/unit physical resolution + in y direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_set_sCAL(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, + num_unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position to write chunk in file + 0: do not write chunk + PNG_HAVE_IHDR: before PLTE + PNG_HAVE_PLTE: before IDAT + PNG_AFTER_IDAT: after IDAT + +The "location" member is set automatically according to +what part of the output file has already been written. +You can change its value after calling png_set_unknown_chunks() +as demonstrated in pngtest.c. Within each of the "locations", +the chunks are sequenced according to their position in the +structure (that is, the value of "i", which is the order in which +the chunk was either read from the input file or defined with +png_set_unknown_chunks). + +A quick word about text and num_text. text is an array of png_text +structures. num_text is the number of valid structures in the array. +Each png_text structure holds a language code, a keyword, a text value, +and a compression type. + +The compression types have the same valid numbers as the compression +types of the image data. Currently, the only valid number is zero. +However, you can store text either compressed or uncompressed, unlike +images, which always have to be compressed. So if you don't want the +text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. +Because tEXt and zTXt chunks don't have a language field, if you +specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt +any language code or translated keyword will not be written out. + +Until text gets around 1000 bytes, it is not worth compressing it. +After the text has been written out to the file, the compression type +is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, +so that it isn't written out again at the end (in case you are calling +png_write_end() with the same struct. + +The keywords that are given in the PNG Specification are: + + Title Short (one line) title or + caption for image + Author Name of image's creator + Description Description of image (possibly long) + Copyright Copyright notice + Creation Time Time of original image creation + (usually RFC 1123 format, see below) + Software Software used to create the image + Disclaimer Legal disclaimer + Warning Warning of nature of content + Source Device used to create the image + Comment Miscellaneous comment; conversion + from other image format + +The keyword-text pairs work like this. Keywords should be short +simple descriptions of what the comment is about. Some typical +keywords are found in the PNG specification, as is some recommendations +on keywords. You can repeat keywords in a file. You can even write +some text before the image and some after. For example, you may want +to put a description of the image before the image, but leave the +disclaimer until after, so viewers working over modem connections +don't have to wait for the disclaimer to go over the modem before +they start seeing the image. Finally, keywords should be full +words, not abbreviations. Keywords and text are in the ISO 8859-1 +(Latin-1) character set (a superset of regular ASCII) and can not +contain NUL characters, and should not contain control or other +unprintable characters. To make the comments widely readable, stick +with basic ASCII, and avoid machine specific character set extensions +like the IBM-PC character set. The keyword must be present, but +you can leave off the text string on non-compressed pairs. +Compressed pairs must have a text string, as only the text string +is compressed anyway, so the compression would be meaningless. + +PNG supports modification time via the png_time structure. Two +conversion routines are provided, png_convert_from_time_t() for +time_t and png_convert_from_struct_tm() for struct tm. The +time_t routine uses gmtime(). You don't have to use either of +these, but if you wish to fill in the png_time structure directly, +you should provide the time in universal time (GMT) if possible +instead of your local time. Note that the year number is the full +year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and +that months start with 1. + +If you want to store the time of the original image creation, you should +use a plain tEXt chunk with the "Creation Time" keyword. This is +necessary because the "creation time" of a PNG image is somewhat vague, +depending on whether you mean the PNG file, the time the image was +created in a non-PNG format, a still photo from which the image was +scanned, or possibly the subject matter itself. In order to facilitate +machine-readable dates, it is recommended that the "Creation Time" +tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), +although this isn't a requirement. Unlike the tIME chunk, the +"Creation Time" tEXt chunk is not expected to be automatically changed +by the software. To facilitate the use of RFC 1123 dates, a function +png_convert_to_rfc1123(png_timep) is provided to convert from PNG +time to an RFC 1123 format string. + +Writing unknown chunks + +You can use the png_set_unknown_chunks function to queue up chunks +for writing. You give it a chunk name, raw data, and a size; that's +all there is to it. The chunks will be written by the next following +png_write_info_before_PLTE, png_write_info, or png_write_end function. +Any chunks previously read into the info structure's unknown-chunk +list will also be written out in a sequence that satisfies the PNG +specification's ordering rules. + +The high-level write interface + +At this point there are two ways to proceed; through the high-level +write interface, or through a sequence of low-level write operations. +You can use the high-level interface if your image data is present +in the info structure. All defined output +transformations are permitted, enabled by the following masks. + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. + +If you have valid image data in the info structure (you can use +png_set_rows() to put image data in the info structure), simply do this: + + png_write_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the bitwise OR of some set of +transformation flags. This call is equivalent to png_write_info(), +followed the set of transformations indicated by the transform mask, +then png_write_image(), and finally png_write_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future output transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_write_png(). + +The low-level write interface + +If you are going the low-level route instead, you are now ready to +write all the file information up to the actual image data. You do +this with a call to png_write_info(). + + png_write_info(png_ptr, info_ptr); + +Note that there is one transformation you may need to do before +png_write_info(). In PNG files, the alpha channel in an image is the +level of opacity. If your data is supplied as a level of +transparency, you can invert the alpha channel before you write it, so +that 0 is fully transparent and 255 (in 8-bit or paletted images) or +65535 (in 16-bit images) is fully opaque, with + + png_set_invert_alpha(png_ptr); + +This must appear before png_write_info() instead of later with the +other transformations because in the case of paletted images the tRNS +chunk data has to be inverted before the tRNS chunk is written. If +your image is not a paletted image, the tRNS data (which in such cases +represents a single color to be rendered as transparent) won't need to +be changed, and you can safely do this transformation after your +png_write_info() call. + +If you need to write a private chunk that you want to appear before +the PLTE chunk when PLTE is present, you can write the PNG info in +two steps, and insert code to write your own chunk between them: + + png_write_info_before_PLTE(png_ptr, info_ptr); + png_set_unknown_chunks(png_ptr, info_ptr, ...); + png_write_info(png_ptr, info_ptr); + +After you've written the file information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +PNG files store RGB pixels packed into 3 or 6 bytes. This code tells +the library to strip input data that has 4 or 8 bytes per pixel down +to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 +bytes per pixel). + + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + +where the 0 is unused, and the location is either PNG_FILLER_BEFORE or +PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel +is stored XRGB or RGBX. + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit files. +If the data is supplied at 1 pixel per byte, use this code, which will +correctly pack the pixels into a single byte: + + png_set_packing(png_ptr); + +PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your +data is of another bit depth, you can write an sBIT chunk into the +file so that decoders can recover the original data if desired. + + /* Set the true bit depth of the image data */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit.red = true_bit_depth; + sig_bit.green = true_bit_depth; + sig_bit.blue = true_bit_depth; + } + else + { + sig_bit.gray = true_bit_depth; + } + if (color_type & PNG_COLOR_MASK_ALPHA) + { + sig_bit.alpha = true_bit_depth; + } + + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + +If the data is stored in the row buffer in a bit depth other than +one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), +this will scale the values to appear to be the correct bit depth as +is required by PNG. + + png_set_shift(png_ptr, &sig_bit); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code would be used if they are +supplied the other way (little-endian, i.e. least significant bits +first, the way PCs store them): + + if (bit_depth > 8) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +PNG files store 3 color pixels in red, green, blue order. This code +would be used if they are supplied as blue, green, red: + + png_set_bgr(png_ptr); + +PNG files describe monochrome as black being zero and white being +one. This code would be used if the pixels are supplied with this reversed +(black being one and white being zero): + + png_set_invert_mono(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_write_user_transform_fn(png_ptr, + write_transform_fn); + +You must supply the function + + void write_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +before any of the other transformations are processed. + +You can also set up a pointer to a user structure for use by your +callback function. + + png_set_user_transform_info(png_ptr, user_ptr, 0, 0); + +The user_channels and user_depth parameters of this function are ignored +when writing; you can set them to zero as shown. + +You can retrieve the pointer via the function png_get_user_transform_ptr(). +For example: + + voidp write_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +It is possible to have libpng flush any pending output, either manually, +or automatically after a certain number of lines have been written. To +flush the output stream a single time call: + + png_write_flush(png_ptr); + +and to have libpng flush the output stream periodically after a certain +number of scanlines have been written, call: + + png_set_flush(png_ptr, nrows); + +Note that the distance between rows is from the last time png_write_flush() +was called, or the first row of the image if it has never been called. +So if you write 50 lines, and then png_set_flush 25, it will flush the +output on the next scanline, and every 25 lines thereafter, unless +png_write_flush() is called before 25 more lines have been written. +If nrows is too small (less than about 10 lines for a 640 pixel wide +RGB image) the image compression may decrease noticeably (although this +may be acceptable for real-time applications). Infrequent flushing will +only degrade the compression performance by a few percent over images +that do not use flushing. + +Writing the image data + +That's it for the transformations. Now you can write the image data. +The simplest way to do this is in one function call. If you have the +whole image in memory, you can just call png_write_image() and libpng +will write the image. You will need to pass in an array of pointers to +each row. This function automatically handles interlacing, so you don't +need to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_write_rows(). + + png_write_image(png_ptr, row_pointers); + +where row_pointers is: + + png_byte *row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to write the whole image at once, you can +use png_write_rows() instead. If the file is not interlaced, +this is simple: + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +row_pointers is the same as in the png_write_image() call. + +If you are just writing one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + + png_write_row(png_ptr, row_pointer); + +When the file is interlaced, things can get a good deal more +complicated. The only currently (as of the PNG Specification +version 1.2, dated July 1999) defined interlacing scheme for PNG files +is the "Adam7" interlace scheme, that breaks down an +image into seven smaller images of varying size. libpng will build +these images for you, or you can do them yourself. If you want to +build them yourself, see the PNG specification for details of which +pixels to write when. + +If you don't want libpng to handle the interlacing details, just +use png_set_interlace_handling() and call png_write_rows() the +correct number of times to write all seven sub-images. + +If you want libpng to build the sub-images, call this before you start +writing any rows: + + number_of_passes = + png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. + +Then write the complete image number_of_passes times. + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +As some of these rows are not used, and thus return immediately, +you may want to read about interlacing in the PNG specification, +and only update the rows that are actually used. + +Finishing a sequential write + +After you are finished writing the image, you should finish writing +the file. If you are interested in writing comments or time, you should +pass an appropriately filled png_info pointer. If you are not interested, +you can pass NULL. + + png_write_end(png_ptr, info_ptr); + +When you are done, you can free all memory used by libpng like this: + + png_destroy_write_struct(&png_ptr, &info_ptr); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the bitwise OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +If you allocated data such as a palette that you passed +in to libpng with png_set_*, you must not free it until just before the call to +png_destroy_write_struct(). + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +For example, to transfer responsibility for some data from a read structure +to a write structure, you could use + + png_data_freer(read_ptr, read_info_ptr, + PNG_USER_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + png_data_freer(write_ptr, write_info_ptr, + PNG_DESTROY_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + +thereby briefly reassigning responsibility for freeing to the user but +immediately afterwards reassigning it once more to the write_destroy +function. Having done this, it would then be safe to destroy the read +structure and continue to use the PLTE, tRNS, and hIST data in the write +structure. + +This function only affects data that has already been allocated. +You can call this function before calling after the png_set_*() functions +to control whether the user or png_destroy_*() is supposed to free the data. +When the user assumes responsibility for libpng-allocated data, the +application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. +For a more compact example of writing a PNG image, see the file example.c. + +V. Modifying/Customizing libpng: + +There are three issues here. The first is changing how libpng does +standard things like memory allocation, input/output, and error handling. +The second deals with more complicated things like adding new chunks, +adding new transformations, and generally changing how libpng works. +Both of those are compile-time issues; that is, they are generally +determined at the time the code is written, and there is rarely a need +to provide the user with a means of changing them. The third is a +run-time issue: choosing between and/or tuning one or more alternate +versions of computationally intensive routines; specifically, optimized +assembly-language (and therefore compiler- and platform-dependent) +versions. + +Memory allocation, input/output, and error handling + +All of the memory allocation, input/output, and error handling in libpng +goes through callbacks that are user-settable. The default routines are +in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change +these functions, call the appropriate png_set_*_fn() function. + +Memory allocation is done through the functions png_malloc() +and png_free(). These currently just call the standard C functions. If +your pointers can't access more then 64K at a time, you will want to set +MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling +memory allocation on a platform will change between applications, these +functions must be modified in the library at compile time. If you prefer +to use a different method of allocating and freeing data, you can use +png_create_read_struct_2() or png_create_write_struct_2() to register +your own functions as described above. +These functions also provide a void pointer that can be retrieved via + + mem_ptr=png_get_mem_ptr(png_ptr); + +Your replacement memory functions must have prototypes as follows: + + png_voidp malloc_fn(png_structp png_ptr, + png_size_t size); + void free_fn(png_structp png_ptr, png_voidp ptr); + +Your malloc_fn() must return NULL in case of failure. The png_malloc() +function will normally call png_error() if it receives a NULL from the +system memory allocator or from your replacement malloc_fn(). + +Input/Output in libpng is done through png_read() and png_write(), +which currently just call fread() and fwrite(). The FILE * is stored in +png_struct and is initialized via png_init_io(). If you wish to change +the method of I/O, the library supplies callbacks that you can set +through the function png_set_read_fn() and png_set_write_fn() at run +time, instead of calling the png_init_io() function. These functions +also provide a void pointer that can be retrieved via the function +png_get_io_ptr(). For example: + + png_set_read_fn(png_structp read_ptr, + voidp read_io_ptr, png_rw_ptr read_data_fn) + + png_set_write_fn(png_structp write_ptr, + voidp write_io_ptr, png_rw_ptr write_data_fn, + png_flush_ptr output_flush_fn); + + voidp read_io_ptr = png_get_io_ptr(read_ptr); + voidp write_io_ptr = png_get_io_ptr(write_ptr); + +The replacement I/O functions must have prototypes as follows: + + void user_read_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_write_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_flush_data(png_structp png_ptr); + +Supplying NULL for the read, write, or flush functions sets them back +to using the default C stream functions. It is an error to read from +a write stream, and vice versa. + +Error handling in libpng is done through png_error() and png_warning(). +Errors handled through png_error() are fatal, meaning that png_error() +should never return to its caller. Currently, this is handled via +setjmp() and longjmp() (unless you have compiled libpng with +PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), +but you could change this to do things like exit() if you should wish. + +On non-fatal errors, png_warning() is called +to print a warning message, and then control returns to the calling code. +By default png_error() and png_warning() print a message on stderr via +fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined +(because you don't want the messages) or PNG_NO_STDIO defined (because +fprintf() isn't available). If you wish to change the behavior of the error +functions, you will need to set up your own message callbacks. These +functions are normally supplied at the time that the png_struct is created. +It is also possible to redirect errors and warnings to your own replacement +functions after png_create_*_struct() has been called by calling: + + png_set_error_fn(png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_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 +default function will be used, calling fprintf() and/or longjmp() if a +problem is encountered. The replacement error functions should have +parameters as follows: + + void user_error_fn(png_structp png_ptr, + png_const_charp error_msg); + void user_warning_fn(png_structp png_ptr, + png_const_charp warning_msg); + +The motivation behind using setjmp() and longjmp() is the C++ throw and +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. +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 +setjmp returns non-zero besides returning itself. Consult your compiler +documentation for more details. For an alternative approach, you may wish +to use the "cexcept" facility (see http://cexcept.sourceforge.net). + +Custom chunks + +If you need to read or write custom chunks, you may need to get deeper +into the libpng code. The library now has mechanisms for storing +and writing chunks of unknown type; you can even declare callbacks +for custom chunks. However, this may not be good enough if the +library code itself needs to know about interactions between your +chunk and existing `intrinsic' chunks. + +If you need to write a new intrinsic chunk, first read the PNG +specification. Acquire a first level of +understanding of how it works. Pay particular attention to the +sections that describe chunk names, and look at how other chunks were +designed, so you can do things similarly. Second, check out the +sections of libpng that read and write chunks. Try to find a chunk +that is similar to yours and use it as a template. More details can +be found in the comments inside the code. It is best to handle unknown +chunks in a generic method, via callback functions, instead of by +modifying libpng functions. + +If you wish to write your own transformation for the data, look through +the part of the code that does the transformations, and check out some of +the simpler ones to get an idea of how they work. Try to find a similar +transformation to the one you want to add and copy off of it. More details +can be found in the comments inside the code itself. + +Configuring for 16 bit platforms + +You will want to look into zconf.h to tell zlib (and thus libpng) that +it cannot allocate more then 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. + +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. + +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 *. + +Configuring for gui/windowing platforms: + +You will need to write new error and warning functions that use the GUI +interface, as described previously, and set them to be the error and +warning functions at the time that png_create_*_struct() is called, +in order to have them available during the structure initialization. +They can be changed later via png_set_error_fn(). On some compilers, +you may also have to change the memory allocators (png_malloc, etc.). + +Configuring for compiler xxx: + +All includes for libpng are in pngconf.h. If you need to add/change/delete +an include, this is the place to do it. The includes that are not +needed outside libpng are protected by the PNG_INTERNAL definition, +which is only defined for those routines inside libpng itself. The +files in libpng proper only include png.h, which includes pngconf.h. + +Configuring zlib: + +There are special functions to configure the compression. Perhaps the +most useful one changes the compression level, which currently uses +input compression values in the range 0 - 9. The library normally +uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests +have shown that for a large majority of images, compression values in +the range 3-6 compress nearly as well as higher levels, and do so much +faster. For online applications it may be desirable to have maximum speed +(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also +specify no compression (Z_NO_COMPRESSION = 0), but this would create +files larger than just storing the raw bitmap. You can specify the +compression level by calling: + + png_set_compression_level(png_ptr, level); + +Another useful one is to reduce the memory level used by the library. +The memory level defaults to 8, but it can be lowered if you are +short on memory (running DOS, for example, where you only have 640K). +Note that the memory level does have an effect on compression; among +other things, lower levels will result in sections of incompressible +data being emitted in smaller stored blocks, with a correspondingly +larger relative overhead of up to 15% in the worst case. + + png_set_compression_mem_level(png_ptr, level); + +The other functions are for configuring zlib. They are not recommended +for normal use and may result in writing an invalid PNG file. See +zlib.h for more information on what these mean. + + png_set_compression_strategy(png_ptr, + strategy); + png_set_compression_window_bits(png_ptr, + window_bits); + png_set_compression_method(png_ptr, method); + png_set_compression_buffer_size(png_ptr, size); + +Controlling row filtering + +If you want to control whether libpng uses filtering or not, which +filters are used, and how it goes about picking row filters, you +can call one of these functions. The selection and configuration +of row filters can have a significant impact on the size and +encoding speed and a somewhat lesser impact on the decoding speed +of an image. Filtering is enabled by default for RGB and grayscale +images (with and without alpha), but not for paletted images nor +for any images with bit depths less than 8 bits/pixel. + +The 'method' parameter sets the main filtering method, which is +currently only '0' in the PNG 1.2 specification. The 'filters' +parameter sets which filter(s), if any, should be used for each +scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS +to turn filtering on and off, respectively. + +Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, +PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise +ORed together with '|' to specify one or more filters to use. +These filters are described in more detail in the PNG specification. +If you intend to change the filter type during the course of writing +the image, you should start with flags set for all of the filters +you intend to use so that libpng can initialize its internal +structures appropriately for all of the filter types. (Note that this +means the first row must always be adaptively filtered, because libpng +currently does not allocate the filter buffers until png_write_row() +is called for the first time.) + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB + PNG_FILTER_UP | PNG_FILTER_AVE | + PNG_FILTER_PAETH | PNG_ALL_FILTERS; + + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, + filters); + The second parameter can also be + PNG_INTRAPIXEL_DIFFERENCING if you are + writing a PNG to be embedded in a MNG + datastream. This parameter must be the + same as the value of filter_method used + in png_set_IHDR(). + +It is also possible to influence how libpng chooses from among the +available filters. This is done in one or both of two ways - by +telling it how important it is to keep the same filter for successive +rows, and by telling it the relative computational costs of the filters. + + double weights[3] = {1.5, 1.3, 1.1}, + costs[PNG_FILTER_VALUE_LAST] = + {1.0, 1.3, 1.3, 1.5, 1.7}; + + png_set_filter_heuristics(png_ptr, + PNG_FILTER_HEURISTIC_WEIGHTED, 3, + weights, costs); + +The weights are multiplying factors that indicate to libpng that the +row filter should be the same for successive rows unless another row filter +is that many times better than the previous filter. In the above example, +if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a +"sum of absolute differences" 1.5 x 1.3 times higher than other filters +and still be chosen, while the NONE filter could have a sum 1.1 times +higher than other filters and still be chosen. Unspecified weights are +taken to be 1.0, and the specified weights should probably be declining +like those above in order to emphasize recent filters over older filters. + +The filter costs specify for each filter type a relative decoding cost +to be considered when selecting row filters. This means that filters +with higher costs are less likely to be chosen over filters with lower +costs, unless their "sum of absolute differences" is that much smaller. +The costs do not necessarily reflect the exact computational speeds of +the various filters, since this would unduly influence the final image +size. + +Note that the numbers above were invented purely for this example and +are given only to help explain the function usage. Little testing has +been done to find optimum values for either the costs or the weights. + +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_. + +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. + +Requesting debug printout + +The macro definition PNG_DEBUG can be used to request debugging +printout. Set it to an integer value in the range 0 to 3. Higher +numbers result in increasing amounts of debugging information. The +information is printed to the "stderr" file, unless another file +name is specified in the PNG_DEBUG_FILE macro definition. + +When PNG_DEBUG > 0, the following functions (macros) become available: + + png_debug(level, message) + png_debug1(level, message, p1) + png_debug2(level, message, p1, p2) + +in which "level" is compared to PNG_DEBUG to decide whether to print +the message, "message" is the formatted string to be printed, +and p1 and p2 are parameters that are to be embedded in the string +according to printf-style formatting directives. For example, + + png_debug1(2, "foo=%d\n", foo); + +is expanded to + + if(PNG_DEBUG > 2) + fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); + +When PNG_DEBUG is defined but is zero, the macros aren't defined, but you +can still use PNG_DEBUG to control your own debugging: + + #ifdef PNG_DEBUG + fprintf(stderr, ... + #endif + +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 +this version of libpng, but if you insert some they will be printed. + +VI. Runtime optimization + +A new feature in libpng 1.2.0 is the ability to dynamically switch between +standard and optimized versions of some routines. Currently these are +limited to three computationally intensive tasks when reading PNG files: +decoding row filters, expanding interlacing, and combining interlaced or +transparent row data with previous row data. Currently the optimized +versions are available only for x86 (Intel, AMD, etc.) platforms with +MMX support, though this may change in future versions. (For example, +the non-MMX assembler optimizations for zlib might become similarly +runtime-selectable in future releases, in which case libpng could be +extended to support them. Alternatively, the compile-time choice of +floating-point versus integer routines for gamma correction might become +runtime-selectable.) + +Because such optimizations tend to be very platform- and compiler-dependent, +both in how they are written and in how they perform, the new runtime code +in libpng has been written to allow programs to query, enable, and disable +either specific optimizations or all such optimizations. For example, to +enable all possible optimizations (bearing in mind that some "optimizations" +may actually run more slowly in rare cases): + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + png_uint_32 mask, flags; + + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags | mask); + #endif + +To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ +by itself when calling png_get_asm_flagmask(); similarly for optimizing +only writing. To disable all optimizations: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags & ~mask); + #endif + +To enable or disable only MMX-related features, use png_get_mmx_flagmask() +in place of png_get_asm_flagmask(). The mmx version takes one additional +parameter: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; + int compilerID; + + mask = png_get_mmx_flagmask(selection, &compilerID); + #endif + +On return, compilerID will indicate which version of the MMX assembler +optimizations was compiled. Currently two flavors exist: Microsoft +Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). +On non-x86 platforms or on systems compiled without MMX optimizations, a +value of -1 is used. + +Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return +all valid, settable optimization bits for the version of the library that's +currently in use. In the case of shared (dynamically linked) libraries, +this may include optimizations that did not exist at the time the code was +written and compiled. It is also possible, of course, to enable only known, +specific optimizations; for example: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + png_set_asm_flags(png_ptr, flags); + #endif + +This method would enable only the MMX read-optimizations available at the +time of libpng 1.2.0's release, regardless of whether a later version of +the DLL were actually being used. (Also note that these functions did not +exist in versions older than 1.2.0, so any attempt to run a dynamically +linked app on such an older version would fail.) + +To determine whether the processor supports MMX instructions at all, use +the png_mmx_support() function: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + mmxsupport = png_mmx_support(); + #endif + +It returns -1 if MMX support is not compiled into libpng, 0 if MMX code +is compiled but MMX is not supported by the processor, or 1 if MMX support +is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), +and png_get_asm_flagmask() all may be called without allocating and ini- +tializing any PNG structures (for example, as part of a usage screen or +"about" box). + +The following code can be used to prevent an application from using the +thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK +defined: + +#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ + && defined(PNG_THREAD_UNSAFE_OK) + /* Disable thread-unsafe features of pnggccrd */ + if (png_access_version_number() >= 10200) + { + png_uint_32 mmx_disable_mask = 0; + png_uint_32 asm_flags; + + mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + asm_flags = png_get_asm_flags(png_ptr); + png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); + } +#endif + +For more extensive examples of runtime querying, enabling and disabling +of optimized features, see contrib/gregbook/readpng2.c in the libpng +source-code distribution. + +VII. MNG support + +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. +Libpng can support some of these extensions. To enable them, use the +png_permit_mng_features() function: + + feature_set = png_permit_mng_features(png_ptr, mask) + mask is a png_uint_32 containing the bitwise OR of the + features you want to enable. These include + PNG_FLAG_MNG_EMPTY_PLTE + PNG_FLAG_MNG_FILTER_64 + PNG_ALL_MNG_FEATURES + feature_set is a png_uint_32 that is the bitwise AND of + your mask with the set of MNG features that is + supported by the version of libpng that you are using. + +It is an error to use this function when reading or writing a standalone +PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped +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 +or any other MNG chunks; your application must provide its own support for +them. You may wish to consider using libmng (available at +http://www.libmng.com) instead. + +VIII. Changes to Libpng from version 0.88 + +It should be noted that versions of libpng later than 0.96 are not +distributed by the original libpng author, Guy Schalnat, nor by +Andreas Dilger, who had taken over from Guy during 1996 and 1997, and +distributed versions 0.89 through 0.96, but rather by another member +of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are +still alive and well, but they have moved on to other things. + +The old libpng functions png_read_init(), png_write_init(), +png_info_init(), png_read_destroy(), and png_write_destroy() have been +moved to PNG_INTERNAL in version 0.95 to discourage their use. These +functions will be removed from libpng version 2.0.0. + +The preferred method of creating and initializing the libpng structures is +via the png_create_read_struct(), png_create_write_struct(), and +png_create_info_struct() because they isolate the size of the structures +from the application, allow version error checking, and also allow the +use of custom error handling routines during the initialization, which +the old functions do not. The functions png_read_destroy() and +png_write_destroy() do not actually free the memory that libpng +allocated for these structs, but just reset the data structures, so they +can be used instead of png_destroy_read_struct() and +png_destroy_write_struct() if you feel there is too much system overhead +allocating and freeing the png_struct for each image read. + +Setting the error callbacks via png_set_message_fn() before +png_read_init() as was suggested in libpng-0.88 is no longer supported +because this caused applications that do not use custom error functions +to fail if the png_ptr was not initialized to zero. It is still possible +to set the error callbacks AFTER png_read_init(), or to change them with +png_set_error_fn(), which is essentially the same function, but with a new +name to force compilation errors with applications that try to use the old +method. + +Starting with version 1.0.7, you can find out which version of the library +you are using at run-time: + + png_uint_32 libpng_vn = png_access_version_number(); + +The number libpng_vn is constructed from the major version, minor +version with leading zero, and release number with leading zero, +(e.g., libpng_vn for version 1.0.7 is 10007). + +You can also check which version of png.h you used when compiling your +application: + + png_uint_32 application_vn = PNG_LIBPNG_VER; + +IX. Y2K Compliance in libpng + +May 15, 2007 + +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.2.18 are Y2K compliant. It is my belief that earlier +versions were also Y2K compliant. + +Libpng only has three year fields. One is a 2-byte unsigned integer that +will hold years up to 65535. The other two hold the date in text +format, and will hold years up to 9999. + +The integer is + "png_uint_16 year" in png_time_struct. + +The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + +There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + 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 diff --git a/src/dep/src/irrlicht/libpng/libpng.3 b/src/dep/src/irrlicht/libpng/libpng.3 new file mode 100644 index 0000000..0507b48 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/libpng.3 @@ -0,0 +1,3707 @@ +.TH LIBPNG 3 "May 15, 2007" +.SH NAME +libpng \- Portable Network Graphics (PNG) Reference Library 1.2.18 +.SH SYNOPSIS +\fB +#include \fP + +\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP + +\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP + +\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP + +\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP + +\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP + +\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP + +\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP + +\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP + +\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP + +\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP + +\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP + +\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP + +\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP + +\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP + +\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP + +\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP + +\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP + +\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP + +\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP + +\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP + +\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP + +\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP + +\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP + +\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP + +\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP + +\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fB#if !defined(PNG_1_0_X) png_int_32 png_get_int_32 (png_bytep buf); \fI#endif + +\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP + +\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP + +\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP + +\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP + +\fBpng_byte png_get_rgb_to_gray_status (png_structp png_ptr) png_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP + +\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP + +\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP + +\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP + +\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP + +\fB#if !defined(PNG_1_0_X) png_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP + +\fBpng_uint_32 png_get_uint_31 (png_bytep \fIbuf\fP\fB);\fP + +\fBpng_uint_32 png_get_uint_32 (png_bytep buf); \fI#endif + +\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP + +\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_user_height_max( png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_user_width_max (png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP + +\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP + +\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP + +\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP + +\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP + +\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP + +\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP + +\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP + +\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP + +\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP + +\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP + +\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP + +\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP + +\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP + +\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP + +\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP + +\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fB#if !defined(PNG_1_0_X) png_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP + +\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP + +\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP + +\fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int flags); \fI#endif + +\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP + +\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP + +\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP + +\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP + +\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP + +\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP + +\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP + +\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP + +\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP + +\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP + +\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP + +\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP + +\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_expand_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP + +\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP + +\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP + +\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP + +\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP + +\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP + +\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP + +\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP + +\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP + +\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP + +\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP + +\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP + +\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP + +\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP + +\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP + +\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP + +\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP + +\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP + +\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP + +\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP + +\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP + +\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP + +\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP + +\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP + +\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP + +\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP + +\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP + +\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP + +\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP + +\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP + +\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP + +\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP + +\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP + +\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP + +\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP + +\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP + +\fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP + +\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP + +\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP + +\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP + +\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP + +\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP + +\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP + +\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP + +\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP + +\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP + +\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP + +\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP + +\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP + +.SH DESCRIPTION +The +.I libpng +library supports encoding, decoding, and various manipulations of +the Portable Network Graphics (PNG) format image files. It uses the +.IR zlib(3) +compression library. +Following is a copy of the libpng.txt file that accompanies libpng. +.SH LIBPNG.TXT +libpng.txt - A description on how to use and modify libpng + + libpng version 1.2.18 - May 15, 2007 + Updated and distributed by Glenn Randers-Pehrson + + Copyright (c) 1998-2007 Glenn Randers-Pehrson + For conditions of distribution and use, see copyright + notice in png.h. + + based on: + + libpng 1.0 beta 6 version 0.96 May 28, 1997 + Updated and distributed by Andreas Dilger + Copyright (c) 1996, 1997 Andreas Dilger + + libpng 1.0 beta 2 - version 0.88 January 26, 1996 + For conditions of distribution and use, see copyright + notice in png.h. Copyright (c) 1995, 1996 Guy Eric + Schalnat, Group 42, Inc. + + Updated/rewritten per request in the libpng FAQ + Copyright (c) 1995, 1996 Frank J. T. Wojcik + December 18, 1995 & January 20, 1996 + +.SH I. Introduction + +This file describes how to use and modify the PNG reference library +(known as libpng) for your own use. There are five sections to this +file: introduction, structures, reading, writing, and modification and +configuration notes for various special platforms. In addition to this +file, example.c is a good starting point for using the library, as +it is heavily commented and should include everything most people +will need. We assume that libpng is already installed; see the +INSTALL file for instructions on how to install libpng. + +For examples of libpng usage, see the files "example.c", "pngtest.c", +and the files in the "contrib" directory, all of which are included in the +libpng distribution. + +Libpng was written as a companion to the PNG specification, as a way +of reducing the amount of time and effort it takes to support the PNG +file format in application programs. + +The PNG specification (second edition), November 2003, is available as +a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at + + +The PNG-1.0 specification is available +as RFC 2083 and as a +W3C Recommendation . Some +additional chunks are described in the special-purpose public chunks +documents at . + +Other information +about PNG, and the latest version of libpng, can be found at the PNG home +page, . + +Most users will not have to modify the library significantly; advanced +users may want to modify it more. All attempts were made to make it as +complete as possible, while keeping the code easy to understand. +Currently, this library only supports C. Support for other languages +is being considered. + +Libpng has been designed to handle multiple sessions at one time, +to be easily modifiable, to be portable to the vast majority of +machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy +to use. The ultimate goal of libpng is to promote the acceptance of +the PNG file format in whatever way possible. While there is still +work to be done (see the TODO file), libpng should cover the +majority of the needs of its users. + +Libpng uses zlib for its compression and decompression of PNG files. +Further information about zlib, and the latest version of zlib, can +be found at the zlib home page, . +The zlib compression utility is a general purpose utility that is +useful for more than PNG files, and can be used without libpng. +See the documentation delivered with zlib for more details. +You can usually find the source files for the zlib utility wherever you +find the libpng source files. + +Libpng is thread safe, provided the threads are using different +instances of the structures. Each thread should have its own +png_struct and png_info instances, and thus its own image. +Libpng does not protect itself against two threads using the +same instance of a structure. Note: thread safety may be defeated +by use of some of the MMX assembler code in pnggccrd.c, which is only +compiled when the user defines PNG_THREAD_UNSAFE_OK. + +.SH II. Structures + +There are two main structures that are important to libpng, png_struct +and png_info. The first, png_struct, is an internal structure that +will not, for the most part, be used by a user except as the first +variable passed to every libpng function call. + +The png_info structure is designed to provide information about the +PNG file. At one time, the fields of png_info were intended to be +directly accessible to the user. However, this tended to cause problems +with applications using dynamically loaded libraries, and as a result +a set of interface functions for png_info (the png_get_*() and png_set_*() +functions) was developed. The fields of png_info are still available for +older applications, but it is suggested that applications use the new +interfaces if at all possible. + +Applications that do make direct access to the members of png_struct (except +for png_ptr->jmpbuf) must be recompiled whenever the library is updated, +and applications that make direct access to the members of png_info must +be recompiled if they were compiled or loaded with libpng version 1.0.6, +in which the members were in a different order. In version 1.0.7, the +members of the png_info structure reverted to the old order, as they were +in versions 0.97c through 1.0.5. Starting with version 2.0.0, both +structures are going to be hidden, and the contents of the structures will +only be accessible through the png_get/png_set functions. + +The png.h header file is an invaluable reference for programming with libpng. +And while I'm on the topic, make sure you include the libpng header file: + +#include + +.SH III. Reading + +We'll now walk you through the possible functions to call when reading +in a PNG file sequentially, briefly explaining the syntax and purpose +of each one. See example.c and png.h for more detail. While +progressive reading is covered in the next section, you will still +need some of the functions discussed in this section to read a PNG +file. + +.SS Setup + +You will want to do the I/O initialization(*) before you get into libpng, +so if it doesn't work, you don't have much to undo. Of course, you +will also want to insure that you are, in fact, dealing with a PNG +file. Libpng provides a simple check to see if a file is a PNG file. +To use it, pass in the first 1 to 8 bytes of the file to the function +png_sig_cmp(), and it will return 0 if the bytes match the corresponding +bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes +you pass in, the greater the accuracy of the prediction. + +If you are intending to keep the file pointer open for use in libpng, +you must ensure you don't read more than 8 bytes from the beginning +of the file, and you also have to make a call to png_set_sig_bytes_read() +with the number of bytes you read from the beginning. Libpng will +then only check the bytes (if any) that your program didn't read. + +(*): If you are not using the standard I/O functions, you will need +to replace them with custom functions. See the discussion under +Customizing libpng. + + + FILE *fp = fopen(file_name, "rb"); + if (!fp) + { + return (ERROR); + } + fread(header, 1, number, fp); + is_png = !png_sig_cmp(header, 0, number); + if (!is_png) + { + return (NOT_PNG); + } + + +Next, png_struct and png_info need to be allocated and initialized. In +order to ensure that the size of these structures is correct even with a +dynamically linked libpng, there are functions to initialize and +allocate the structures. We also pass the library version, optional +pointers to error handling functions, and a pointer to a data struct for +use by the error functions, if necessary (the pointer and functions can +be NULL if the default error handlers are to be used). See the section +on Changes to Libpng below regarding the old initialization functions. +The structure allocation functions quietly return NULL if they fail to +create the structure, so your application should check for that. + + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, + (png_infopp)NULL, (png_infopp)NULL); + return (ERROR); + } + + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_read_struct_2() instead of png_create_read_struct(): + + png_structp png_ptr = png_create_read_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +The error handling routines passed to png_create_read_struct() +and the memory alloc/free routines passed to png_create_struct_2() +are only necessary if you are not using the libpng supplied error +handling and memory alloc/free functions. + +When libpng encounters an error, it expects to longjmp back +to your routine. Therefore, you will need to call setjmp and pass +your png_jmpbuf(png_ptr). If you read the file from different +routines, you will need to update the jmpbuf field every time you enter +a new routine that will call a png_*() function. + +See your documentation of setjmp/longjmp for your compiler for more +information on setjmp/longjmp. See the discussion on libpng error +handling in the Customizing Libpng section below for more information +on the libpng error handling. If an error occurs, and libpng longjmp's +back to your setjmp, you will want to call png_destroy_read_struct() to +free any memory. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + fclose(fp); + return (ERROR); + } + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the input code. The default for libpng is to +use the C function fread(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. If you wish to handle reading data in another +way, you need not call the png_init_io() function, but you must then +implement the libpng I/O methods discussed in the Customizing Libpng +section below. + + png_init_io(png_ptr, fp); + +If you had previously opened the file and read any of the signature from +the beginning in order to see if this was a PNG file, you need to let +libpng know that there are some bytes missing from the start of the file. + + png_set_sig_bytes(png_ptr, number); + +.SS Setting up callback code + +You can set up a callback function to handle any unknown chunks in the +input stream. You must supply the function + + read_chunk_callback(png_ptr ptr, + png_unknown_chunkp chunk); + { + /* The unknown chunk structure contains your + chunk data: */ + png_byte name[5]; + png_byte *data; + png_size_t size; + /* Note that libpng has already taken care of + the CRC handling */ + + /* put your code here. Return one of the + following: */ + + return (-n); /* chunk had an error */ + return (0); /* did not recognize */ + return (n); /* success */ + } + +(You can give your function another name that you like instead of +"read_chunk_callback") + +To inform libpng about your function, use + + png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, + read_chunk_callback); + +This names not only the callback function, but also a user pointer that +you can retrieve with + + png_get_user_chunk_ptr(png_ptr); + +At this point, you can set up a callback function that will be +called after each row has been read, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void read_row_callback(png_ptr ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "read_row_callback") + +To inform libpng about your function, use + + png_set_read_status_fn(png_ptr, read_row_callback); + +.SS Width and height limits + +The PNG specification allows the width and height of an image to be as +large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. +Since very few applications really need to process such large images, +we have imposed an arbitrary 1-million limit on rows and columns. +Larger images will be rejected immediately with a png_error() call. If +you wish to override this limit, you can use + + png_set_user_limits(png_ptr, width_max, height_max); + +to set your own limits, or use width_max = height_max = 0x7fffffffL +to allow all valid dimensions (libpng may reject some very large images +anyway because of potential buffer overflow conditions). + +You should put this statement after you create the PNG structure and +before calling png_read_info(), png_read_png(), or png_process_data(). +If you need to retrieve the limits that are being applied, use + + width_max = png_get_user_width_max(png_ptr); + height_max = png_get_user_height_max(png_ptr); + +.SS Unknown-chunk handling + +Now you get to set the way the library processes unknown chunks in the +input PNG stream. Both known and unknown chunks will be read. Normal +behavior is that known chunks will be parsed into information in +various info_ptr members; unknown chunks will be discarded. To change +this, you can call: + + png_set_keep_unknown_chunks(png_ptr, keep, + chunk_list, num_chunks); + keep - 0: do not handle as unknown + 1: do not keep + 2: keep only if safe-to-copy + 3: keep even if unsafe-to-copy + You can use these definitions: + PNG_HANDLE_CHUNK_AS_DEFAULT 0 + PNG_HANDLE_CHUNK_NEVER 1 + PNG_HANDLE_CHUNK_IF_SAFE 2 + PNG_HANDLE_CHUNK_ALWAYS 3 + chunk_list - list of chunks affected (a byte string, + five bytes per chunk, NULL or '\0' if + num_chunks is 0) + num_chunks - number of chunks affected; if 0, all + unknown chunks are affected. If nonzero, + only the chunks in the list are affected + +Unknown chunks declared in this way will be saved as raw data onto a +list of png_unknown_chunk structures. If a chunk that is normally +known to libpng is named in the list, it will be handled as unknown, +according to the "keep" directive. If a chunk is named in successive +instances of png_set_keep_unknown_chunks(), the final instance will +take precedence. The IHDR and IEND chunks should not be named in +chunk_list; if they are, libpng will process them normally anyway. + +.SS The high-level read interface + +At this point there are two ways to proceed; through the high-level +read interface, or through a sequence of low-level read operations. +You can use the high-level interface if (a) you are willing to read +the entire image into memory, and (b) the input transformations +you want to do are limited to the following set: + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to + 8 bits + PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel + PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit + samples to bytes + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_EXPAND Perform set_expand() + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + +(This excludes setting a background color, doing gamma transformation, +dithering, and setting filler.) If this is the case, simply do this: + + png_read_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the bitwise OR of +some set of transformation flags. This call is equivalent to png_read_info(), +followed the set of transformations indicated by the transform mask, +then png_read_image(), and finally png_read_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future input transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_read_png(). + +After you have called png_read_png(), you can retrieve the image data +with + + row_pointers = png_get_rows(png_ptr, info_ptr); + +where row_pointers is an array of pointers to the pixel data for each row: + + png_bytep row_pointers[height]; + +If you know your image size and pixel size ahead of time, you can allocate +row_pointers prior to calling png_read_png() with + + if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) + png_error (png_ptr, + "Image is too tall to process in memory"); + if (width > PNG_UINT_32_MAX/pixel_size) + png_error (png_ptr, + "Image is too wide to process in memory"); + row_pointers = png_malloc(png_ptr, + height*png_sizeof(png_bytep)); + for (int i=0; i) and +png_get_(png_ptr, info_ptr, ...) functions return non-zero if the +data has been read, or zero if it is missing. The parameters to the +png_get_ are set directly if they are simple data types, or a pointer +into the info_ptr is returned for any complex types. + + png_get_PLTE(png_ptr, info_ptr, &palette, + &num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_get_gAMA(png_ptr, info_ptr, &gamma); + gamma - the gamma the file is written + at (PNG_INFO_gAMA) + + png_get_sRGB(png_ptr, info_ptr, &srgb_intent); + srgb_intent - the rendering intent (PNG_INFO_sRGB) + The presence of the sRGB chunk + means that the pixel data is in the + sRGB color space. This chunk also + implies specific values of gAMA and + cHRM. + + png_get_iCCP(png_ptr, info_ptr, &name, + &compression_type, &profile, &proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, + red, green, and blue channels, + whichever are appropriate for the + given color type (png_color_16) + + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, + &trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_get_hIST(png_ptr, info_ptr, &hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_get_tIME(png_ptr, info_ptr, &mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_get_bKGD(png_ptr, info_ptr, &background); + background - background color (PNG_VALID_bKGD) + valid 16-bit red, green and blue + values, regardless of color_type + + num_comments = png_get_text(png_ptr, info_ptr, + &text_ptr, &num_text); + num_comments - number of comments + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (empty + string for unknown). + text_ptr[i].lang_key - keyword in UTF-8 + (empty string for unknown). + num_text - number of comments (same as + num_comments; you can put NULL here + to avoid the duplication) + Note while png_set_text() will accept text, language, + and translated keywords that can be NULL pointers, the + structure returned by png_get_text will always contain + regular zero-terminated C strings. They might be + empty strings but they will never be NULL pointers. + + num_spalettes = png_get_sPLT(png_ptr, info_ptr, + &palette_ptr); + palette_ptr - array of palette structures holding + contents of one or more sPLT chunks + read. + num_spalettes - number of sPLT chunks read. + + png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, + &unit_type); + offset_x - positive offset from the left edge + of the screen + offset_y - positive offset from the top edge + of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, + &unit_type); + res_x - pixels/unit physical resolution in + x direction + res_y - pixels/unit physical resolution in + x direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_get_sCAL(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, + &height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + num_unknown_chunks = png_get_unknown_chunks(png_ptr, + info_ptr, &unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position of chunk in file + + The value of "i" corresponds to the order in which the + chunks were read from the PNG file or inserted with the + png_set_unknown_chunks() function. + +The data from the pHYs chunk can be retrieved in several convenient +forms: + + res_x = png_get_x_pixels_per_meter(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_meter(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_meter(png_ptr, + info_ptr) + res_x = png_get_x_pixels_per_inch(png_ptr, + info_ptr) + res_y = png_get_y_pixels_per_inch(png_ptr, + info_ptr) + res_x_and_y = png_get_pixels_per_inch(png_ptr, + info_ptr) + aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, + info_ptr) + + (Each of these returns 0 [signifying "unknown"] if + the data is not present or if res_x is 0; + res_x_and_y is 0 if res_x != res_y) + +The data from the oFFs chunk can be retrieved in several convenient +forms: + + x_offset = png_get_x_offset_microns(png_ptr, info_ptr); + y_offset = png_get_y_offset_microns(png_ptr, info_ptr); + x_offset = png_get_x_offset_inches(png_ptr, info_ptr); + y_offset = png_get_y_offset_inches(png_ptr, info_ptr); + + (Each of these returns 0 [signifying "unknown" if both + x and y are 0] if the data is not present or if the + chunk is present but the unit is the pixel) + +For more information, see the png_info definition in png.h and the +PNG specification for chunk contents. Be careful with trusting +rowbytes, as some of the transformations could increase the space +needed to hold a row (expand, filler, gray_to_rgb, etc.). +See png_read_update_info(), below. + +A quick word about text_ptr and num_text. PNG stores comments in +keyword/text pairs, one pair per chunk, with no limit on the number +of text chunks, and a 2^31 byte limit on their size. While there are +suggested keywords, there is no requirement to restrict the use to these +strings. It is strongly suggested that keywords and text be sensible +to humans (that's the point), so don't use abbreviations. Non-printing +symbols are not allowed. See the PNG specification for more details. +There is also no requirement to have text after the keyword. + +Keywords should be limited to 79 Latin-1 characters without leading or +trailing spaces, but non-consecutive spaces are allowed within the +keyword. It is possible to have the same keyword any number of times. +The text_ptr is an array of png_text structures, each holding a +pointer to a language string, a pointer to a keyword and a pointer to +a text string. The text string, language code, and translated +keyword may be empty or NULL pointers. The keyword/text +pairs are put into the array in the order that they are received. +However, some or all of the text chunks may be after the image, so, to +make sure you have read all the text chunks, don't mess with these +until after you read the stuff after the image. This will be +mentioned again below in the discussion that goes with png_read_end(). + +.SS Input transformations + +After you've read the header information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +The colors used for the background and transparency values should be +supplied in the same format/depth as the current image data. They +are stored in the same format/depth as the image data in a bKGD or tRNS +chunk, so this is what libpng expects for this data. The colors are +transformed to keep in sync with the image data when an application +calls the png_read_update_info() routine (see below). + +Data will be decoded into the supplied row buffers packed into bytes +unless the library has been told to transform it into another format. +For example, 4 bit/pixel paletted or grayscale data will be returned +2 pixels/byte with the leftmost pixel in the high-order bits of the +byte, unless png_set_packing() is called. 8-bit RGB data will be stored +in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() +is called to insert filler bytes, either before or after each RGB triplet. +16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant +byte of the color value first, unless png_set_strip_16() is called to +transform it to regular RGB RGB triplets, or png_set_filler() or +png_set_add alpha() is called to insert filler bytes, either before or +after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can +be modified with +png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). + +The following code transforms grayscale images of less than 8 to 8 bits, +changes paletted images to RGB, and adds a full alpha channel if there is +transparency information in a tRNS chunk. This is most useful on +grayscale images with bit depths of 2 or 4 or if there is a multiple-image +viewing application that wishes to treat all images in the same way. + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY && + bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); + + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); + +These three functions are actually aliases for png_set_expand(), added +in libpng version 1.0.4, with the function names expanded to improve code +readability. In some future version they may actually do different +things. + +As of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was +added. It expands the sample depth without changing tRNS to alpha. +At the same time, png_set_gray_1_2_4_to_8() was deprecated, and it +will be removed from a future version. + +PNG can have files with 16 bits per channel. If you only can handle +8 bits per channel, this will strip the pixels down to 8 bit. + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + +If, for some reason, you don't need the alpha channel on an image, +and you want to remove it rather than combining it with the background +(but the image author certainly had in mind that you *would* combine +it with the background, so that's what you should probably do): + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); + +In PNG files, the alpha channel in an image +is the level of opacity. If you need the alpha channel in an image to +be the level of transparency instead of opacity, you can invert the +alpha channel (or the tRNS chunk data) after it's read, so that 0 is +fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit +images) is fully transparent, with + + png_set_invert_alpha(png_ptr); + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit +files. This code expands to 1 pixel per byte without changing the +values of the pixels: + + if (bit_depth < 8) + png_set_packing(png_ptr); + +PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels +stored in a PNG image have been "scaled" or "shifted" up to the next +higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to +8 bits/sample in the range [0, 255]). However, it is also possible to +convert the PNG pixel data back to the original bit depth of the image. +This call reduces the pixels back down to the original bit depth: + + png_color_8p sig_bit; + + if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) + png_set_shift(png_ptr, sig_bit); + +PNG files store 3-color pixels in red, green, blue order. This code +changes the storage of the pixels to blue, green, red: + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + +PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them +into 4 or 8 bytes for windowing systems that need them in this format: + + if (color_type == PNG_COLOR_TYPE_RGB) + png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); + +where "filler" is the 8 or 16-bit number to fill with, and the location is +either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether +you want the filler before the RGB or after. This transformation +does not affect images that already have full alpha channels. To add an +opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which +will generate RGBA pixels. + +Note that png_set_filler() does not change the color type. If you want +to do that, you can add a true alpha channel with + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY) + png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); + +where "filler" contains the alpha value to assign to each pixel. +This function was added in libpng-1.2.7. + +If you are reading an image with an alpha channel, and you need the +data as ARGB instead of the normal PNG format RGBA: + + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_swap_alpha(png_ptr); + +For some uses, you may want a grayscale image to be represented as +RGB. This code will do that conversion: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + +Conversely, you can convert an RGB or RGBA image to grayscale or grayscale +with alpha. + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_rgb_to_gray_fixed(png_ptr, error_action, + int red_weight, int green_weight); + + error_action = 1: silently do the conversion + error_action = 2: issue a warning if the original + image has any pixel where + red != green or red != blue + error_action = 3: issue an error and abort the + conversion if the original + image has any pixel where + red != green or red != blue + + red_weight: weight of red component times 100000 + green_weight: weight of green component times 100000 + If either weight is negative, default + weights (21268, 71514) are used. + +If you have set error_action = 1 or 2, you can +later check whether the image really was gray, after processing +the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. +It will return a png_byte that is zero if the image was gray or +1 if there were any non-gray pixels. bKGD and sBIT data +will be silently converted to grayscale, using the green channel +data, regardless of the error_action setting. + +With red_weight+green_weight<=100000, +the normalized graylevel is computed: + + int rw = red_weight * 65536; + int gw = green_weight * 65536; + int bw = 65536 - (rw + gw); + gray = (rw*red + gw*green + bw*blue)/65536; + +The default values approximate those recommended in the Charles +Poynton's Color FAQ, +Copyright (c) 1998-01-04 Charles Poynton + + Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + +Libpng approximates this with + + Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + +which can be expressed with integers as + + Y = (6969 * R + 23434 * G + 2365 * B)/32768 + +The calculation is done in a linear colorspace, if the image gamma +is known. + +If you have a grayscale and you are using png_set_expand_depth(), +png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to +a higher bit-depth, you must either supply the background color as a gray +value at the original file bit-depth (need_expand = 1) or else supply the +background color as an RGB triplet at the final, expanded bit depth +(need_expand = 0). Similarly, if you are reading a paletted image, you +must either supply the background color as a palette index (need_expand = 1) +or as an RGB triplet that may or may not be in the palette (need_expand = 0). + + png_color_16 my_background; + png_color_16p image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + +The png_set_background() function tells libpng to composite images +with alpha or simple transparency against the supplied background +color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), +you may use this color, or supply another color more suitable for +the current display (e.g., the background color from a web page). You +need to tell libpng whether the color is in the gamma space of the +display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file +(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one +that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't +know why anyone would use this, but it's here). + +To properly display PNG images on any kind of system, the application needs +to know what the display gamma is. Ideally, the user will know this, and +the application will allow them to set it. One method of allowing the user +to set the display gamma separately for each system is to check for a +SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be +correctly set. + +Note that display_gamma is the overall gamma correction required to produce +pleasing results, which depends on the lighting conditions in the surrounding +environment. In a dim or brightly lit room, no compensation other than +the physical gamma exponent of the monitor is needed, while in a dark room +a slightly smaller exponent is better. + + double gamma, screen_gamma; + + if (/* We have a user-defined screen + gamma value */) + { + screen_gamma = user_defined_screen_gamma; + } + /* One way that applications can share the same + screen gamma value */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) + != NULL) + { + screen_gamma = (double)atof(gamma_str); + } + /* If we don't have another value */ + else + { + screen_gamma = 2.2; /* A good guess for a + PC monitor in a bright office or a dim room */ + screen_gamma = 2.0; /* A good guess for a + PC monitor in a dark room */ + screen_gamma = 1.7 or 1.0; /* A good + guess for Mac systems */ + } + +The png_set_gamma() function handles gamma transformations of the data. +Pass both the file gamma and the current screen_gamma. If the file does +not have a gamma value, you can pass one anyway if you have an idea what +it is (usually 0.45455 is a good guess for GIF images on PCs). Note +that file gammas are inverted from screen gammas. See the discussions +on gamma in the PNG specification for an excellent description of what +gamma is, and why all applications should support it. It is strongly +recommended that PNG viewers support gamma correction. + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, screen_gamma, gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + +If you need to reduce an RGB file to a paletted file, or if a paletted +file has more entries then will fit on your screen, png_set_dither() +will do that. Note that this is a simple match dither that merely +finds the closest color available. This should work fairly well with +optimized palettes, and fairly badly with linear color cubes. If you +pass a palette that is larger then maximum_colors, the file will +reduce the number of colors in the palette so it will fit into +maximum_colors. If there is a histogram, it will use it to make +more intelligent choices when reducing the palette. If there is no +histogram, it may not do as good a job. + + if (color_type & PNG_COLOR_MASK_COLOR) + { + if (png_get_valid(png_ptr, info_ptr, + PNG_INFO_PLTE)) + { + png_uint_16p histogram = NULL; + + png_get_hIST(png_ptr, info_ptr, + &histogram); + png_set_dither(png_ptr, palette, num_palette, + max_screen_colors, histogram, 1); + } + else + { + png_color std_color_cube[MAX_SCREEN_COLORS] = + { ... colors ... }; + + png_set_dither(png_ptr, std_color_cube, + MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, + NULL,0); + } + } + +PNG files describe monochrome as black being zero and white being one. +The following code will reverse this (make black be one and white be +zero): + + if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) + png_set_invert_mono(png_ptr); + +This function can also be used to invert grayscale and gray-alpha images: + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_invert_mono(png_ptr); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code changes the storage to the +other way (little-endian, i.e. least significant bits first, the +way PCs store them): + + if (bit_depth == 16) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_read_user_transform_fn(png_ptr, + read_transform_fn); + +You must supply the function + + void read_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +after all of the other transformations have been processed. + +You can also set up a pointer to a user structure for use by your +callback function, and you can inform libpng that your transform +function will change the number of channels or bit depth with the +function + + png_set_user_transform_info(png_ptr, user_ptr, + user_depth, user_channels); + +The user's application, not libpng, is responsible for allocating and +freeing any memory required for the user structure. + +You can retrieve the pointer via the function +png_get_user_transform_ptr(). For example: + + voidp read_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +The last thing to handle is interlacing; this is covered in detail below, +but you must call the function here if you want libpng to handle expansion +of the interlaced image. + + number_of_passes = png_set_interlace_handling(png_ptr); + +After setting the transformations, libpng can update your png_info +structure to reflect any transformations you've requested with this +call. This is most useful to update the info structure's rowbytes +field so you can use it to allocate your image memory. This function +will also update your palette with the correct screen_gamma and +background if these have been given with the calls above. + + png_read_update_info(png_ptr, info_ptr); + +After you call png_read_update_info(), you can allocate any +memory you need to hold the image. The row data is simply +raw byte data for all forms of images. As the actual allocation +varies among applications, no example will be given. If you +are allocating one large chunk, you will need to build an +array of pointers to each row, as it will be needed for some +of the functions below. + +.SS Reading image data + +After you've allocated memory, you can read the image data. +The simplest way to do this is in one function call. If you are +allocating enough memory to hold the whole image, you can just +call png_read_image() and libpng will read in all the image data +and put it in the memory area supplied. You will need to pass in +an array of pointers to each row. + +This function automatically handles interlacing, so you don't need +to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_read_rows(). + + png_read_image(png_ptr, row_pointers); + +where row_pointers is: + + png_bytep row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to read in the whole image at once, you can +use png_read_rows() instead. If there is no interlacing (check +interlace_type == PNG_INTERLACE_NONE), this is simple: + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +where row_pointers is the same as in the png_read_image() call. + +If you are doing this just one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + png_read_row(png_ptr, row_pointer, NULL); + +If the file is interlaced (interlace_type != 0 in the IHDR chunk), things +get somewhat harder. The only current (PNG Specification version 1.2) +interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) +is a somewhat complicated 2D interlace scheme, known as Adam7, that +breaks down an image into seven smaller images of varying size, based +on an 8x8 grid. + +libpng can fill out those images or it can give them to you "as is". +If you want them filled out, there are two ways to do that. The one +mentioned in the PNG specification is to expand each pixel to cover +those pixels that have not been read yet (the "rectangle" method). +This results in a blocky image for the first pass, which gradually +smooths out as more pixels are read. The other method is the "sparkle" +method, where pixels are drawn only in their final locations, with the +rest of the image remaining whatever colors they were initialized to +before the start of the read. The first method usually looks better, +but tends to be slower, as there are more pixels to put in the rows. + +If you don't want libpng to handle the interlacing details, just call +png_read_rows() seven times to read in all seven images. Each of the +images is a valid image by itself, or they can all be combined on an +8x8 grid to form a single image (although if you intend to combine them +you would be far better off using the libpng interlace handling). + +The first pass will return an image 1/8 as wide as the entire image +(every 8th column starting in column 0) and 1/8 as high as the original +(every 8th row starting in row 0), the second will be 1/8 as wide +(starting in column 4) and 1/8 as high (also starting in row 0). The +third pass will be 1/4 as wide (every 4th pixel starting in column 0) and +1/8 as high (every 8th row starting in row 4), and the fourth pass will +be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, +and every 4th row starting in row 0). The fifth pass will return an +image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), +while the sixth pass will be 1/2 as wide and 1/2 as high as the original +(starting in column 1 and row 0). The seventh and final pass will be as +wide as the original, and 1/2 as high, containing all of the odd +numbered scanlines. Phew! + +If you want libpng to expand the images, call this before calling +png_start_read_image() or png_read_update_info(): + + if (interlace_type == PNG_INTERLACE_ADAM7) + number_of_passes + = png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. +This function can be called even if the file is not interlaced, +where it will return one pass. + +If you are not going to display the image after each pass, but are +going to wait until the entire image is read in, use the sparkle +effect. This effect is faster and the end result of either method +is exactly the same. If you are planning on displaying the image +after each pass, the "rectangle" effect is generally considered the +better looking one. + +If you only want the "sparkle" effect, just call png_read_rows() as +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 +rows between calls. You can change the locations of the data, just +not the data. Each pass only writes the pixels appropriate for that +pass, and assumes the data from previous passes is still valid. + + png_read_rows(png_ptr, row_pointers, NULL, + number_of_rows); + +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 +the second parameter NULL. + + png_read_rows(png_ptr, NULL, row_pointers, + number_of_rows); + +.SS Finishing a sequential read + +After you are finished reading the image through the +low-level interface, you can finish reading the file. If you are +interested in comments or time, which may be stored either before or +after the image data, you should pass the separate png_info struct if +you want to keep the comments from before and after the image +separate. If you are not interested, you can pass NULL. + + png_read_end(png_ptr, end_info); + +When you are done, you can free all memory allocated by libpng like this: + + png_destroy_read_struct(&png_ptr, &info_ptr, + &end_info); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the bitwise OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +This function only affects data that has already been allocated. +You can call this function after reading the PNG data but before calling +any png_set_*() functions, to control whether the user or the png_set_*() +function is responsible for freeing any existing data that might be present, +and again after the png_set_*() functions to control whether the user +or png_destroy_*() is supposed to free the data. When the user assumes +responsibility for libpng-allocated data, the application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated your row_pointers in a single block, as suggested above in +the description of the high level read interface, you must not transfer +responsibility for freeing it to the png_set_rows or png_read_destroy function, +because they would also try to free the individual row_pointers[i]. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. + +The png_free_data() function will turn off the "valid" flag for anything +it frees. If you need to turn the flag off for a chunk that was freed by your +application instead of by libpng, you can use + + png_set_invalid(png_ptr, info_ptr, mask); + mask - identifies the chunks to be made invalid, + containing the bitwise OR of one or + more of + PNG_INFO_gAMA, PNG_INFO_sBIT, + PNG_INFO_cHRM, PNG_INFO_PLTE, + PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_hIST, PNG_INFO_pHYs, + PNG_INFO_oFFs, PNG_INFO_tIME, + PNG_INFO_pCAL, PNG_INFO_sRGB, + PNG_INFO_iCCP, PNG_INFO_sPLT, + PNG_INFO_sCAL, PNG_INFO_IDAT + +For a more compact example of reading a PNG image, see the file example.c. + +.SS Reading PNG files progressively + +The progressive reader is slightly different then the non-progressive +reader. Instead of calling png_read_info(), png_read_rows(), and +png_read_end(), you make one call to png_process_data(), which calls +callbacks when it has the info, a row, or the end of the image. You +set up these callbacks with png_set_progressive_read_fn(). You don't +have to worry about the input/output functions of libpng, as you are +giving the library the data directly in png_process_data(). I will +assume that you have read the section on reading PNG files above, +so I will only highlight the differences (although I will show +all of the code). + +png_structp png_ptr; +png_infop info_ptr; + + /* An example code fragment of how you would + initialize the progressive reader in your + application. */ + int + initialize_png_reader() + { + png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, + (png_infopp)NULL); + return (ERROR); + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new. You can provide functions + to be called when the header info is valid, + when each row is completed, and when the image + is finished. If you aren't using all functions, + you can specify NULL parameters. Even when all + three functions are NULL, you need to call + png_set_progressive_read_fn(). You can use + any struct as the user_ptr (cast to a void pointer + for the function call), and retrieve the pointer + from inside the callbacks using the function + + png_get_progressive_ptr(png_ptr); + + which will return a void pointer, which you have + to cast appropriately. + */ + png_set_progressive_read_fn(png_ptr, (void *)user_ptr, + info_callback, row_callback, end_callback); + + return 0; + } + + /* A code fragment that you call as you receive blocks + of data */ + int + process_data(png_bytep buffer, png_uint_32 length) + { + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, + (png_infopp)NULL); + return (ERROR); + } + + /* This one's new also. Simply give it a chunk + of data from the file stream (in order, of + course). On machines with segmented memory + models machines, don't give it any more than + 64K. The library seems to run fine with sizes + of 4K. Although you can give it much less if + necessary (I assume you can give it chunks of + 1 byte, I haven't tried less then 256 bytes + yet). When this function returns, you may + want to display any rows that were generated + in the row callback if you don't already do + so there. + */ + png_process_data(png_ptr, info_ptr, buffer, length); + return 0; + } + + /* This function is called (as set by + png_set_progressive_read_fn() above) when enough data + has been supplied so all of the header has been + read. + */ + void + info_callback(png_structp png_ptr, png_infop info) + { + /* Do any setup here, including setting any of + the transformations mentioned in the Reading + PNG files section. For now, you _must_ call + either png_start_read_image() or + png_read_update_info() after all the + transformations are set (even if you don't set + any). You may start getting rows before + png_process_data() returns, so this is your + last chance to prepare for that. + */ + } + + /* This function is called when each row of image + data is complete */ + void + row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) + { + /* If the image is interlaced, and you turned + on the interlace handler, this function will + be called for every row in every pass. Some + of these rows will not be changed from the + previous pass. When the row is not changed, + the new_row variable will be NULL. The rows + and passes are called in order, so you don't + really need the row_num and pass, but I'm + supplying them because it may make your life + easier. + + For the non-NULL rows of interlaced images, + you must call png_progressive_combine_row() + passing in the row and the old row. You can + call this function for NULL rows (it will just + return) and for non-interlaced images (it just + does the memcpy for you) if it will make the + code easier. Thus, you can just do this for + all cases: + */ + + png_progressive_combine_row(png_ptr, old_row, + new_row); + + /* where old_row is what was displayed for + previously for the row. Note that the first + pass (pass == 0, really) will completely cover + the old row, so the rows do not have to be + initialized. After the first pass (and only + for interlaced images), you will have to pass + the current row, and the function will combine + the old row and the new row. + */ + } + + void + end_callback(png_structp png_ptr, png_infop info) + { + /* This function is called after the whole image + has been read, including any chunks after the + image (up to and including the IEND). You + will usually have the same info chunk as you + had in the header, although some data may have + been added to the comments and time fields. + + Most people won't do much here, perhaps setting + a flag that marks the image as finished. + */ + } + + + +.SH IV. Writing + +Much of this is very similar to reading. However, everything of +importance is repeated here, so you won't have to constantly look +back up in the reading section to understand writing. + +.SS Setup + +You will want to do the I/O initialization before you get into libpng, +so if it doesn't work, you don't have anything to undo. If you are not +using the standard I/O functions, you will need to replace them with +custom writing functions. See the discussion under Customizing libpng. + + FILE *fp = fopen(file_name, "wb"); + if (!fp) + { + return (ERROR); + } + +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 +on the stack, unless you have stack space to spare. Of course, you +will want to check if they return NULL. If you are also reading, +you won't want to name your read structure and your write structure +both "png_ptr"; you can call them anything you like, such as +"read_ptr" and "write_ptr". Look at pngtest.c, for example. + + png_structp png_ptr = png_create_write_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn); + if (!png_ptr) + return (ERROR); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_write_struct(&png_ptr, + (png_infopp)NULL); + return (ERROR); + } + +If you want to use your own memory allocation routines, +define PNG_USER_MEM_SUPPORTED and use +png_create_write_struct_2() instead of png_create_write_struct(): + + png_structp png_ptr = png_create_write_struct_2 + (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, + user_error_fn, user_warning_fn, (png_voidp) + user_mem_ptr, user_malloc_fn, user_free_fn); + +After you have these structures, you will need to set up the +error handling. When libpng encounters an error, it expects to +longjmp() back to your routine. Therefore, you will need to call +setjmp() and pass the png_jmpbuf(png_ptr). If you +write the file from different routines, you will need to update +the png_jmpbuf(png_ptr) every time you enter a new routine that will +call a png_*() function. See your documentation of setjmp/longjmp +for your compiler for more information on setjmp/longjmp. See +the discussion on libpng error handling in the Customizing Libpng +section below for more information on the libpng error handling. + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (ERROR); + } + ... + return; + +If you would rather avoid the complexity of setjmp/longjmp issues, +you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case +errors will result in a call to PNG_ABORT() which defaults to abort(). + +Now you need to set up the output code. The default for libpng is to +use the C function fwrite(). If you use this, you will need to pass a +valid FILE * in the function png_init_io(). Be sure that the file is +opened in binary mode. Again, if you wish to handle writing data in +another way, see the discussion on libpng I/O handling in the Customizing +Libpng section below. + + png_init_io(png_ptr, fp); + +If you are embedding your PNG into a datastream such as MNG, and don't +want libpng to write the 8-byte signature, or if you have already +written the signature in your application, use + + png_set_sig_bytes(png_ptr, 8); + +to inform libpng that it should not write a signature. + +.SS Write callbacks + +At this point, you can set up a callback function that will be +called after each row has been written, which you can use to control +a progress meter or the like. It's demonstrated in pngtest.c. +You must supply a function + + void write_row_callback(png_ptr, png_uint_32 row, + int pass); + { + /* put your code here */ + } + +(You can give it another name that you like instead of "write_row_callback") + +To inform libpng about your function, use + + png_set_write_status_fn(png_ptr, write_row_callback); + +You now have the option of modifying how the compression library will +run. The following functions are mainly for testing, but may be useful +in some cases, like if you need to write PNG files extremely fast and +are willing to give up some compression, or if you want to get the +maximum possible compression at the expense of slower writing. If you +have no special needs in this area, let the library do what it wants by +not calling this function at all, as it has been tuned to deliver a good +speed/compression ratio. The second parameter to png_set_filter() is +the filter method, for which the only valid values are 0 (as of the +July 1999 PNG specification, version 1.2) or 64 (if you are writing +a PNG datastream that is to be embedded in a MNG datastream). The third +parameter is a flag that indicates which filter type(s) are to be tested +for each scanline. See the PNG specification for details on the specific filter +types. + + + /* turn on or off filtering, and/or choose + specific filters. You can use either a single + PNG_FILTER_VALUE_NAME or the bitwise OR of one + or more PNG_FILTER_NAME masks. */ + png_set_filter(png_ptr, 0, + PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | + PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | + PNG_FILTER_UP | PNG_FILTER_VALUE_UP | + PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | + PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| + PNG_ALL_FILTERS); + +If an application +wants to start and stop using particular filters during compression, +it should start out with all of the filters (to ensure that the previous +row of pixels will be stored in case it's needed later), and then add +and remove them after the start of compression. + +If you are writing a PNG datastream that is to be embedded in a MNG +datastream, the second parameter can be either 0 or 64. + +The png_set_compression_*() functions interface to the zlib compression +library, and should mostly be ignored unless you really know what you are +doing. The only generally useful call is png_set_compression_level() +which changes how much time zlib spends on trying to compress the image +data. See the Compression Library (zlib.h and algorithm.txt, distributed +with zlib) for details on the compression levels. + + /* set the zlib compression level */ + png_set_compression_level(png_ptr, + Z_BEST_COMPRESSION); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr, + Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192) + +extern PNG_EXPORT(void,png_set_zbuf_size) + +.SS Setting the contents of info for output + +You now need to fill in the png_info structure with all the data you +wish to write before the actual image. Note that the only thing you +are allowed to write after the image is the text chunks and the time +chunk (as of PNG Specification 1.2, anyway). See png_write_end() and +the latest PNG specification for more information on that. If you +wish to write them before the image, fill them in now, and flag that +data as being valid. If you want to wait until after the data, don't +fill them until png_write_end(). For all the fields in png_info and +their data types, see png.h. For explanations of what the fields +contain, see the PNG specification. + +Some of the more important parts of the png_info are: + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, interlace_type, + compression_type, filter_method) + width - holds the width of the image + in pixels (up to 2^31). + height - holds the height of the image + in pixels (up to 2^31). + bit_depth - holds the bit depth of one of the + image channels. + (valid values are 1, 2, 4, 8, 16 + and depend also on the + color_type. See also significant + bits (sBIT) below). + color_type - describes which color/alpha + channels are present. + PNG_COLOR_TYPE_GRAY + (bit depths 1, 2, 4, 8, 16) + PNG_COLOR_TYPE_GRAY_ALPHA + (bit depths 8, 16) + PNG_COLOR_TYPE_PALETTE + (bit depths 1, 2, 4, 8) + PNG_COLOR_TYPE_RGB + (bit_depths 8, 16) + PNG_COLOR_TYPE_RGB_ALPHA + (bit_depths 8, 16) + + PNG_COLOR_MASK_PALETTE + PNG_COLOR_MASK_COLOR + PNG_COLOR_MASK_ALPHA + + interlace_type - PNG_INTERLACE_NONE or + PNG_INTERLACE_ADAM7 + compression_type - (must be + PNG_COMPRESSION_TYPE_DEFAULT) + filter_method - (must be PNG_FILTER_TYPE_DEFAULT + or, if you are writing a PNG to + be embedded in a MNG datastream, + can also be + PNG_INTRAPIXEL_DIFFERENCING) + + png_set_PLTE(png_ptr, info_ptr, palette, + num_palette); + palette - the palette for the file + (array of png_color) + num_palette - number of entries in the palette + + png_set_gAMA(png_ptr, info_ptr, gamma); + gamma - the gamma the image was created + at (PNG_INFO_gAMA) + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of + the sRGB chunk means that the pixel + data is in the sRGB color space. + This chunk also implies specific + values of gAMA and cHRM. Rendering + intent is the CSS-1 property that + has been defined by the International + Color Consortium + (http://www.color.org). + It can be one of + PNG_sRGB_INTENT_SATURATION, + PNG_sRGB_INTENT_PERCEPTUAL, + PNG_sRGB_INTENT_ABSOLUTE, or + PNG_sRGB_INTENT_RELATIVE. + + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, + srgb_intent); + srgb_intent - the rendering intent + (PNG_INFO_sRGB) The presence of the + sRGB chunk means that the pixel + data is in the sRGB color space. + This function also causes gAMA and + cHRM chunks with the specific values + that are consistent with sRGB to be + written. + + png_set_iCCP(png_ptr, info_ptr, name, compression_type, + profile, proflen); + name - The profile name. + compression - The compression type; always + PNG_COMPRESSION_TYPE_BASE for PNG 1.0. + You may give NULL to this argument to + ignore it. + profile - International Color Consortium color + profile data. May contain NULs. + proflen - length of profile data in bytes. + + png_set_sBIT(png_ptr, info_ptr, sig_bit); + sig_bit - the number of significant bits for + (PNG_INFO_sBIT) each of the gray, red, + green, and blue channels, whichever are + appropriate for the given color type + (png_color_16) + + png_set_tRNS(png_ptr, info_ptr, trans, num_trans, + trans_values); + trans - array of transparent entries for + palette (PNG_INFO_tRNS) + trans_values - graylevel or color sample values of + the single transparent color for + non-paletted images (PNG_INFO_tRNS) + num_trans - number of transparent entries + (PNG_INFO_tRNS) + + png_set_hIST(png_ptr, info_ptr, hist); + (PNG_INFO_hIST) + hist - histogram of palette (array of + png_uint_16) + + png_set_tIME(png_ptr, info_ptr, mod_time); + mod_time - time image was last modified + (PNG_VALID_tIME) + + png_set_bKGD(png_ptr, info_ptr, background); + background - background color (PNG_VALID_bKGD) + + png_set_text(png_ptr, info_ptr, text_ptr, num_text); + text_ptr - array of png_text holding image + comments + text_ptr[i].compression - type of compression used + on "text" PNG_TEXT_COMPRESSION_NONE + PNG_TEXT_COMPRESSION_zTXt + PNG_ITXT_COMPRESSION_NONE + PNG_ITXT_COMPRESSION_zTXt + text_ptr[i].key - keyword for comment. Must contain + 1-79 characters. + text_ptr[i].text - text comments for current + keyword. Can be NULL or empty. + text_ptr[i].text_length - length of text string, + after decompression, 0 for iTXt + text_ptr[i].itxt_length - length of itxt string, + after decompression, 0 for tEXt/zTXt + text_ptr[i].lang - language of comment (NULL or + empty for unknown). + text_ptr[i].translated_keyword - keyword in UTF-8 (NULL + or empty for unknown). + num_text - number of comments + + png_set_sPLT(png_ptr, info_ptr, &palette_ptr, + num_spalettes); + palette_ptr - array of png_sPLT_struct structures + to be added to the list of palettes + in the info structure. + num_spalettes - number of palette structures to be + added. + + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, + unit_type); + offset_x - positive offset from the left + edge of the screen + offset_y - positive offset from the top + edge of the screen + unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER + + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, + unit_type); + res_x - pixels/unit physical resolution + in x direction + res_y - pixels/unit physical resolution + in y direction + unit_type - PNG_RESOLUTION_UNKNOWN, + PNG_RESOLUTION_METER + + png_set_sCAL(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are doubles) + + png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) + unit - physical scale units (an integer) + width - width of a pixel in physical scale units + height - height of a pixel in physical scale units + (width and height are strings like "2.54") + + png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, + num_unknowns) + unknowns - array of png_unknown_chunk + structures holding unknown chunks + unknowns[i].name - name of unknown chunk + unknowns[i].data - data of unknown chunk + unknowns[i].size - size of unknown chunk's data + unknowns[i].location - position to write chunk in file + 0: do not write chunk + PNG_HAVE_IHDR: before PLTE + PNG_HAVE_PLTE: before IDAT + PNG_AFTER_IDAT: after IDAT + +The "location" member is set automatically according to +what part of the output file has already been written. +You can change its value after calling png_set_unknown_chunks() +as demonstrated in pngtest.c. Within each of the "locations", +the chunks are sequenced according to their position in the +structure (that is, the value of "i", which is the order in which +the chunk was either read from the input file or defined with +png_set_unknown_chunks). + +A quick word about text and num_text. text is an array of png_text +structures. num_text is the number of valid structures in the array. +Each png_text structure holds a language code, a keyword, a text value, +and a compression type. + +The compression types have the same valid numbers as the compression +types of the image data. Currently, the only valid number is zero. +However, you can store text either compressed or uncompressed, unlike +images, which always have to be compressed. So if you don't want the +text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. +Because tEXt and zTXt chunks don't have a language field, if you +specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt +any language code or translated keyword will not be written out. + +Until text gets around 1000 bytes, it is not worth compressing it. +After the text has been written out to the file, the compression type +is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, +so that it isn't written out again at the end (in case you are calling +png_write_end() with the same struct. + +The keywords that are given in the PNG Specification are: + + Title Short (one line) title or + caption for image + Author Name of image's creator + Description Description of image (possibly long) + Copyright Copyright notice + Creation Time Time of original image creation + (usually RFC 1123 format, see below) + Software Software used to create the image + Disclaimer Legal disclaimer + Warning Warning of nature of content + Source Device used to create the image + Comment Miscellaneous comment; conversion + from other image format + +The keyword-text pairs work like this. Keywords should be short +simple descriptions of what the comment is about. Some typical +keywords are found in the PNG specification, as is some recommendations +on keywords. You can repeat keywords in a file. You can even write +some text before the image and some after. For example, you may want +to put a description of the image before the image, but leave the +disclaimer until after, so viewers working over modem connections +don't have to wait for the disclaimer to go over the modem before +they start seeing the image. Finally, keywords should be full +words, not abbreviations. Keywords and text are in the ISO 8859-1 +(Latin-1) character set (a superset of regular ASCII) and can not +contain NUL characters, and should not contain control or other +unprintable characters. To make the comments widely readable, stick +with basic ASCII, and avoid machine specific character set extensions +like the IBM-PC character set. The keyword must be present, but +you can leave off the text string on non-compressed pairs. +Compressed pairs must have a text string, as only the text string +is compressed anyway, so the compression would be meaningless. + +PNG supports modification time via the png_time structure. Two +conversion routines are provided, png_convert_from_time_t() for +time_t and png_convert_from_struct_tm() for struct tm. The +time_t routine uses gmtime(). You don't have to use either of +these, but if you wish to fill in the png_time structure directly, +you should provide the time in universal time (GMT) if possible +instead of your local time. Note that the year number is the full +year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and +that months start with 1. + +If you want to store the time of the original image creation, you should +use a plain tEXt chunk with the "Creation Time" keyword. This is +necessary because the "creation time" of a PNG image is somewhat vague, +depending on whether you mean the PNG file, the time the image was +created in a non-PNG format, a still photo from which the image was +scanned, or possibly the subject matter itself. In order to facilitate +machine-readable dates, it is recommended that the "Creation Time" +tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), +although this isn't a requirement. Unlike the tIME chunk, the +"Creation Time" tEXt chunk is not expected to be automatically changed +by the software. To facilitate the use of RFC 1123 dates, a function +png_convert_to_rfc1123(png_timep) is provided to convert from PNG +time to an RFC 1123 format string. + +.SS Writing unknown chunks + +You can use the png_set_unknown_chunks function to queue up chunks +for writing. You give it a chunk name, raw data, and a size; that's +all there is to it. The chunks will be written by the next following +png_write_info_before_PLTE, png_write_info, or png_write_end function. +Any chunks previously read into the info structure's unknown-chunk +list will also be written out in a sequence that satisfies the PNG +specification's ordering rules. + +.SS The high-level write interface + +At this point there are two ways to proceed; through the high-level +write interface, or through a sequence of low-level write operations. +You can use the high-level interface if your image data is present +in the info structure. All defined output +transformations are permitted, enabled by the following masks. + + PNG_TRANSFORM_IDENTITY No transformation + PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples + PNG_TRANSFORM_PACKSWAP Change order of packed + pixels to LSB first + PNG_TRANSFORM_INVERT_MONO Invert monochrome images + PNG_TRANSFORM_SHIFT Normalize pixels to the + sBIT depth + PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA + to BGRA + PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA + to AG + PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity + to transparency + PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples + PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. + +If you have valid image data in the info structure (you can use +png_set_rows() to put image data in the info structure), simply do this: + + png_write_png(png_ptr, info_ptr, png_transforms, NULL) + +where png_transforms is an integer containing the bitwise OR of some set of +transformation flags. This call is equivalent to png_write_info(), +followed the set of transformations indicated by the transform mask, +then png_write_image(), and finally png_write_end(). + +(The final parameter of this call is not yet used. Someday it might point +to transformation parameters required by some future output transform.) + +You must use png_transforms and not call any png_set_transform() functions +when you use png_write_png(). + +.SS The low-level write interface + +If you are going the low-level route instead, you are now ready to +write all the file information up to the actual image data. You do +this with a call to png_write_info(). + + png_write_info(png_ptr, info_ptr); + +Note that there is one transformation you may need to do before +png_write_info(). In PNG files, the alpha channel in an image is the +level of opacity. If your data is supplied as a level of +transparency, you can invert the alpha channel before you write it, so +that 0 is fully transparent and 255 (in 8-bit or paletted images) or +65535 (in 16-bit images) is fully opaque, with + + png_set_invert_alpha(png_ptr); + +This must appear before png_write_info() instead of later with the +other transformations because in the case of paletted images the tRNS +chunk data has to be inverted before the tRNS chunk is written. If +your image is not a paletted image, the tRNS data (which in such cases +represents a single color to be rendered as transparent) won't need to +be changed, and you can safely do this transformation after your +png_write_info() call. + +If you need to write a private chunk that you want to appear before +the PLTE chunk when PLTE is present, you can write the PNG info in +two steps, and insert code to write your own chunk between them: + + png_write_info_before_PLTE(png_ptr, info_ptr); + png_set_unknown_chunks(png_ptr, info_ptr, ...); + png_write_info(png_ptr, info_ptr); + +After you've written the file information, you can set up the library +to handle any special transformations of the image data. The various +ways to transform the data will be described in the order that they +should occur. This is important, as some of these change the color +type and/or bit depth of the data, and some others only work on +certain color types and bit depths. Even though each transformation +checks to see if it has data that it can do something with, you should +make sure to only enable a transformation if it will be valid for the +data. For example, don't swap red and blue on grayscale data. + +PNG files store RGB pixels packed into 3 or 6 bytes. This code tells +the library to strip input data that has 4 or 8 bytes per pixel down +to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 +bytes per pixel). + + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + +where the 0 is unused, and the location is either PNG_FILLER_BEFORE or +PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel +is stored XRGB or RGBX. + +PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as +they can, resulting in, for example, 8 pixels per byte for 1 bit files. +If the data is supplied at 1 pixel per byte, use this code, which will +correctly pack the pixels into a single byte: + + png_set_packing(png_ptr); + +PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your +data is of another bit depth, you can write an sBIT chunk into the +file so that decoders can recover the original data if desired. + + /* Set the true bit depth of the image data */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit.red = true_bit_depth; + sig_bit.green = true_bit_depth; + sig_bit.blue = true_bit_depth; + } + else + { + sig_bit.gray = true_bit_depth; + } + if (color_type & PNG_COLOR_MASK_ALPHA) + { + sig_bit.alpha = true_bit_depth; + } + + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + +If the data is stored in the row buffer in a bit depth other than +one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), +this will scale the values to appear to be the correct bit depth as +is required by PNG. + + png_set_shift(png_ptr, &sig_bit); + +PNG files store 16 bit pixels in network byte order (big-endian, +ie. most significant bits first). This code would be used if they are +supplied the other way (little-endian, i.e. least significant bits +first, the way PCs store them): + + if (bit_depth > 8) + png_set_swap(png_ptr); + +If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you +need to change the order the pixels are packed into bytes, you can use: + + if (bit_depth < 8) + png_set_packswap(png_ptr); + +PNG files store 3 color pixels in red, green, blue order. This code +would be used if they are supplied as blue, green, red: + + png_set_bgr(png_ptr); + +PNG files describe monochrome as black being zero and white being +one. This code would be used if the pixels are supplied with this reversed +(black being one and white being zero): + + png_set_invert_mono(png_ptr); + +Finally, you can write your own transformation function if none of +the existing ones meets your needs. This is done by setting a callback +with + + png_set_write_user_transform_fn(png_ptr, + write_transform_fn); + +You must supply the function + + void write_transform_fn(png_ptr ptr, row_info_ptr + row_info, png_bytep data) + +See pngtest.c for a working example. Your function will be called +before any of the other transformations are processed. + +You can also set up a pointer to a user structure for use by your +callback function. + + png_set_user_transform_info(png_ptr, user_ptr, 0, 0); + +The user_channels and user_depth parameters of this function are ignored +when writing; you can set them to zero as shown. + +You can retrieve the pointer via the function png_get_user_transform_ptr(). +For example: + + voidp write_user_transform_ptr = + png_get_user_transform_ptr(png_ptr); + +It is possible to have libpng flush any pending output, either manually, +or automatically after a certain number of lines have been written. To +flush the output stream a single time call: + + png_write_flush(png_ptr); + +and to have libpng flush the output stream periodically after a certain +number of scanlines have been written, call: + + png_set_flush(png_ptr, nrows); + +Note that the distance between rows is from the last time png_write_flush() +was called, or the first row of the image if it has never been called. +So if you write 50 lines, and then png_set_flush 25, it will flush the +output on the next scanline, and every 25 lines thereafter, unless +png_write_flush() is called before 25 more lines have been written. +If nrows is too small (less than about 10 lines for a 640 pixel wide +RGB image) the image compression may decrease noticeably (although this +may be acceptable for real-time applications). Infrequent flushing will +only degrade the compression performance by a few percent over images +that do not use flushing. + +.SS Writing the image data + +That's it for the transformations. Now you can write the image data. +The simplest way to do this is in one function call. If you have the +whole image in memory, you can just call png_write_image() and libpng +will write the image. You will need to pass in an array of pointers to +each row. This function automatically handles interlacing, so you don't +need to call png_set_interlace_handling() or call this function multiple +times, or any of that other stuff necessary with png_write_rows(). + + png_write_image(png_ptr, row_pointers); + +where row_pointers is: + + png_byte *row_pointers[height]; + +You can point to void or char or whatever you use for pixels. + +If you don't want to write the whole image at once, you can +use png_write_rows() instead. If the file is not interlaced, +this is simple: + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +row_pointers is the same as in the png_write_image() call. + +If you are just writing one row at a time, you can do this with +a single row_pointer instead of an array of row_pointers: + + png_bytep row_pointer = row; + + png_write_row(png_ptr, row_pointer); + +When the file is interlaced, things can get a good deal more +complicated. The only currently (as of the PNG Specification +version 1.2, dated July 1999) defined interlacing scheme for PNG files +is the "Adam7" interlace scheme, that breaks down an +image into seven smaller images of varying size. libpng will build +these images for you, or you can do them yourself. If you want to +build them yourself, see the PNG specification for details of which +pixels to write when. + +If you don't want libpng to handle the interlacing details, just +use png_set_interlace_handling() and call png_write_rows() the +correct number of times to write all seven sub-images. + +If you want libpng to build the sub-images, call this before you start +writing any rows: + + number_of_passes = + png_set_interlace_handling(png_ptr); + +This will return the number of passes needed. Currently, this +is seven, but may change if another interlace type is added. + +Then write the complete image number_of_passes times. + + png_write_rows(png_ptr, row_pointers, + number_of_rows); + +As some of these rows are not used, and thus return immediately, +you may want to read about interlacing in the PNG specification, +and only update the rows that are actually used. + +.SS Finishing a sequential write + +After you are finished writing the image, you should finish writing +the file. If you are interested in writing comments or time, you should +pass an appropriately filled png_info pointer. If you are not interested, +you can pass NULL. + + png_write_end(png_ptr, info_ptr); + +When you are done, you can free all memory used by libpng like this: + + png_destroy_write_struct(&png_ptr, &info_ptr); + +It is also possible to individually free the info_ptr members that +point to libpng-allocated storage with the following function: + + png_free_data(png_ptr, info_ptr, mask, seq) + mask - identifies data to be freed, a mask + containing the bitwise OR of one or + more of + PNG_FREE_PLTE, PNG_FREE_TRNS, + PNG_FREE_HIST, PNG_FREE_ICCP, + PNG_FREE_PCAL, PNG_FREE_ROWS, + PNG_FREE_SCAL, PNG_FREE_SPLT, + PNG_FREE_TEXT, PNG_FREE_UNKN, + or simply PNG_FREE_ALL + seq - sequence number of item to be freed + (-1 for all items) + +This function may be safely called when the relevant storage has +already been freed, or has not yet been allocated, or was allocated +by the user and not by libpng, and will in those +cases do nothing. The "seq" parameter is ignored if only one item +of the selected data type, such as PLTE, is allowed. If "seq" is not +-1, and multiple items are allowed for the data type identified in +the mask, such as text or sPLT, only the n'th item in the structure +is freed, where n is "seq". + +If you allocated data such as a palette that you passed +in to libpng with png_set_*, you must not free it until just before the call to +png_destroy_write_struct(). + +The default behavior is only to free data that was allocated internally +by libpng. This can be changed, so that libpng will not free the data, +or so that it will free data that was allocated by the user with png_malloc() +or png_zalloc() and passed in via a png_set_*() function, with + + png_data_freer(png_ptr, info_ptr, freer, mask) + mask - which data elements are affected + same choices as in png_free_data() + freer - one of + PNG_DESTROY_WILL_FREE_DATA + PNG_SET_WILL_FREE_DATA + PNG_USER_WILL_FREE_DATA + +For example, to transfer responsibility for some data from a read structure +to a write structure, you could use + + png_data_freer(read_ptr, read_info_ptr, + PNG_USER_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + png_data_freer(write_ptr, write_info_ptr, + PNG_DESTROY_WILL_FREE_DATA, + PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) + +thereby briefly reassigning responsibility for freeing to the user but +immediately afterwards reassigning it once more to the write_destroy +function. Having done this, it would then be safe to destroy the read +structure and continue to use the PLTE, tRNS, and hIST data in the write +structure. + +This function only affects data that has already been allocated. +You can call this function before calling after the png_set_*() functions +to control whether the user or png_destroy_*() is supposed to free the data. +When the user assumes responsibility for libpng-allocated data, the +application must use +png_free() to free it, and when the user transfers responsibility to libpng +for data that the user has allocated, the user must have used png_malloc() +or png_zalloc() to allocate it. + +If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword +separately, do not transfer responsibility for freeing text_ptr to libpng, +because when libpng fills a png_text structure it combines these members with +the key member, and png_free_data() will free only text_ptr.key. Similarly, +if you transfer responsibility for free'ing text_ptr from libpng to your +application, your application must not separately free those members. +For a more compact example of writing a PNG image, see the file example.c. + +.SH V. Modifying/Customizing libpng: + +There are three issues here. The first is changing how libpng does +standard things like memory allocation, input/output, and error handling. +The second deals with more complicated things like adding new chunks, +adding new transformations, and generally changing how libpng works. +Both of those are compile-time issues; that is, they are generally +determined at the time the code is written, and there is rarely a need +to provide the user with a means of changing them. The third is a +run-time issue: choosing between and/or tuning one or more alternate +versions of computationally intensive routines; specifically, optimized +assembly-language (and therefore compiler- and platform-dependent) +versions. + +Memory allocation, input/output, and error handling + +All of the memory allocation, input/output, and error handling in libpng +goes through callbacks that are user-settable. The default routines are +in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change +these functions, call the appropriate png_set_*_fn() function. + +Memory allocation is done through the functions png_malloc() +and png_free(). These currently just call the standard C functions. If +your pointers can't access more then 64K at a time, you will want to set +MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling +memory allocation on a platform will change between applications, these +functions must be modified in the library at compile time. If you prefer +to use a different method of allocating and freeing data, you can use +png_create_read_struct_2() or png_create_write_struct_2() to register +your own functions as described above. +These functions also provide a void pointer that can be retrieved via + + mem_ptr=png_get_mem_ptr(png_ptr); + +Your replacement memory functions must have prototypes as follows: + + png_voidp malloc_fn(png_structp png_ptr, + png_size_t size); + void free_fn(png_structp png_ptr, png_voidp ptr); + +Your malloc_fn() must return NULL in case of failure. The png_malloc() +function will normally call png_error() if it receives a NULL from the +system memory allocator or from your replacement malloc_fn(). + +Input/Output in libpng is done through png_read() and png_write(), +which currently just call fread() and fwrite(). The FILE * is stored in +png_struct and is initialized via png_init_io(). If you wish to change +the method of I/O, the library supplies callbacks that you can set +through the function png_set_read_fn() and png_set_write_fn() at run +time, instead of calling the png_init_io() function. These functions +also provide a void pointer that can be retrieved via the function +png_get_io_ptr(). For example: + + png_set_read_fn(png_structp read_ptr, + voidp read_io_ptr, png_rw_ptr read_data_fn) + + png_set_write_fn(png_structp write_ptr, + voidp write_io_ptr, png_rw_ptr write_data_fn, + png_flush_ptr output_flush_fn); + + voidp read_io_ptr = png_get_io_ptr(read_ptr); + voidp write_io_ptr = png_get_io_ptr(write_ptr); + +The replacement I/O functions must have prototypes as follows: + + void user_read_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_write_data(png_structp png_ptr, + png_bytep data, png_size_t length); + void user_flush_data(png_structp png_ptr); + +Supplying NULL for the read, write, or flush functions sets them back +to using the default C stream functions. It is an error to read from +a write stream, and vice versa. + +Error handling in libpng is done through png_error() and png_warning(). +Errors handled through png_error() are fatal, meaning that png_error() +should never return to its caller. Currently, this is handled via +setjmp() and longjmp() (unless you have compiled libpng with +PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), +but you could change this to do things like exit() if you should wish. + +On non-fatal errors, png_warning() is called +to print a warning message, and then control returns to the calling code. +By default png_error() and png_warning() print a message on stderr via +fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined +(because you don't want the messages) or PNG_NO_STDIO defined (because +fprintf() isn't available). If you wish to change the behavior of the error +functions, you will need to set up your own message callbacks. These +functions are normally supplied at the time that the png_struct is created. +It is also possible to redirect errors and warnings to your own replacement +functions after png_create_*_struct() has been called by calling: + + png_set_error_fn(png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_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 +default function will be used, calling fprintf() and/or longjmp() if a +problem is encountered. The replacement error functions should have +parameters as follows: + + void user_error_fn(png_structp png_ptr, + png_const_charp error_msg); + void user_warning_fn(png_structp png_ptr, + png_const_charp warning_msg); + +The motivation behind using setjmp() and longjmp() is the C++ throw and +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. +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 +setjmp returns non-zero besides returning itself. Consult your compiler +documentation for more details. For an alternative approach, you may wish +to use the "cexcept" facility (see http://cexcept.sourceforge.net). + +.SS Custom chunks + +If you need to read or write custom chunks, you may need to get deeper +into the libpng code. The library now has mechanisms for storing +and writing chunks of unknown type; you can even declare callbacks +for custom chunks. However, this may not be good enough if the +library code itself needs to know about interactions between your +chunk and existing `intrinsic' chunks. + +If you need to write a new intrinsic chunk, first read the PNG +specification. Acquire a first level of +understanding of how it works. Pay particular attention to the +sections that describe chunk names, and look at how other chunks were +designed, so you can do things similarly. Second, check out the +sections of libpng that read and write chunks. Try to find a chunk +that is similar to yours and use it as a template. More details can +be found in the comments inside the code. It is best to handle unknown +chunks in a generic method, via callback functions, instead of by +modifying libpng functions. + +If you wish to write your own transformation for the data, look through +the part of the code that does the transformations, and check out some of +the simpler ones to get an idea of how they work. Try to find a similar +transformation to the one you want to add and copy off of it. More details +can be found in the comments inside the code itself. + +.SS Configuring for 16 bit platforms + +You will want to look into zconf.h to tell zlib (and thus libpng) that +it cannot allocate more then 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. + +.SS 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. + +.SS 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 *. + +.SS Configuring for gui/windowing platforms: + +You will need to write new error and warning functions that use the GUI +interface, as described previously, and set them to be the error and +warning functions at the time that png_create_*_struct() is called, +in order to have them available during the structure initialization. +They can be changed later via png_set_error_fn(). On some compilers, +you may also have to change the memory allocators (png_malloc, etc.). + +.SS Configuring for compiler xxx: + +All includes for libpng are in pngconf.h. If you need to add/change/delete +an include, this is the place to do it. The includes that are not +needed outside libpng are protected by the PNG_INTERNAL definition, +which is only defined for those routines inside libpng itself. The +files in libpng proper only include png.h, which includes pngconf.h. + +.SS Configuring zlib: + +There are special functions to configure the compression. Perhaps the +most useful one changes the compression level, which currently uses +input compression values in the range 0 - 9. The library normally +uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests +have shown that for a large majority of images, compression values in +the range 3-6 compress nearly as well as higher levels, and do so much +faster. For online applications it may be desirable to have maximum speed +(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also +specify no compression (Z_NO_COMPRESSION = 0), but this would create +files larger than just storing the raw bitmap. You can specify the +compression level by calling: + + png_set_compression_level(png_ptr, level); + +Another useful one is to reduce the memory level used by the library. +The memory level defaults to 8, but it can be lowered if you are +short on memory (running DOS, for example, where you only have 640K). +Note that the memory level does have an effect on compression; among +other things, lower levels will result in sections of incompressible +data being emitted in smaller stored blocks, with a correspondingly +larger relative overhead of up to 15% in the worst case. + + png_set_compression_mem_level(png_ptr, level); + +The other functions are for configuring zlib. They are not recommended +for normal use and may result in writing an invalid PNG file. See +zlib.h for more information on what these mean. + + png_set_compression_strategy(png_ptr, + strategy); + png_set_compression_window_bits(png_ptr, + window_bits); + png_set_compression_method(png_ptr, method); + png_set_compression_buffer_size(png_ptr, size); + +.SS Controlling row filtering + +If you want to control whether libpng uses filtering or not, which +filters are used, and how it goes about picking row filters, you +can call one of these functions. The selection and configuration +of row filters can have a significant impact on the size and +encoding speed and a somewhat lesser impact on the decoding speed +of an image. Filtering is enabled by default for RGB and grayscale +images (with and without alpha), but not for paletted images nor +for any images with bit depths less than 8 bits/pixel. + +The 'method' parameter sets the main filtering method, which is +currently only '0' in the PNG 1.2 specification. The 'filters' +parameter sets which filter(s), if any, should be used for each +scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS +to turn filtering on and off, respectively. + +Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, +PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise +ORed together with '|' to specify one or more filters to use. +These filters are described in more detail in the PNG specification. +If you intend to change the filter type during the course of writing +the image, you should start with flags set for all of the filters +you intend to use so that libpng can initialize its internal +structures appropriately for all of the filter types. (Note that this +means the first row must always be adaptively filtered, because libpng +currently does not allocate the filter buffers until png_write_row() +is called for the first time.) + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB + PNG_FILTER_UP | PNG_FILTER_AVE | + PNG_FILTER_PAETH | PNG_ALL_FILTERS; + + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, + filters); + The second parameter can also be + PNG_INTRAPIXEL_DIFFERENCING if you are + writing a PNG to be embedded in a MNG + datastream. This parameter must be the + same as the value of filter_method used + in png_set_IHDR(). + +It is also possible to influence how libpng chooses from among the +available filters. This is done in one or both of two ways - by +telling it how important it is to keep the same filter for successive +rows, and by telling it the relative computational costs of the filters. + + double weights[3] = {1.5, 1.3, 1.1}, + costs[PNG_FILTER_VALUE_LAST] = + {1.0, 1.3, 1.3, 1.5, 1.7}; + + png_set_filter_heuristics(png_ptr, + PNG_FILTER_HEURISTIC_WEIGHTED, 3, + weights, costs); + +The weights are multiplying factors that indicate to libpng that the +row filter should be the same for successive rows unless another row filter +is that many times better than the previous filter. In the above example, +if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a +"sum of absolute differences" 1.5 x 1.3 times higher than other filters +and still be chosen, while the NONE filter could have a sum 1.1 times +higher than other filters and still be chosen. Unspecified weights are +taken to be 1.0, and the specified weights should probably be declining +like those above in order to emphasize recent filters over older filters. + +The filter costs specify for each filter type a relative decoding cost +to be considered when selecting row filters. This means that filters +with higher costs are less likely to be chosen over filters with lower +costs, unless their "sum of absolute differences" is that much smaller. +The costs do not necessarily reflect the exact computational speeds of +the various filters, since this would unduly influence the final image +size. + +Note that the numbers above were invented purely for this example and +are given only to help explain the function usage. Little testing has +been done to find optimum values for either the costs or the weights. + +.SS 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_. + +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. + +.SS Requesting debug printout + +The macro definition PNG_DEBUG can be used to request debugging +printout. Set it to an integer value in the range 0 to 3. Higher +numbers result in increasing amounts of debugging information. The +information is printed to the "stderr" file, unless another file +name is specified in the PNG_DEBUG_FILE macro definition. + +When PNG_DEBUG > 0, the following functions (macros) become available: + + png_debug(level, message) + png_debug1(level, message, p1) + png_debug2(level, message, p1, p2) + +in which "level" is compared to PNG_DEBUG to decide whether to print +the message, "message" is the formatted string to be printed, +and p1 and p2 are parameters that are to be embedded in the string +according to printf-style formatting directives. For example, + + png_debug1(2, "foo=%d\n", foo); + +is expanded to + + if(PNG_DEBUG > 2) + fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); + +When PNG_DEBUG is defined but is zero, the macros aren't defined, but you +can still use PNG_DEBUG to control your own debugging: + + #ifdef PNG_DEBUG + fprintf(stderr, ... + #endif + +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 +this version of libpng, but if you insert some they will be printed. + +.SH VI. Runtime optimization + +A new feature in libpng 1.2.0 is the ability to dynamically switch between +standard and optimized versions of some routines. Currently these are +limited to three computationally intensive tasks when reading PNG files: +decoding row filters, expanding interlacing, and combining interlaced or +transparent row data with previous row data. Currently the optimized +versions are available only for x86 (Intel, AMD, etc.) platforms with +MMX support, though this may change in future versions. (For example, +the non-MMX assembler optimizations for zlib might become similarly +runtime-selectable in future releases, in which case libpng could be +extended to support them. Alternatively, the compile-time choice of +floating-point versus integer routines for gamma correction might become +runtime-selectable.) + +Because such optimizations tend to be very platform- and compiler-dependent, +both in how they are written and in how they perform, the new runtime code +in libpng has been written to allow programs to query, enable, and disable +either specific optimizations or all such optimizations. For example, to +enable all possible optimizations (bearing in mind that some "optimizations" +may actually run more slowly in rare cases): + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + png_uint_32 mask, flags; + + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags | mask); + #endif + +To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ +by itself when calling png_get_asm_flagmask(); similarly for optimizing +only writing. To disable all optimizations: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = png_get_asm_flags(png_ptr); + mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); + png_set_asm_flags(png_ptr, flags & ~mask); + #endif + +To enable or disable only MMX-related features, use png_get_mmx_flagmask() +in place of png_get_asm_flagmask(). The mmx version takes one additional +parameter: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; + int compilerID; + + mask = png_get_mmx_flagmask(selection, &compilerID); + #endif + +On return, compilerID will indicate which version of the MMX assembler +optimizations was compiled. Currently two flavors exist: Microsoft +Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). +On non-x86 platforms or on systems compiled without MMX optimizations, a +value of -1 is used. + +Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return +all valid, settable optimization bits for the version of the library that's +currently in use. In the case of shared (dynamically linked) libraries, +this may include optimizations that did not exist at the time the code was +written and compiled. It is also possible, of course, to enable only known, +specific optimizations; for example: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + png_set_asm_flags(png_ptr, flags); + #endif + +This method would enable only the MMX read-optimizations available at the +time of libpng 1.2.0's release, regardless of whether a later version of +the DLL were actually being used. (Also note that these functions did not +exist in versions older than 1.2.0, so any attempt to run a dynamically +linked app on such an older version would fail.) + +To determine whether the processor supports MMX instructions at all, use +the png_mmx_support() function: + + #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) + mmxsupport = png_mmx_support(); + #endif + +It returns -1 if MMX support is not compiled into libpng, 0 if MMX code +is compiled but MMX is not supported by the processor, or 1 if MMX support +is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), +and png_get_asm_flagmask() all may be called without allocating and ini- +tializing any PNG structures (for example, as part of a usage screen or +"about" box). + +The following code can be used to prevent an application from using the +thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK +defined: + +#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ + && defined(PNG_THREAD_UNSAFE_OK) + /* Disable thread-unsafe features of pnggccrd */ + if (png_access_version_number() >= 10200) + { + png_uint_32 mmx_disable_mask = 0; + png_uint_32 asm_flags; + + mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); + asm_flags = png_get_asm_flags(png_ptr); + png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); + } +#endif + +For more extensive examples of runtime querying, enabling and disabling +of optimized features, see contrib/gregbook/readpng2.c in the libpng +source-code distribution. + +.SH VII. MNG support + +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. +Libpng can support some of these extensions. To enable them, use the +png_permit_mng_features() function: + + feature_set = png_permit_mng_features(png_ptr, mask) + mask is a png_uint_32 containing the bitwise OR of the + features you want to enable. These include + PNG_FLAG_MNG_EMPTY_PLTE + PNG_FLAG_MNG_FILTER_64 + PNG_ALL_MNG_FEATURES + feature_set is a png_uint_32 that is the bitwise AND of + your mask with the set of MNG features that is + supported by the version of libpng that you are using. + +It is an error to use this function when reading or writing a standalone +PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped +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 +or any other MNG chunks; your application must provide its own support for +them. You may wish to consider using libmng (available at +http://www.libmng.com) instead. + +.SH VIII. Changes to Libpng from version 0.88 + +It should be noted that versions of libpng later than 0.96 are not +distributed by the original libpng author, Guy Schalnat, nor by +Andreas Dilger, who had taken over from Guy during 1996 and 1997, and +distributed versions 0.89 through 0.96, but rather by another member +of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are +still alive and well, but they have moved on to other things. + +The old libpng functions png_read_init(), png_write_init(), +png_info_init(), png_read_destroy(), and png_write_destroy() have been +moved to PNG_INTERNAL in version 0.95 to discourage their use. These +functions will be removed from libpng version 2.0.0. + +The preferred method of creating and initializing the libpng structures is +via the png_create_read_struct(), png_create_write_struct(), and +png_create_info_struct() because they isolate the size of the structures +from the application, allow version error checking, and also allow the +use of custom error handling routines during the initialization, which +the old functions do not. The functions png_read_destroy() and +png_write_destroy() do not actually free the memory that libpng +allocated for these structs, but just reset the data structures, so they +can be used instead of png_destroy_read_struct() and +png_destroy_write_struct() if you feel there is too much system overhead +allocating and freeing the png_struct for each image read. + +Setting the error callbacks via png_set_message_fn() before +png_read_init() as was suggested in libpng-0.88 is no longer supported +because this caused applications that do not use custom error functions +to fail if the png_ptr was not initialized to zero. It is still possible +to set the error callbacks AFTER png_read_init(), or to change them with +png_set_error_fn(), which is essentially the same function, but with a new +name to force compilation errors with applications that try to use the old +method. + +Starting with version 1.0.7, you can find out which version of the library +you are using at run-time: + + png_uint_32 libpng_vn = png_access_version_number(); + +The number libpng_vn is constructed from the major version, minor +version with leading zero, and release number with leading zero, +(e.g., libpng_vn for version 1.0.7 is 10007). + +You can also check which version of png.h you used when compiling your +application: + + png_uint_32 application_vn = PNG_LIBPNG_VER; + +.SH IX. Y2K Compliance in libpng + +May 15, 2007 + +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.2.18 are Y2K compliant. It is my belief that earlier +versions were also Y2K compliant. + +Libpng only has three year fields. One is a 2-byte unsigned integer that +will hold years up to 65535. The other two hold the date in text +format, and will hold years up to 9999. + +The integer is + "png_uint_16 year" in png_time_struct. + +The strings are + "png_charp time_buffer" in png_struct and + "near_time_buffer", which is a local character string in png.c. + +There are seven time-related functions: + + png_convert_to_rfc_1123() in png.c + (formerly png_convert_to_rfc_1152() in error) + 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 + +.SH NOTE + +Note about libpng version numbers: + +Due to various miscommunications, unforeseen code incompatibilities +and occasional factors outside the authors' control, version numbering +on the library has not always been consistent and straightforward. +The following table summarizes matters since version 0.89c, which was +the first widely used release: + + source png.h png.h shared-lib + version string int version + ------- ------ ----- ---------- + 0.89c ("beta 3") 0.89 89 1.0.89 + 0.90 ("beta 4") 0.90 90 0.90 + 0.95 ("beta 5") 0.95 95 0.95 + 0.96 ("beta 6") 0.96 96 0.96 + 0.97b ("beta 7") 1.00.97 97 1.0.1 + 0.97c 0.97 97 2.0.97 + 0.98 0.98 98 2.0.98 + 0.99 0.99 98 2.0.99 + 0.99a-m 0.99 99 2.0.99 + 1.00 1.00 100 2.1.0 + 1.0.0 1.0.0 100 2.1.0 + 1.0.0 (from here on, the 100 2.1.0 + 1.0.1 png.h string is 10001 2.1.0 + 1.0.1a-e identical to the 10002 from here on, the + 1.0.2 source version) 10002 shared library is 2.V + 1.0.2a-b 10003 where V is the source + 1.0.1 10001 code version except as + 1.0.1a-e 10002 2.1.0.1a-e noted. + 1.0.2 10002 2.1.0.2 + 1.0.2a-b 10003 2.1.0.2a-b + 1.0.3 10003 2.1.0.3 + 1.0.3a-d 10004 2.1.0.3a-d + 1.0.4 10004 2.1.0.4 + 1.0.4a-f 10005 2.1.0.4a-f + 1.0.5 (+ 2 patches) 10005 2.1.0.5 + 1.0.5a-d 10006 2.1.0.5a-d + 1.0.5e-r 10100 2.1.0.5e-r + 1.0.5s-v 10006 2.1.0.5s-v + 1.0.6 (+ 3 patches) 10006 2.1.0.6 + 1.0.6d-g 10007 2.1.0.6d-g + 1.0.6h 10007 10.6h + 1.0.6i 10007 10.6i + 1.0.6j 10007 2.1.0.6j + 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 + 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 + 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 + 1.0.7 1 10007 2.1.0.7 + 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + 1.0.8rc1 1 10008 2.1.0.8rc1 + 1.0.8 1 10008 2.1.0.8 + 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + 1.0.9rc1 1 10009 2.1.0.9rc1 + 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + 1.0.9rc2 1 10009 2.1.0.9rc2 + 1.0.9 1 10009 2.1.0.9 + 1.0.10beta1 1 10010 2.1.0.10beta1 + 1.0.10rc1 1 10010 2.1.0.10rc1 + 1.0.10 1 10010 2.1.0.10 + 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + 1.0.11rc1 1 10011 2.1.0.11rc1 + 1.0.11 1 10011 2.1.0.11 + 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + 1.0.12rc1 2 10012 2.1.0.12rc1 + 1.0.12 2 10012 2.1.0.12 + 1.1.0a-f - 10100 2.1.1.0a-f abandoned + 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + 1.2.0rc1 3 10200 3.1.2.0rc1 + 1.2.0 3 10200 3.1.2.0 + 1.2.1beta-4 3 10201 3.1.2.1beta1-4 + 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + 1.2.1 3 10201 3.1.2.1 + 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + 1.0.13 10 10013 10.so.0.1.0.13 + 1.2.2 12 10202 12.so.0.1.2.2 + 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + 1.2.3 12 10203 12.so.0.1.2.3 + 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + 1.0.14 10 10014 10.so.0.1.0.14 + 1.2.4 13 10204 12.so.0.1.2.4 + 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + 1.0.15rc1 10 10015 10.so.0.1.0.15rc1 + 1.0.15 10 10015 10.so.0.1.0.15 + 1.2.5 13 10205 12.so.0.1.2.5 + 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + 1.2.6rc1-5 13 10206 12.so.0.1.2.6rc1-5 + 1.0.16 10 10016 10.so.0.1.0.16 + 1.2.6 13 10206 12.so.0.1.2.6 + 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + 1.0.17 10 10017 10.so.0.1.0.17 + 1.2.7 13 10207 12.so.0.1.2.7 + 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + 1.0.18 10 10018 10.so.0.1.0.18 + 1.2.8 13 10208 12.so.0.1.2.8 + 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + 1.2.9beta4-11 13 10209 12.so.0.9[.0] + 1.2.9rc1 13 10209 12.so.0.9[.0] + 1.2.9 13 10209 12.so.0.9[.0] + 1.2.10beta1-8 13 10210 12.so.0.10[.0] + 1.2.10rc1-3 13 10210 12.so.0.10[.0] + 1.2.10 13 10210 12.so.0.10[.0] + 1.2.11beta1-4 13 10211 12.so.0.11[.0] + 1.0.19rc1-5 10 10019 10.so.0.19[.0] + 1.2.11rc1-5 13 10211 12.so.0.11[.0] + 1.0.19 10 10019 10.so.0.19[.0] + 1.2.11 13 10211 12.so.0.11[.0] + 1.0.20 10 10020 10.so.0.20[.0] + 1.2.12 13 10212 12.so.0.12[.0] + 1.2.13beta1 13 10213 12.so.0.13[.0] + 1.0.21 10 10021 10.so.0.21[.0] + 1.2.13 13 10213 12.so.0.13[.0] + 1.2.14beta1-2 13 10214 12.so.0.14[.0] + 1.0.22rc1 10 10022 10.so.0.22[.0] + 1.2.14rc1 13 10214 12.so.0.14[.0] + 1.2.15beta1-6 13 10215 12.so.0.15[.0] + 1.0.23rc1-5 10 10023 10.so.0.23[.0] + 1.2.15rc1-5 13 10215 12.so.0.15[.0] + 1.0.23 10 10023 10.so.0.23[.0] + 1.2.15 13 10215 12.so.0.15[.0] + 1.2.16beta1-2 13 10216 12.so.0.16[.0] + 1.2.16rc1 13 10216 12.so.0.16[.0] + 1.0.24 10 10024 10.so.0.24[.0] + 1.2.16 13 10216 12.so.0.16[.0] + 1.2.17beta1-2 13 10217 12.so.0.17[.0] + 1.0.25rc1 10 10025 10.so.0.25[.0] + 1.2.17rc1-3 13 10217 12.so.0.17[.0] + 1.0.25 10 10025 10.so.0.25[.0] + 1.2.17 13 10217 12.so.0.17[.0] + 1.0.26 10 10026 10.so.0.26[.0] + 1.2.18 13 10218 12.so.0.18[.0] + +Henceforth the source version will match the shared-library minor +and patch numbers; the shared-library major version number will be +used for changes in backward compatibility, as it is intended. The +PNG_PNGLIB_VER macro, which is not used within libpng but is available +for applications, is an unsigned integer of the form xyyzz corresponding +to the source version x.y.z (leading zeros in y and z). Beta versions +were given the previous public release number plus a letter, until +version 1.0.6j; from then on they were given the upcoming public +release number plus "betaNN" or "rcN". + +.SH "SEE ALSO" +libpngpf(3), png(5) +.LP +.IR libpng : +.IP +http://libpng.sourceforge.net (follow the [DOWNLOAD] link) +http://www.libpng.org/pub/png + +.LP +.IR zlib : +.IP +(generally) at the same location as +.I libpng +or at +.br +ftp://ftp.info-zip.org/pub/infozip/zlib + +.LP +.IR PNG specification: RFC 2083 +.IP +(generally) at the same location as +.I libpng +or at +.br +ftp://ds.internic.net/rfc/rfc2083.txt +.br +or (as a W3C Recommendation) at +.br +http://www.w3.org/TR/REC-png.html + +.LP +In the case of any inconsistency between the PNG specification +and this library, the specification takes precedence. + +.SH AUTHORS +This man page: Glenn Randers-Pehrson + + +The contributing authors would like to thank all those who helped +with testing, bug fixes, and patience. This wouldn't have been +possible without all of you. + +Thanks to Frank J. T. Wojcik for helping with the documentation. + +Libpng version 1.2.18 - May 15, 2007: +Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. +Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). + +Supported by the PNG development group +.br +png-mng-implement at lists.sf.net +(subscription required; visit +png-mng-implement at lists.sourceforge.net (subscription required; visit +https://lists.sourceforge.net/lists/listinfo/png-mng-implement +to subscribe). + +.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +(This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail.) + +If you modify libpng you may insert additional notices immediately following +this sentence. + +libpng versions 1.2.6, August 15, 2004, through 1.2.18, May 15, 2007, are +Copyright (c) 2004,2006-2007 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.2.5 +with the following individual added to the list of Contributing Authors + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your + enjoyment of the library or against infringement. + There is no warranty that our efforts or the library + will fulfill any of your particular purposes or needs. + This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and + effort is with the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson +Distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and + must not be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from + any source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +May 15, 2007 + +.\" end of man page + diff --git a/src/dep/src/irrlicht/libpng/libpngpf.3 b/src/dep/src/irrlicht/libpng/libpngpf.3 new file mode 100644 index 0000000..ee75e45 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/libpngpf.3 @@ -0,0 +1,274 @@ +.TH LIBPNGPF 3 "May 15, 2007" +.SH NAME +libpng \- Portable Network Graphics (PNG) Reference Library 1.2.18 +(private functions) +.SH SYNOPSIS +\fB#include \fP + +\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP + +\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP + +\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP + +\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fImask\fP\fB);\fP + +\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP + +\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP + +\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP + +\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBpng_voidp png_create_struct (int \fItype\fP\fB);\fP + +\fBpng_voidp png_create_struct_2 (int \fP\fItype\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP + +\fBpng_charp png_decompress_chunk (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcomp_type\fP\fB, png_charp \fP\fIchunkdata\fP\fB, png_size_t \fP\fIchunklength\fP\fB, png_size_t \fP\fIprefix_length\fP\fB, png_size_t \fI*data_length\fP\fB);\fP + +\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP + +\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fP\fIfree_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP + +\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP + +\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP + +\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP + +\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP + +\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP + +\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP + +\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP + +\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP + +\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP + +\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP + +\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP + +\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP + +\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP + +\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_iTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_init_mmx_flags (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP + +\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP + +\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP + +\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP + +\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP + +\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP + +\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP + +\fBint png_set_text_2 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP + +\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP + +\fBvoid png_write_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP + +\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP + +\fBvoid png_write_find_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP + +\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP + +\fBvoid png_write_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIint_file_gamma\fP\fB);\fP + +\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP + +\fBvoid png_write_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, int \fIproflen\fP\fB);\fP + +\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP + +\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP + +\fBvoid png_write_iTXt (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcompression\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fIlang\fP\fB, png_charp \fP\fItranslated_key\fP\fB, png_charp \fItext\fP\fB);\fP + +\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP + +\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP + +\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP + +\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP + +\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP + +\fBvoid png_write_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP + +\fBvoid png_write_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP + +\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP + +\fBvoid png_write_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_spalette_p \fIpalette\fP\fB);\fP + +\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP + +\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP + +\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP + +\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP + +\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP + +\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP + +\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP + +\fI\fB + +.SH DESCRIPTION +The functions listed above are used privately by libpng +and are not recommended for use by applications. They are +not "exported" to applications using shared libraries. They +are listed alphabetically here as an aid to libpng maintainers. +See png.h for more information on these functions. + +.SH SEE ALSO +libpng(3), png(5) +.SH AUTHOR +Glenn Randers-Pehrson diff --git a/src/dep/src/irrlicht/libpng/png.5 b/src/dep/src/irrlicht/libpng/png.5 new file mode 100644 index 0000000..142faf6 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/png.5 @@ -0,0 +1,74 @@ +.TH PNG 5 "May 15, 2007" +.SH NAME +png \- Portable Network Graphics (PNG) format +.SH DESCRIPTION +PNG (Portable Network Graphics) is an extensible file format for the +lossless, portable, well-compressed storage of raster images. PNG provides +a patent-free replacement for GIF and can also replace many +common uses of TIFF. Indexed-color, grayscale, and truecolor images are +supported, plus an optional alpha channel. Sample depths range from +1 to 16 bits. +.br + +PNG is designed to work well in online viewing applications, such as the +World Wide Web, so it is fully streamable with a progressive display +option. PNG is robust, providing both full file integrity checking and +fast, simple detection of common transmission errors. Also, PNG can store +gamma and chromaticity data for improved color matching on heterogeneous +platforms. + +.SH "SEE ALSO" +.IR libpng(3), zlib(3), deflate(5), and zlib(5) +.LP +PNG specification (second edition), November 2003: +.IP +.br + 8) + png_error(png_ptr, "Too many bytes for PNG signature."); + + png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); +} + +/* Checks whether the supplied bytes match the PNG signature. We allow + * checking less than the full 8-byte signature so that those apps that + * already read the first few bytes of a file to determine the file type + * can simply check the remaining bytes for extra assurance. Returns + * an integer less than, equal to, or greater than zero if sig is found, + * respectively, to be less than, to match, or be greater than the correct + * PNG signature (this is the same behaviour as strcmp, memcmp, etc). + */ +int PNGAPI +png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + if (num_to_check > 8) + num_to_check = 8; + else if (num_to_check < 1) + return (-1); + + if (start > 7) + return (-1); + + if (start + num_to_check > 8) + num_to_check = 8 - start; + + return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); +} + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* (Obsolete) function to check signature bytes. It does not allow one + * to check a partial signature. This function might be removed in the + * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG. + */ +int PNGAPI +png_check_sig(png_bytep sig, int num) +{ + return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num)); +} +#endif +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Function to allocate memory for zlib and clear it to 0. */ +#ifdef PNG_1_0_X +voidpf PNGAPI +#else +voidpf /* private */ +#endif +png_zalloc(voidpf png_ptr, uInt items, uInt size) +{ + png_voidp ptr; + png_structp p=(png_structp)png_ptr; + png_uint_32 save_flags=p->flags; + png_uint_32 num_bytes; + + if(png_ptr == NULL) return (NULL); + if (items > PNG_UINT_32_MAX/size) + { + png_warning (p, "Potential overflow in png_zalloc()"); + return (NULL); + } + num_bytes = (png_uint_32)items * size; + + p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); + p->flags=save_flags; + +#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO) + if (ptr == NULL) + return ((voidpf)ptr); + + if (num_bytes > (png_uint_32)0x8000L) + { + png_memset(ptr, 0, (png_size_t)0x8000L); + png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0, + (png_size_t)(num_bytes - (png_uint_32)0x8000L)); + } + else + { + png_memset(ptr, 0, (png_size_t)num_bytes); + } +#endif + return ((voidpf)ptr); +} + +/* function to free memory for zlib */ +#ifdef PNG_1_0_X +void PNGAPI +#else +void /* private */ +#endif +png_zfree(voidpf png_ptr, voidpf ptr) +{ + png_free((png_structp)png_ptr, (png_voidp)ptr); +} + +/* Reset the CRC variable to 32 bits of 1's. Care must be taken + * in case CRC is > 32 bits to leave the top bits 0. + */ +void /* PRIVATE */ +png_reset_crc(png_structp png_ptr) +{ + png_ptr->crc = crc32(0, Z_NULL, 0); +} + +/* Calculate the CRC over a section of data. We can only pass as + * much data to this routine as the largest single buffer size. We + * also check that this data will actually be used before going to the + * trouble of calculating it. + */ +void /* PRIVATE */ +png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) +{ + int need_crc = 1; + + if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + + if (need_crc) + png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); +} + +/* Allocate the memory for an info_struct for the application. We don't + * really need the png_ptr, but it could potentially be useful in the + * future. This should be used in favour of malloc(png_sizeof(png_info)) + * and png_info_init() so that applications that want to use a shared + * libpng don't have to be recompiled if png_info changes size. + */ +png_infop PNGAPI +png_create_info_struct(png_structp png_ptr) +{ + png_infop info_ptr; + + png_debug(1, "in png_create_info_struct\n"); + if(png_ptr == NULL) return (NULL); +#ifdef PNG_USER_MEM_SUPPORTED + info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, + png_ptr->malloc_fn, png_ptr->mem_ptr); +#else + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); +#endif + if (info_ptr != NULL) + png_info_init_3(&info_ptr, png_sizeof(png_info)); + + return (info_ptr); +} + +/* This function frees the memory associated with a single info struct. + * Normally, one would use either png_destroy_read_struct() or + * png_destroy_write_struct() to free an info struct, but this may be + * useful for some applications. + */ +void PNGAPI +png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) +{ + png_infop info_ptr = NULL; + if(png_ptr == NULL) return; + + png_debug(1, "in png_destroy_info_struct\n"); + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + png_info_destroy(png_ptr, info_ptr); + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, + png_ptr->mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } +} + +/* Initialize the info structure. This is now an internal function (0.89) + * and applications using it are urged to use png_create_info_struct() + * instead. + */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +#undef png_info_init +void PNGAPI +png_info_init(png_infop info_ptr) +{ + /* We only come here via pre-1.0.12-compiled applications */ + png_info_init_3(&info_ptr, 0); +} +#endif + +void PNGAPI +png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) +{ + png_infop info_ptr = *ptr_ptr; + + if(info_ptr == NULL) return; + + png_debug(1, "in png_info_init_3\n"); + + if(png_sizeof(png_info) > png_info_struct_size) + { + png_destroy_struct(info_ptr); + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); + *ptr_ptr = info_ptr; + } + + /* set everything to 0 */ + png_memset(info_ptr, 0, png_sizeof (png_info)); +} + +#ifdef PNG_FREE_ME_SUPPORTED +void PNGAPI +png_data_freer(png_structp png_ptr, png_infop info_ptr, + int freer, png_uint_32 mask) +{ + png_debug(1, "in png_data_freer\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if(freer == PNG_DESTROY_WILL_FREE_DATA) + info_ptr->free_me |= mask; + else if(freer == PNG_USER_WILL_FREE_DATA) + info_ptr->free_me &= ~mask; + else + png_warning(png_ptr, + "Unknown freer parameter in png_data_freer."); +} +#endif + +void PNGAPI +png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, + int num) +{ + png_debug(1, "in png_free_data\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + +#if defined(PNG_TEXT_SUPPORTED) +/* free text item num or (if num == -1) all text items */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) +#else +if (mask & PNG_FREE_TEXT) +#endif +{ + if (num != -1) + { + if (info_ptr->text && info_ptr->text[num].key) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + } + else + { + int i; + for (i = 0; i < info_ptr->num_text; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + info_ptr->num_text=0; + } +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +/* free any tRNS entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) +#endif +{ + png_free(png_ptr, info_ptr->trans); + info_ptr->valid &= ~PNG_INFO_tRNS; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; +#endif + info_ptr->trans = NULL; +} +#endif + +#if defined(PNG_sCAL_SUPPORTED) +/* free any sCAL entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) +#else +if (mask & PNG_FREE_SCAL) +#endif +{ +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_height); + info_ptr->scal_s_width = NULL; + info_ptr->scal_s_height = NULL; +#endif + info_ptr->valid &= ~PNG_INFO_sCAL; +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +/* free any pCAL entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) +#else +if (mask & PNG_FREE_PCAL) +#endif +{ + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + info_ptr->pcal_purpose = NULL; + info_ptr->pcal_units = NULL; + if (info_ptr->pcal_params != NULL) + { + int i; + for (i = 0; i < (int)info_ptr->pcal_nparams; i++) + { + png_free(png_ptr, info_ptr->pcal_params[i]); + info_ptr->pcal_params[i]=NULL; + } + png_free(png_ptr, info_ptr->pcal_params); + info_ptr->pcal_params = NULL; + } + info_ptr->valid &= ~PNG_INFO_pCAL; +} +#endif + +#if defined(PNG_iCCP_SUPPORTED) +/* free any iCCP entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) +#else +if (mask & PNG_FREE_ICCP) +#endif +{ + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->iccp_name = NULL; + info_ptr->iccp_profile = NULL; + info_ptr->valid &= ~PNG_INFO_iCCP; +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +/* free a given sPLT entry, or (if num == -1) all sPLT entries */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) +#else +if (mask & PNG_FREE_SPLT) +#endif +{ + if (num != -1) + { + if(info_ptr->splt_palettes) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + info_ptr->splt_palettes[num].name = NULL; + info_ptr->splt_palettes[num].entries = NULL; + } + } + else + { + if(info_ptr->splt_palettes_num) + { + int i; + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = NULL; + info_ptr->splt_palettes_num = 0; + } + info_ptr->valid &= ~PNG_INFO_sPLT; + } +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if(png_ptr->unknown_chunk.data) + { + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) +#else +if (mask & PNG_FREE_UNKN) +#endif +{ + if (num != -1) + { + if(info_ptr->unknown_chunks) + { + png_free(png_ptr, info_ptr->unknown_chunks[num].data); + info_ptr->unknown_chunks[num].data = NULL; + } + } + else + { + int i; + + if(info_ptr->unknown_chunks_num) + { + for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks_num = 0; + } + } +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +/* free any hIST entry */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_HIST) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) +#endif +{ + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; +#endif +} +#endif + +/* free any PLTE entry that was internally allocated */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) +#else +if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) +#endif +{ + png_zfree(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; +#endif + info_ptr->num_palette = 0; +} + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* free any image bits attached to the info structure */ +#ifdef PNG_FREE_ME_SUPPORTED +if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) +#else +if (mask & PNG_FREE_ROWS) +#endif +{ + if(info_ptr->row_pointers) + { + int row; + for (row = 0; row < (int)info_ptr->height; row++) + { + png_free(png_ptr, info_ptr->row_pointers[row]); + info_ptr->row_pointers[row]=NULL; + } + png_free(png_ptr, info_ptr->row_pointers); + info_ptr->row_pointers=NULL; + } + info_ptr->valid &= ~PNG_INFO_IDAT; +} +#endif + +#ifdef PNG_FREE_ME_SUPPORTED + if(num == -1) + info_ptr->free_me &= ~mask; + else + info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); +#endif +} + +/* This is an internal routine to free any memory that the info struct is + * pointing to before re-using it or freeing the struct itself. Recall + * that png_free() checks for NULL pointers for us. + */ +void /* PRIVATE */ +png_info_destroy(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_info_destroy\n"); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + png_ptr->num_chunk_list=0; + } +#endif + + png_info_init_3(&info_ptr, png_sizeof(png_info)); +} +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +/* This function returns a pointer to the io_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy() or png_read_destroy() are called. + */ +png_voidp PNGAPI +png_get_io_ptr(png_structp png_ptr) +{ + if(png_ptr == NULL) return (NULL); + return (png_ptr->io_ptr); +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#if !defined(PNG_NO_STDIO) +/* Initialize the default input/output functions for the PNG file. If you + * use your own read or write routines, you can call either png_set_read_fn() + * or png_set_write_fn() instead of png_init_io(). If you have defined + * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't + * necessarily available. + */ +void PNGAPI +png_init_io(png_structp png_ptr, png_FILE_p fp) +{ + png_debug(1, "in png_init_io\n"); + if(png_ptr == NULL) return; + png_ptr->io_ptr = (png_voidp)fp; +} +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +/* Convert the supplied time into an RFC 1123 string suitable for use in + * a "Creation Time" or other text-based time string. + */ +png_charp PNGAPI +png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) +{ + static PNG_CONST char short_months[12][4] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + if(png_ptr == NULL) return (NULL); + if (png_ptr->time_buffer == NULL) + { + png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* + png_sizeof(char))); + } + +#if defined(_WIN32_WCE) + { + wchar_t time_buf[29]; + wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"), + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); + WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29, + NULL, NULL); + } +#else +#ifdef USE_FAR_KEYWORD + { + char near_time_buf[29]; + sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000", + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); + png_memcpy(png_ptr->time_buffer, near_time_buf, + 29*png_sizeof(char)); + } +#else + sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000", + ptime->day % 32, short_months[(ptime->month - 1) % 12], + ptime->year, ptime->hour % 24, ptime->minute % 60, + ptime->second % 61); +#endif +#endif /* _WIN32_WCE */ + return ((png_charp)png_ptr->time_buffer); +} +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + +#if 0 +/* Signature string for a PNG file. */ +png_bytep PNGAPI +png_sig_bytes(void) +{ + return ((png_bytep)"\211\120\116\107\015\012\032\012"); +} +#endif +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +png_charp PNGAPI +png_get_copyright(png_structp png_ptr) +{ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) "\n libpng version 1.2.18 - May 15, 2007\n\ + Copyright (c) 1998-2007 Glenn Randers-Pehrson\n\ + Copyright (c) 1996-1997 Andreas Dilger\n\ + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); + return ((png_charp) ""); +} + +/* The following return the library version as a short string in the + * format 1.0.0 through 99.99.99zz. To get the version of *.h files + * used with your application, print out PNG_LIBPNG_VER_STRING, which + * is defined in png.h. + * Note: now there is no difference between png_get_libpng_ver() and + * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, + * it is guaranteed that png.c uses the correct version of png.h. + */ +png_charp PNGAPI +png_get_libpng_ver(png_structp png_ptr) +{ + /* Version of *.c files used when building libpng */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); + return ((png_charp) ""); +} + +png_charp PNGAPI +png_get_header_ver(png_structp png_ptr) +{ + /* Version of *.h files used when building libpng */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); + return ((png_charp) ""); +} + +png_charp PNGAPI +png_get_header_version(png_structp png_ptr) +{ + /* Returns longer string containing both version and date */ + if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_HEADER_VERSION_STRING); + return ((png_charp) ""); +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) +{ + /* check chunk_name and return "keep" value if it's on the list, else 0 */ + int i; + png_bytep p; + if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0) + return 0; + p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5; + for (i = png_ptr->num_chunk_list; i; i--, p-=5) + if (!png_memcmp(chunk_name, p, 4)) + return ((int)*(p+4)); + return 0; +} +#endif + +/* This function, added to libpng-1.0.6g, is untested. */ +int PNGAPI +png_reset_zstream(png_structp png_ptr) +{ + if (png_ptr == NULL) return Z_STREAM_ERROR; + return (inflateReset(&png_ptr->zstream)); +} +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +/* This function was added to libpng-1.0.7 */ +png_uint_32 PNGAPI +png_access_version_number(void) +{ + /* Version of *.c files used when building libpng */ + return((png_uint_32) PNG_LIBPNG_VER); +} + + +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) +#if defined(PNG_MMX_CODE_SUPPORTED) +/* this INTERNAL function was added to libpng 1.2.0 */ +void /* PRIVATE */ +png_init_mmx_flags (png_structp png_ptr) +{ + if(png_ptr == NULL) return; + png_ptr->mmx_rowbytes_threshold = 0; + png_ptr->mmx_bitdepth_threshold = 0; + +# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD)) + + png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED; + + if (png_mmx_support() > 0) { + png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU +# ifdef PNG_HAVE_MMX_COMBINE_ROW + | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW +# endif +# ifdef PNG_HAVE_MMX_READ_INTERLACE + | PNG_ASM_FLAG_MMX_READ_INTERLACE +# endif +# ifndef PNG_HAVE_MMX_READ_FILTER_ROW + ; +# else + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB + | PNG_ASM_FLAG_MMX_READ_FILTER_UP + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + + png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT; + png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT; +# endif + } else { + png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU + | PNG_MMX_READ_FLAGS + | PNG_MMX_WRITE_FLAGS ); + } + +# else /* !(PNGVCRD || PNGGCCRD) */ + + /* clear all MMX flags; no support is compiled in */ + png_ptr->asm_flags &= ~( PNG_MMX_FLAGS ); + +# endif /* ?(PNGVCRD || PNGGCCRD) */ +} + +#endif /* !(PNG_MMX_CODE_SUPPORTED) */ + +/* this function was added to libpng 1.2.0 */ +#if !defined(PNG_USE_PNGGCCRD) && \ + !(defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)) +int PNGAPI +png_mmx_support(void) +{ + return -1; +} +#endif +#endif /* PNG_1_0_X && PNG_ASSEMBLER_CODE_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#ifdef PNG_SIZE_T +/* Added at libpng version 1.2.6 */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +png_size_t PNGAPI +png_convert_size(size_t size) +{ + if (size > (png_size_t)-1) + PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ + return ((png_size_t)size); +} +#endif /* PNG_SIZE_T */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/src/dep/src/irrlicht/libpng/png.h b/src/dep/src/irrlicht/libpng/png.h new file mode 100644 index 0000000..f19cf81 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/png.h @@ -0,0 +1,3523 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.2.18 - May 15, 2007 + * Copyright (c) 1998-2007 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.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.18 - May 15, 2007: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 10.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.2.13beta1 13 10213 12.so.0.13[.0] + * 1.0.21 10 10021 10.so.0.21[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.2.14beta1-2 13 10214 12.so.0.14[.0] + * 1.0.22rc1 10 10022 10.so.0.22[.0] + * 1.2.14rc1 13 10214 12.so.0.14[.0] + * 1.0.22 10 10022 10.so.0.22[.0] + * 1.2.14 13 10214 12.so.0.14[.0] + * 1.2.15beta1-6 13 10215 12.so.0.15[.0] + * 1.0.23rc1-5 10 10023 10.so.0.23[.0] + * 1.2.15rc1-5 13 10215 12.so.0.15[.0] + * 1.0.23 10 10023 10.so.0.23[.0] + * 1.2.15 13 10215 12.so.0.15[.0] + * 1.2.16beta1-2 13 10216 12.so.0.16[.0] + * 1.2.16rc1 13 10216 12.so.0.16[.0] + * 1.0.24 10 10024 10.so.0.24[.0] + * 1.2.16 13 10216 12.so.0.16[.0] + * 1.2.17beta1-2 13 10217 12.so.0.17[.0] + * 1.0.25rc1 10 10025 10.so.0.25[.0] + * 1.2.17rc1-3 13 10217 12.so.0.17[.0] + * 1.0.25 10 10025 10.so.0.25[.0] + * 1.2.17 13 10217 12.so.0.17[.0] + * 1.0.26 10 10026 10.so.0.26[.0] + * 1.2.18 13 10218 12.so.0.18[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO Specification, + * defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + png_error_ptr warning_fn; /* function for printing warnings */ + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_size_t zbuf_size; /* size of zbuf */ + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 irowbytes; /* size of current interlaced row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf; /* buffer to save current (unfiltered) row */ + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ + png_row_info row_info; /* used for transformation routines */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler; /* filler byte for pixel expansion */ +#else + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif +#endif + +#if defined(PNG_bKGD_SUPPORTED) + png_byte background_gamma_type; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma; +# endif + png_color_16 background; /* background color in screen gamma space */ +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma; /* file gamma value */ + float screen_gamma; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ + png_color_16 trans_values; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# if defined(PNG_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytep palette_lookup; /* lookup table for dithering */ + png_bytep dither_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_charp time_buffer; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + int num_chunk_list; + png_bytep chunk_list; +#endif + +/* New members added in libpng-1.0.3 */ +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_byte rgb_to_gray_status; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + png_uint_16 rgb_to_gray_blue_coeff; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else + png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_byte filter_type; +#endif + +#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size; +#endif + +/* New members added in libpng-1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +# if !defined(PNG_1_0_X) +# if defined(PNG_MMX_CODE_SUPPORTED) + png_byte mmx_bitdepth_threshold; + png_uint_32 mmx_rowbytes_threshold; +# endif + png_uint_32 asm_flags; +# endif +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif +}; + + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef png_structp version_1_2_18; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); +#endif + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)); + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ + png_sizeof(png_info)); +#endif + +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* _WIN32_WCE */ + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +#endif +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)); +#endif +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); +#endif + +/* write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)); + +/* set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#if !defined(PNG_NO_STDIO) +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)); + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + +/* frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)); +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)); + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)); + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* Returns row_pointers, which is an array of pointers to scanlines that was +returned from png_read_png(). */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use +by png_write_png(). */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#if defined(PNG_TEXT_SUPPORTED) +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behaviour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + If you need to turn it off for a chunk that your application has freed, + you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include +#if (PNG_DEBUG > 1) +#define png_debug(l,m) _RPT0(_CRT_WARN,m) +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ +#if (PNG_DEBUG > 1) +#define png_debug(l,m) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ +} +#define png_debug1(l,m,p1) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ +} +#define png_debug2(l,m,p1,p2) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ +} +#endif /* (PNG_DEBUG > 1) */ +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +#if 0 +extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void)); +#endif + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 +#endif /* PNG_MMX_CODE_SUPPORTED */ + +#if !defined(PNG_1_0_X) +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ + +#if !defined(PNG_1_0_X) +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif + +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp + png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp + png_ptr)); +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp + png_ptr)); +#endif + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + + +/* Various modes of operation, that are visible to applications because + * they are used for unknown chunk location. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ +#define PNG_HAVE_IEND 0x10 + +#if defined(PNG_INTERNAL) + +/* More modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ +#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +/* flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ + (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + ideal-delta..ideal+delta. Each argument is evaluated twice. + "ideal" and "delta" should be constants, normally simple + integers, "value" a variable. Added to libpng-1.2.6 JB */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8]; +#else +#if 0 +#define png_sig png_sig_bytes(NULL) +#endif +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +#ifdef PNG_SIZE_T +/* Function to convert a sizeof an item to png_sizeof item */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +#endif + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); + +/* write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point + file_gamma)); +#endif +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)); +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)); +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)); +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)); +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)); +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)); +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)); +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)); +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)); +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); +#endif + +/* combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +/* expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)); +/* finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); +/* optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* these are the functions that do the transformations */ +#if defined(PNG_READ_FILLER_SUPPORTED) +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); + +# if defined(PNG_CORRECT_PALETTE_SUPPORTED) +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)); +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#if defined(PNG_READ_bKGD_SUPPORTED) +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_gAMA_SUPPORTED) +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_sRGB_SUPPORTED) +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)); + +/* handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); + +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_pHYs_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* do not put anything past this line */ +#endif /* PNG_H */ diff --git a/src/dep/src/irrlicht/libpng/pngbar.jpg b/src/dep/src/irrlicht/libpng/pngbar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70ba8d817ce433788c7933dbe3c29c3e384b2b0a GIT binary patch literal 2498 zcmb79cR1UN8veLX-}`>=f8Y0x?_}m=8Q`%n#hU_5OiaM90Zxtq1>=CgTfsNH zyhE`{nwsjeShHXcFRV>~hi`yq2v*YHBRtd~Fu*+^LY^4lCw1}#Lva_%-vvRO=aKPAMFitLB9!@Se7YxRO;(_xakVqs4H@^T1A;613B7T`LfloCM zC>s>YhTw#8BK~ij^a5~J00TIJnM42(oCyqPI(Y@00RRyA^t=CpnFWBbLcymyB_03- z0x_M|W@3T<`-BN}TAvxt!Yd50@*zZ&*pN77LnCW9lz^y8aNMcnEYqn3{J(Y(W-t^0 zvHZ$XfCC^V5CqH&h5jdw2?Phg5ME(JD6^7?wOdfuSH8H0zP}N;;+36~Ie_ET2?Phj z0ewJu_XPOzrM!FkVBFSWa?9PHSVQF9@l6YED#^WWRML1J9VDQieoKN{=G;@B(Vmqw zMZd`y)ni0|7a{dGH#QBu4Xb>^8Ml-38dtbR*{4J6CiE}A`n<^Swi_b~53dp@Oz5&x zqIb>@R2bY|^Eg5Q^oZrcolUy~e~ev4`E;SpK(~nwOpGHYx7IEN6TgtCZ%ql2@{}O= zB=jD|t!NkbZ`gujXu2t1GZEV?OI;QB^sVbc{HllYU92vX0u%;zs?5Dy7i5b^Vr}Pn zO2G4GXu7^$QmgA^)I4+H4Ve#&F8{pR>+ENwX4HwzetiUp&~J{h-wxp)&2&qMG9ULl z$1sGXW1&H@50#Izy=lZUfjypz`|x(CS!BmIDmt4<-iM+7vJJYh6Ok&Y`9uLDz-dii|{T@&nMOnhYGW-(Yq<%v= zZ{=JMeWTwA?P4UG8a$$%3#A_D7*<`B{srsRec$8y$6ez;HO0+<=@)~a+C#KD$fFie zOF5lh(}n6`?kJ=#rB8?(qO_~`d`n%$zP0)o`DHOCeo?6M-Pn1fN6p1D_{#*0&JIPU zL@9JFTVPL!MG(xN{Pyi$)cs@-UVOt7&mCx*p!Qt+LYRroDYFGACZJ{8Pxa zhc4YRL#jc2?yi*%aQ(San~2E>xW1QR0J9uq>9 zE|N+~DEC)g{=F~&W?nheQJ?`Q<2i%Wz?M||p-DL5&AOs`qIe3z=N#%2ExTl7#Mi~t zZTvmnY2L6RG=bnbgRr9M+u}{jp7ydMJN^)W@t){SwRelgUb%&^y1 zM;W@kz|uUoUabJ?0dbrrlPe>APntXLz&pJ5ZWI7}GEh1`;2^(^ytgu48%@k}`m_4R zx8US1L-x+#p75_R@wMZVM}ykuYvioTTGW)v@utp6&FdCbVm5jv1($E4n`7P(vX8P^ zVZA#7-KlKgbTX}&!a_R%ta^0&^b~I$WKg~SIROeW8CO-de{#3jS6!TXFi85;P@Hrz zD3>)2F0f1;VrK&%21hW;jd0Cjw4?npnIr&aVCT_ zW9a^Bg^fd&pImbNpxTP+{rooTc`NU48`F^mV8?f=97sYHnM7{LO)G6#omwpLj@zjk z*`m5o3~<=GP;|qAvDunf<-pg& zIH~t>Us-XJV%rkrKOD99=3flubRj$V{UNE2PCJI@Qi7&wDXM|x@Dll=Tj)D@Y(u1P z7_yCfQ%}|zKKprCcz*XtvG}TKViW44NE~ZF&3pW4f2!sm`cI`U`Bl!2_PqS3Dvok5 z=2eTiaWh#`Q&nhOeYk8Y2gu}DUKS%W-&K5bD>U`DQo92*Z9Jvl-A7zo%D^O5+z3*TS2sjBs^v)SGJg_-$$y+3;FN@u#o{#rqd z=-;Zemc);1)~-n;ZNYgD*QCx)qTS?(6>`Yxu0|T02j9{jA-iY!XBs6VtKgN(?M>3M zXitp$#9|Y^aqefnpO5s_bc&VI`Mol8lb36szrH?8J9^Y{Sh=Zut;vy9EAFY*!eBw< zUh1>Fup<1+##XO=O2huD7w?@yH~akK6(i-EANrw@1tl$;?SdE;AJIJyTU&yrti_SX zqL2K}JyH4R*vHyPyly4H@@Qky6>b`Z!-~dp<=^<0ql8jCIzJ{n2`02PuA?k^A&hB? zljJT{WGG{Bb%mft`m0YCNhgQcH?}Ga`o4KT7r9mpTO|G-ajjf)rUae~l{ z0Rja6`T3xspr4_iba{e!dVHCinSz3e@1>=%j($2G9;~mjBv2nTG{hSR28W4<;$UEa zfq+#nVBJJS0RaHmC@AQFfQX5U(+mu00070t%A%vz78nt@y3y1S5N2m)Kc7E!n|s1o zS3*LZ`|ImCIy_xnT}Vn#B_<}-6cj!`B>eC1D=aTfO-&XS7mt#WfPvpvG$H~507gef za(0FG_V)er^K^NAv$WC-3=ME`ynZ!EiHe1F4i6%tFFzXq(o3jLNqluBO@b zVbTT$78e$QPf^Cm#xylL6B84MYEWEsVPscG4Gj%}gp7rShJJ*J1_uTQ1qZgcwgm+R zTU=lS0|Z`PB(t=$0s#U60RaF30IsgC78d%fuB?oX+;MYqIXXKmDvVH6GZr>DJ8*F|pP|?3h={zu&lnR8iH(zuj*X0tj8%hK4-gJ}V^=2} z6>oEP2?_mre}vT-7)}5HC?_Km6cv1ad;tIecYA?^h0qZY6Aum%b9;T@R8)kCkwQa5 zadmqS2M0SlJZ)}m(EtEcS6dMa3_n3bUt?)wWMf%cS%!(3`QP6|MM@eP`5+-7d3AOF z|Nm+%D{E|VNkkrIXlz47LkkNGKtMq3?d<#K=S5UV_RGudo}K{#0%vG&=I7>ARK#Xx zZ!^wXXe#HK_DO?>Sbn6Qdo$IQAs2u8X6iK7#qpU$!=|P zH#j{eCMlYoeM(75KtVqc5c_+8WeN%km6n;gySbjFueP_g0|EoHwX*;K|7dG)!Bu-G z000IGNklHt z*vcw)0ZfC}7KY%R=*angFf7GDQDX{kit>gDqYzS58b_&yP)Sh~f_vJw^;p^2y#yCM zISs%G832=BMOOfjy#g7m@ zt+jh(w*X#u^vDspeASlpa4&Rno;k@j!sy{`WCR+Uq@`vIjHM+IP*3zXu&|I&vvBhr zt5-6<$;<(2f0#8w1lUp z1?ZrY7`SR}R`W7r#`?tgl6cdPoX?M$DvQtWI;4E?_jQN%)H5pc$G$QI+vc!SEpCkx z#+g9_7fww>9KozuLwWI;j6+9TpAhcZ3t)y?l zdFG(xs{LWrE9KT-raI@mim4p&N{FMfnYvkx$&R<(ms07RfJb`ikXw53l+@$=(}P z?MpK-^c){YFoBt|a4?lG5TfY@J<<>?PQod%2Mgco&28>|0SA}+mYBOllOs`!S5By% zPP)yMN8hY0FHucYC;n_6!ovRAX#_Va6gmb@(5FOo!%@D@y8%T(VK`nksAFI>hf954 z%;R4p&z*B}R#o1+ANee}?qI;Zm|;~&O?-uKytC6Dx4SG1Pcbm+Lj?nKq_BGlH;X_Kt|nbMUG0>1pkOx7k6gb9<~7 zEJCZ>+w;OZRw?IW&lmbl5aqEGH3-e+iMsSUx=|fB7lp(Cl}Z05;e)elg=25lhPU3OFC-`X4O~Pp z(+u8SxX6@Nu-gU$cM%?iDf;}>eg@uPwZ7NbAfwc4%LKv$AESApwMAQTgR)Bj)d}7P zwCAfKkJo5opoC@6Lg<3Mcwvcs4!^5<=}qW6{9VgWp{KyaBpI7crIgaZ7IUp RQSJZ$002ovPDHLkV1iCKFfIT9 literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/pngconf.h b/src/dep/src/irrlicht/libpng/pngconf.h new file mode 100644 index 0000000..f1c2767 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngconf.h @@ -0,0 +1,1483 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.2.18 - May 15, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#define PNG_1_2_X + +/* + * PNG_USER_CONFIG has to be defined on the compiler command line. This + * includes the resource compiler for Windows DLL configurations. + */ +#ifdef PNG_USER_CONFIG +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif +#include "pngusr.h" +#endif + +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #define PNG_USER_PRIVATEBUILD + * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." + * #define PNG_USER_DLLFNAME_POSTFIX + * e.g. // private DLL "libpng13gx.dll" + * #define PNG_USER_DLLFNAME_POSTFIX "gx" + * + * The following macros are also at your disposal if you want to complete the + * DLL VERSIONINFO structure. + * - PNG_USER_VERSIONINFO_COMMENTS + * - PNG_USER_VERSIONINFO_COMPANYNAME + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS + */ + +#ifdef __STDC__ +#ifdef SPECIALBUILD +# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") +#endif + +#ifdef PRIVATEBUILD +# pragma message("PRIVATEBUILD is deprecated.\ + Use PNG_USER_PRIVATEBUILD instead.") +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif +#endif /* __STDC__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + support PNGs that are embedded in MNG datastreams */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#if defined(__CYGWIN__) +# if defined(ALL_STATIC) +# if defined(PNG_BUILD_DLL) +# undef PNG_BUILD_DLL +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# if !defined(PNG_STATIC) +# define PNG_STATIC +# endif +# else +# if defined (PNG_BUILD_DLL) +# if defined(PNG_STATIC) +# undef PNG_STATIC +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# else +# if defined(PNG_STATIC) +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# else +# if !defined(PNG_USE_DLL) +# define PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#if defined(_WIN32_WCE) +# include + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include +# endif +# endif +# else +# if !defined(_WIN32_WCE) +/* "stdio.h" functions are not supported on WindowsCE */ +# include +# endif +# endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + */ + +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + /* If you encounter a compiler error here, see the explanation + * near the end of INSTALL. + */ + __png.h__ already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ + + /* include setjmp.h for error handling */ +# include + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# define _BSD_SOURCE +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include +#else +# include +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) +# if defined(MACOS) + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +/* I have no idea why is this necessary... */ +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt support was added. iTXt support was turned off by default through + * libpng-1.2.x, to support old apps that malloc the png_text structure + * instead of calling png_set_text() and letting libpng malloc it. It + * was turned on by default in libpng-1.3.0. + */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt +# define PNG_NO_READ_iTXt +# endif +# ifndef PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_iTXt +# endif +#endif + +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#if defined(PNG_READ_SUPPORTED) + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following line: */ + +#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_WRITE_SUPPORTED) + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ +#endif + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + !defined(PNG_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_1_0_X +# ifndef PNG_NO_ERROR_NUMBERS +# define PNG_ERROR_NUMBERS_SUPPORTED +# endif +#endif /* PNG_1_0_X */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + * even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined. + * + * PNG_NO_ASSEMBLER_CODE disables use of all assembler code and optimized C, + * and removes or includes several functions in the API. + * + * PNG_NO_MMX_CODE disables the use of MMX code without changing the API. + * When MMX code is off, then optimized C replacement functions are used. +*/ +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif +# if defined(XP_MACOSX) && !defined(PNG_NO_MMX_CODE) + /* work around Intel-Mac compiler bug */ +# define PNG_NO_MMX_CODE +# endif +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) && \ + defined(__MMX__) +# define PNG_MMX_CODE_SUPPORTED +# endif +# if !defined(PNG_USE_PNGGCCRD) && !defined(PNG_NO_MMX_CODE) && \ + !defined(PNG_USE_PNGVCRD) && defined(__MMX__) +# define PNG_USE_PNGGCCRD +# endif +#endif + +/* If you are sure that you don't need thread safety and you are compiling + with PNG_USE_PNGCCRD for an MMX application, you can define this for + faster execution. See pnggccrd.c. +#define PNG_THREAD_UNSAFE_OK +*/ + +#if !defined(PNG_1_0_X) +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#if !defined(PNG_1_0_X) +#ifndef PNG_SET_USER_LIMITS_SUPPORTED +#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED) +# define PNG_SET_USER_LIMITS_SUPPORTED +#endif +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter + * how large, set these limits to 0x7fffffffL + */ +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* need the time information for reading tIME chunks */ +#if defined(PNG_tIME_SUPPORTED) +# if !defined(_WIN32_WCE) + /* "time.h" functions are not supported on WindowsCE */ +# include +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned int png_uint_32; +typedef int png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +#ifdef PNG_SIZE_T + typedef PNG_SIZE_T png_size_t; +# define png_sizeof(x) png_convert_size(sizeof (x)) +#else + typedef size_t png_size_t; +# define png_sizeof(x) sizeof (x) +#endif + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#if defined(FAR) +# if defined(M_I86MM) +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#if defined(_WIN32_WCE) +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.3.0 - GR-P */ +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#if defined(__CYGWIN__) +# if !defined(PNG_STATIC) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL)) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# ifndef PNGAPI +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# if !defined(PNG_IMPEXP) + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# if !defined(PNG_IMPEXP) +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# ifndef PNGAPI +# define PNGAPI _System +# endif +# else +# if 0 /* ... other platforms, with other meanings */ +# endif +# endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#if defined(USE_FAR_KEYWORD) /* memory model independent fns */ +/* use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strcpy _fstrcpy +# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy strcpy +# define png_strncpy strncpy /* Added to v 1.2.6 */ +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +#ifdef PNG_READ_SUPPORTED +/* Prior to libpng-1.0.9, this block was in pngasmrd.h */ +#if defined(PNG_INTERNAL) + +/* These are the default thresholds before the MMX code kicks in; if either + * rowbytes or bitdepth is below the threshold, plain C code is used. These + * can be overridden at runtime via the png_set_mmx_thresholds() call in + * libpng 1.2.0 and later. The values below were chosen by Intel. + */ + +#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT +# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */ +#endif +#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT +# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */ +#endif + +/* Set this in the makefile for VC++ on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pngvcrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGVCRD +# define PNG_HAVE_MMX_COMBINE_ROW +# define PNG_HAVE_MMX_READ_INTERLACE +# define PNG_HAVE_MMX_READ_FILTER_ROW +#endif + +/* Set this in the makefile for gcc/as on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pnggccrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGGCCRD +# define PNG_HAVE_MMX_COMBINE_ROW +# define PNG_HAVE_MMX_READ_INTERLACE +# define PNG_HAVE_MMX_READ_FILTER_ROW +#endif +/* - see pnggccrd.c for info about what is currently enabled */ + +#endif /* PNG_INTERNAL */ +#endif /* PNG_READ_SUPPORTED */ + +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGCONF_H */ diff --git a/src/dep/src/irrlicht/libpng/pngerror.c b/src/dep/src/irrlicht/libpng/pngerror.c new file mode 100644 index 0000000..ddc96cd --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngerror.c @@ -0,0 +1,320 @@ + +/* 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; iflags&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)) +const 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 */ diff --git a/src/dep/src/irrlicht/libpng/pnggccrd.c b/src/dep/src/irrlicht/libpng/pnggccrd.c new file mode 100644 index 0000000..08ab5e2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pnggccrd.c @@ -0,0 +1,5420 @@ + +/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file + * + * For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler. + * + * See http://www.intel.com/drg/pentiumII/appnotes/916/916.htm + * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm + * for Intel's performance analysis of the MMX vs. non-MMX code. + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 Glenn Randers-Pehrson + * Copyright (c) 1998, Intel Corporation + * + * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. + * Interface to libpng contributed by Gilles Vollant, 1999. + * GNU C port by Greg Roelofs, 1999-2001. + * + * Lines 2350-4300 converted in place with intel2gas 1.3.1: + * + * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c + * + * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ . + * + * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows) + * is required to assemble the newer MMX instructions such as movq. + * For djgpp, see + * + * ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu281b.zip + * + * (or a later version in the same directory). For Linux, check your + * distribution's web site(s) or try these links: + * + * http://rufus.w3.org/linux/RPM/binutils.html + * http://www.debian.org/Packages/stable/devel/binutils.html + * ftp://ftp.slackware.com/pub/linux/slackware/slackware/slakware/d1/ + * binutils.tgz + * + * For other platforms, see the main GNU site: + * + * ftp://ftp.gnu.org/pub/gnu/binutils/ + * + * Version 2.5.2l.15 is definitely too old... + */ + +/* + * TEMPORARY PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs) + * ===================================== + * + * 19991006: + * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases) + * + * 19991007: + * - additional optimizations (possible or definite): + * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested] + * - write MMX code for 48-bit case (pixel_bytes == 6) + * - figure out what's up with 24-bit case (pixel_bytes == 3): + * why subtract 8 from width_mmx in the pass 4/5 case? + * (only width_mmx case) (near line 1606) + * x [DONE] replace pixel_bytes within each block with the true + * constant value (or are compilers smart enough to do that?) + * - rewrite all MMX interlacing code so it's aligned with + * the *beginning* of the row buffer, not the end. This + * would not only allow one to eliminate half of the memory + * writes for odd passes (that is, pass == odd), it may also + * eliminate some unaligned-data-access exceptions (assuming + * there's a penalty for not aligning 64-bit accesses on + * 64-bit boundaries). The only catch is that the "leftover" + * pixel(s) at the end of the row would have to be saved, + * but there are enough unused MMX registers in every case, + * so this is not a problem. A further benefit is that the + * post-MMX cleanup code (C code) in at least some of the + * cases could be done within the assembler block. + * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing, + * inconsistent, and don't match the MMX Programmer's Reference + * Manual conventions anyway. They should be changed to + * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that + * was lowest in memory (e.g., corresponding to a left pixel) + * and b7 is the byte that was highest (e.g., a right pixel). + * + * 19991016: + * - Brennan's Guide notwithstanding, gcc under Linux does *not* + * want globals prefixed by underscores when referencing them-- + * i.e., if the variable is const4, then refer to it as const4, + * not _const4. This seems to be a djgpp-specific requirement. + * Also, such variables apparently *must* be declared outside + * of functions; neither static nor automatic variables work if + * defined within the scope of a single function, but both + * static and truly global (multi-module) variables work fine. + * + * 19991023: + * - fixed png_combine_row() non-MMX replication bug (odd passes only?) + * - switched from string-concatenation-with-macros to cleaner method of + * renaming global variables for djgpp--i.e., always use prefixes in + * inlined assembler code (== strings) and conditionally rename the + * variables, not the other way around. Hence _const4, _mask8_0, etc. + * + * 19991024: + * - fixed mmxsupport()/png_do_read_interlace() first-row bug + * This one was severely weird: even though mmxsupport() doesn't touch + * ebx (where "row" pointer was stored), it nevertheless managed to zero + * the register (even in static/non-fPIC code--see below), which in turn + * caused png_do_read_interlace() to return prematurely on the first row of + * interlaced images (i.e., without expanding the interlaced pixels). + * Inspection of the generated assembly code didn't turn up any clues, + * although it did point at a minor optimization (i.e., get rid of + * mmx_supported_local variable and just use eax). Possibly the CPUID + * instruction is more destructive than it looks? (Not yet checked.) + * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly + * listings... Apparently register spillage has to do with ebx, since + * it's used to index the global offset table. Commenting it out of the + * input-reg lists in png_combine_row() eliminated compiler barfage, so + * ifdef'd with __PIC__ macro: if defined, use a global for unmask + * + * 19991107: + * - verified CPUID clobberage: 12-char string constant ("GenuineIntel", + * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish. + * + * 19991120: + * - made "diff" variable (now "_dif") global to simplify conversion of + * filtering routines (running out of regs, sigh). "diff" is still used + * in interlacing routines, however. + * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX + * macro determines which is used); original not yet tested. + * + * 20000213: + * - when compiling with gcc, be sure to use -fomit-frame-pointer + * + * 20000319: + * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case, + * pass == 4 or 5, that caused visible corruption of interlaced images + * + * 20000623: + * - Various problems were reported with gcc 2.95.2 in the Cygwin environment, + * many of the form "forbidden register 0 (ax) was spilled for class AREG." + * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and + * Chuck Wilson supplied a patch involving dummy output registers. See + * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624 + * for the original (anonymous) SourceForge bug report. + * + * 20000706: + * - Chuck Wilson passed along these remaining gcc 2.95.2 errors: + * pnggccrd.c: In function `png_combine_row': + * pnggccrd.c:525: more than 10 operands in `asm' + * pnggccrd.c:669: more than 10 operands in `asm' + * pnggccrd.c:828: more than 10 operands in `asm' + * pnggccrd.c:994: more than 10 operands in `asm' + * pnggccrd.c:1177: more than 10 operands in `asm' + * They are all the same problem and can be worked around by using the + * global _unmask variable unconditionally, not just in the -fPIC case. + * Reportedly earlier versions of gcc also have the problem with more than + * 10 operands; they just don't report it. Much strangeness ensues, etc. + * + * 20000729: + * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted + * MMX routine); began converting png_read_filter_row_mmx_sub() + * - to finish remaining sections: + * - clean up indentation and comments + * - preload local variables + * - add output and input regs (order of former determines numerical + * mapping of latter) + * - avoid all usage of ebx (including bx, bh, bl) register [20000823] + * - remove "$" from addressing of Shift and Mask variables [20000823] + * + * 20000731: + * - global union vars causing segfaults in png_read_filter_row_mmx_sub()? + * + * 20000822: + * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with + * shared-library (-fPIC) version! Code works just fine as part of static + * library. Damn damn damn damn damn, should have tested that sooner. + * ebx is getting clobbered again (explicitly this time); need to save it + * on stack or rewrite asm code to avoid using it altogether. Blargh! + * + * 20000823: + * - first section was trickiest; all remaining sections have ebx -> edx now. + * (-fPIC works again.) Also added missing underscores to various Shift* + * and *Mask* globals and got rid of leading "$" signs. + * + * 20000826: + * - added visual separators to help navigate microscopic printed copies + * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working + * on png_read_filter_row_mmx_avg() + * + * 20000828: + * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...) + * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not + * cleaned up/shortened in either routine, but functionality is complete + * and seems to be working fine. + * + * 20000829: + * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed + * as an input reg (with dummy output variables, etc.), then it *cannot* + * also appear in the clobber list or gcc 2.95.2 will barf. The solution + * is simple enough... + * + * 20000914: + * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled + * correctly (but 48-bit RGB just fine) + * + * 20000916: + * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors: + * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;" + * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;" + * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2" + * + * 20010101: + * - added new png_init_mmx_flags() function (here only because it needs to + * call mmxsupport(), which should probably become global png_mmxsupport()); + * modified other MMX routines to run conditionally (png_ptr->asm_flags) + * + * 20010103: + * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported, + * and made it public; moved png_init_mmx_flags() to png.c as internal func + * + * 20010104: + * - removed dependency on png_read_filter_row_c() (C code already duplicated + * within MMX version of png_read_filter_row()) so no longer necessary to + * compile it into pngrutil.o + * + * 20010310: + * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX) + * + * 20020304: + * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case + * + * 20040724: + * - more tinkering with clobber list at lines 4529 and 5033, to get + * it to compile on gcc-3.4. + * + * STILL TO DO: + * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) + * - write MMX code for 48-bit case (pixel_bytes == 6) + * - figure out what's up with 24-bit case (pixel_bytes == 3): + * why subtract 8 from width_mmx in the pass 4/5 case? + * (only width_mmx case) (near line 1606) + * - rewrite all MMX interlacing code so it's aligned with beginning + * of the row buffer, not the end (see 19991007 for details) + * x pick one version of mmxsupport() and get rid of the other + * - add error messages to any remaining bogus default cases + * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed) + * x add support for runtime enable/disable/query of various MMX routines + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGGCCRD) + +int PNGAPI png_mmx_support(void); + +#ifdef PNG_USE_LOCAL_ARRAYS +const static int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; +const static int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +const static int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; +#endif + +#if defined(PNG_MMX_CODE_SUPPORTED) +/* djgpp, Win32, Cygwin, and OS2 add their own underscores to global variables, + * so define them without: */ +#if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__OS2__) +# define _mmx_supported mmx_supported +# define _const4 const4 +# define _const6 const6 +# define _mask8_0 mask8_0 +# define _mask16_1 mask16_1 +# define _mask16_0 mask16_0 +# define _mask24_2 mask24_2 +# define _mask24_1 mask24_1 +# define _mask24_0 mask24_0 +# define _mask32_3 mask32_3 +# define _mask32_2 mask32_2 +# define _mask32_1 mask32_1 +# define _mask32_0 mask32_0 +# define _mask48_5 mask48_5 +# define _mask48_4 mask48_4 +# define _mask48_3 mask48_3 +# define _mask48_2 mask48_2 +# define _mask48_1 mask48_1 +# define _mask48_0 mask48_0 +# define _LBCarryMask LBCarryMask +# define _HBClearMask HBClearMask +# define _ActiveMask ActiveMask +# define _ActiveMask2 ActiveMask2 +# define _ActiveMaskEnd ActiveMaskEnd +# define _ShiftBpp ShiftBpp +# define _ShiftRem ShiftRem +#ifdef PNG_THREAD_UNSAFE_OK +# define _unmask unmask +# define _FullLength FullLength +# define _MMXLength MMXLength +# define _dif dif +# define _patemp patemp +# define _pbtemp pbtemp +# define _pctemp pctemp +#endif +#endif + + +/* These constants are used in the inlined MMX assembly code. + Ignore gcc's "At top level: defined but not used" warnings. */ + +/* GRR 20000706: originally _unmask was needed only when compiling with -fPIC, + * since that case uses the %ebx register for indexing the Global Offset Table + * and there were no other registers available. But gcc 2.95 and later emit + * "more than 10 operands in `asm'" errors when %ebx is used to preload unmask + * in the non-PIC case, so we'll just use the global unconditionally now. + */ +#ifdef PNG_THREAD_UNSAFE_OK +static int _unmask; +#endif + +const static unsigned long long _mask8_0 = 0x0102040810204080LL; + +const static unsigned long long _mask16_1 = 0x0101020204040808LL; +const static unsigned long long _mask16_0 = 0x1010202040408080LL; + +const static unsigned long long _mask24_2 = 0x0101010202020404LL; +const static unsigned long long _mask24_1 = 0x0408080810101020LL; +const static unsigned long long _mask24_0 = 0x2020404040808080LL; + +const static unsigned long long _mask32_3 = 0x0101010102020202LL; +const static unsigned long long _mask32_2 = 0x0404040408080808LL; +const static unsigned long long _mask32_1 = 0x1010101020202020LL; +const static unsigned long long _mask32_0 = 0x4040404080808080LL; + +const static unsigned long long _mask48_5 = 0x0101010101010202LL; +const static unsigned long long _mask48_4 = 0x0202020204040404LL; +const static unsigned long long _mask48_3 = 0x0404080808080808LL; +const static unsigned long long _mask48_2 = 0x1010101010102020LL; +const static unsigned long long _mask48_1 = 0x2020202040404040LL; +const static unsigned long long _mask48_0 = 0x4040808080808080LL; + +const static unsigned long long _const4 = 0x0000000000FFFFFFLL; +//const static unsigned long long _const5 = 0x000000FFFFFF0000LL; // NOT USED +const static unsigned long long _const6 = 0x00000000000000FFLL; + +// These are used in the row-filter routines and should/would be local +// variables if not for gcc addressing limitations. +// WARNING: Their presence probably defeats the thread safety of libpng. + +#ifdef PNG_THREAD_UNSAFE_OK +static png_uint_32 _FullLength; +static png_uint_32 _MMXLength; +static int _dif; +static int _patemp; // temp variables for Paeth routine +static int _pbtemp; +static int _pctemp; +#endif + +void /* PRIVATE */ +png_squelch_warnings(void) +{ +#ifdef PNG_THREAD_UNSAFE_OK + _dif = _dif; + _patemp = _patemp; + _pbtemp = _pbtemp; + _pctemp = _pctemp; + _MMXLength = _MMXLength; +#endif + _const4 = _const4; + _const6 = _const6; + _mask8_0 = _mask8_0; + _mask16_1 = _mask16_1; + _mask16_0 = _mask16_0; + _mask24_2 = _mask24_2; + _mask24_1 = _mask24_1; + _mask24_0 = _mask24_0; + _mask32_3 = _mask32_3; + _mask32_2 = _mask32_2; + _mask32_1 = _mask32_1; + _mask32_0 = _mask32_0; + _mask48_5 = _mask48_5; + _mask48_4 = _mask48_4; + _mask48_3 = _mask48_3; + _mask48_2 = _mask48_2; + _mask48_1 = _mask48_1; + _mask48_0 = _mask48_0; +} +#endif /* PNG_MMX_CODE_SUPPORTED */ + + +static int _mmx_supported = 2; + +/*===========================================================================*/ +/* */ +/* P N G _ C O M B I N E _ R O W */ +/* */ +/*===========================================================================*/ + +#if defined(PNG_HAVE_MMX_COMBINE_ROW) + +#define BPP2 2 +#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ +#define BPP4 4 +#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ +#define BPP8 8 + +/* Combines the row recently read in with the previous row. + This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined; a + zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. + If you want all pixels to be combined, pass 0xff (255) in mask. */ + +/* Use this routine for the x86 platform - it uses a faster MMX routine + if the machine supports MMX. */ + +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ + png_debug(1, "in png_combine_row (pnggccrd.c)\n"); + +#if defined(PNG_MMX_CODE_SUPPORTED) + if (_mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif + + if (mask == 0xff) + { + png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); + png_memcpy(row, png_ptr->row_buf + 1, + (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width)); + } + else /* (png_combine_row() is never called with mask == 0) */ + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_inc, s_start, s_end; + int m; + int shift; + png_uint_32 i; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x1; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 2: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x3; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 4: /* png_ptr->row_info.pixel_depth */ + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 8: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask8_0, %%mm0 \n\t" + "pand %%mm7, %%mm0 \n\t" // nonzero if keep byte + "pcmpeqb %%mm6, %%mm0 \n\t" // zeros->1s, v versa + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" // len == 0 ? + "je mainloop8end \n\t" + + "mainloop8: \n\t" + "movq (%%esi), %%mm4 \n\t" // *srcptr + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "pandn (%%edi), %%mm6 \n\t" // *dstptr + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + "addl $8, %%esi \n\t" // inc by 8 bytes processed + "addl $8, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop8 \n\t" + + "mainloop8end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end8 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop8: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip8 \n\t" // if CF = 0 + "movb (%%esi), %%al \n\t" + "movb %%al, (%%edi) \n\t" + + "skip8: \n\t" + "incl %%esi \n\t" + "incl %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop8 \n\t" + + "end8: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm4", "%mm6", "%mm7" // clobber list +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff /* *BPP1 */ ; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + + } /* end of else (_mmx_supported) */ + + break; + } /* end 8 bpp */ + + case 16: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask16_0, %%mm0 \n\t" + "movq _mask16_1, %%mm1 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop16end \n\t" + + "mainloop16: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "addl $16, %%esi \n\t" // inc by 16 bytes processed + "addl $16, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop16 \n\t" + + "mainloop16end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end16 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop16: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip16 \n\t" // if CF = 0 + "movw (%%esi), %%ax \n\t" + "movw %%ax, (%%edi) \n\t" + + "skip16: \n\t" + "addl $2, %%esi \n\t" + "addl $2, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop16 \n\t" + + "end16: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=c" (dummy_value_c), + "=d" (dummy_value_d), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (diff), // eax // input regs +// was (unmask) " " RESERVED // ebx // Global Offset Table idx + "1" (len), // ecx + "2" (mask), // edx + "3" (srcptr), // esi + "4" (dstptr) // edi + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm4" // clobber list + , "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP2 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP2; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 16 bpp */ + + case 24: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask24_0, %%mm0 \n\t" + "movq _mask24_1, %%mm1 \n\t" + "movq _mask24_2, %%mm2 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop24end \n\t" + + "mainloop24: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq 16(%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm4 \n\t" + "por %%mm4, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "addl $24, %%esi \n\t" // inc by 24 bytes processed + "addl $24, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + + "ja mainloop24 \n\t" + + "mainloop24end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end24 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop24: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip24 \n\t" // if CF = 0 + "movw (%%esi), %%ax \n\t" + "movw %%ax, (%%edi) \n\t" + "xorl %%eax, %%eax \n\t" + "movb 2(%%esi), %%al \n\t" + "movb %%al, 2(%%edi) \n\t" + + "skip24: \n\t" + "addl $3, %%esi \n\t" + "addl $3, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop24 \n\t" + + "end24: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP3 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP3; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 24 bpp */ + + case 32: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask32_0, %%mm0 \n\t" + "movq _mask32_1, %%mm1 \n\t" + "movq _mask32_2, %%mm2 \n\t" + "movq _mask32_3, %%mm3 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + "pand %%mm7, %%mm3 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + "pcmpeqb %%mm6, %%mm3 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" // lcr + "jz mainloop32end \n\t" + + "mainloop32: \n\t" + "movq (%%esi), %%mm4 \n\t" + "pand %%mm0, %%mm4 \n\t" + "movq %%mm0, %%mm6 \n\t" + "movq (%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm6 \n\t" + "por %%mm6, %%mm4 \n\t" + "movq %%mm4, (%%edi) \n\t" + + "movq 8(%%esi), %%mm5 \n\t" + "pand %%mm1, %%mm5 \n\t" + "movq %%mm1, %%mm7 \n\t" + "movq 8(%%edi), %%mm6 \n\t" + "pandn %%mm6, %%mm7 \n\t" + "por %%mm7, %%mm5 \n\t" + "movq %%mm5, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq 16(%%edi), %%mm7 \n\t" + "pandn %%mm7, %%mm4 \n\t" + "por %%mm4, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "movq 24(%%esi), %%mm7 \n\t" + "pand %%mm3, %%mm7 \n\t" + "movq %%mm3, %%mm5 \n\t" + "movq 24(%%edi), %%mm4 \n\t" + "pandn %%mm4, %%mm5 \n\t" + "por %%mm5, %%mm7 \n\t" + "movq %%mm7, 24(%%edi) \n\t" + + "addl $32, %%esi \n\t" // inc by 32 bytes processed + "addl $32, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + "ja mainloop32 \n\t" + + "mainloop32end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end32 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // low byte => high byte + + "secondloop32: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip32 \n\t" // if CF = 0 + "movl (%%esi), %%eax \n\t" + "movl %%eax, (%%edi) \n\t" + + "skip32: \n\t" + "addl $4, %%esi \n\t" + "addl $4, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop32 \n\t" + + "end32: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP4 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP4; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 32 bpp */ + + case 48: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + png_uint_32 len; + int diff; + int dummy_value_a; // fix 'forbidden register spilled' error + int dummy_value_d; + int dummy_value_c; + int dummy_value_S; + int dummy_value_D; + _unmask = ~mask; // global variable for -fPIC version + srcptr = png_ptr->row_buf + 1; + dstptr = row; + len = png_ptr->width &~7; // reduce to multiple of 8 + diff = (int) (png_ptr->width & 7); // amount lost // + + __asm__ __volatile__ ( + "movd _unmask, %%mm7 \n\t" // load bit pattern + "psubb %%mm6, %%mm6 \n\t" // zero mm6 + "punpcklbw %%mm7, %%mm7 \n\t" + "punpcklwd %%mm7, %%mm7 \n\t" + "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks + + "movq _mask48_0, %%mm0 \n\t" + "movq _mask48_1, %%mm1 \n\t" + "movq _mask48_2, %%mm2 \n\t" + "movq _mask48_3, %%mm3 \n\t" + "movq _mask48_4, %%mm4 \n\t" + "movq _mask48_5, %%mm5 \n\t" + + "pand %%mm7, %%mm0 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pand %%mm7, %%mm4 \n\t" + "pand %%mm7, %%mm5 \n\t" + + "pcmpeqb %%mm6, %%mm0 \n\t" + "pcmpeqb %%mm6, %%mm1 \n\t" + "pcmpeqb %%mm6, %%mm2 \n\t" + "pcmpeqb %%mm6, %%mm3 \n\t" + "pcmpeqb %%mm6, %%mm4 \n\t" + "pcmpeqb %%mm6, %%mm5 \n\t" + +// preload "movl len, %%ecx \n\t" // load length of line +// preload "movl srcptr, %%esi \n\t" // load source +// preload "movl dstptr, %%edi \n\t" // load dest + + "cmpl $0, %%ecx \n\t" + "jz mainloop48end \n\t" + + "mainloop48: \n\t" + "movq (%%esi), %%mm7 \n\t" + "pand %%mm0, %%mm7 \n\t" + "movq %%mm0, %%mm6 \n\t" + "pandn (%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, (%%edi) \n\t" + + "movq 8(%%esi), %%mm6 \n\t" + "pand %%mm1, %%mm6 \n\t" + "movq %%mm1, %%mm7 \n\t" + "pandn 8(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 8(%%edi) \n\t" + + "movq 16(%%esi), %%mm6 \n\t" + "pand %%mm2, %%mm6 \n\t" + "movq %%mm2, %%mm7 \n\t" + "pandn 16(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 16(%%edi) \n\t" + + "movq 24(%%esi), %%mm7 \n\t" + "pand %%mm3, %%mm7 \n\t" + "movq %%mm3, %%mm6 \n\t" + "pandn 24(%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, 24(%%edi) \n\t" + + "movq 32(%%esi), %%mm6 \n\t" + "pand %%mm4, %%mm6 \n\t" + "movq %%mm4, %%mm7 \n\t" + "pandn 32(%%edi), %%mm7 \n\t" + "por %%mm7, %%mm6 \n\t" + "movq %%mm6, 32(%%edi) \n\t" + + "movq 40(%%esi), %%mm7 \n\t" + "pand %%mm5, %%mm7 \n\t" + "movq %%mm5, %%mm6 \n\t" + "pandn 40(%%edi), %%mm6 \n\t" + "por %%mm6, %%mm7 \n\t" + "movq %%mm7, 40(%%edi) \n\t" + + "addl $48, %%esi \n\t" // inc by 48 bytes processed + "addl $48, %%edi \n\t" + "subl $8, %%ecx \n\t" // dec by 8 pixels processed + + "ja mainloop48 \n\t" + + "mainloop48end: \n\t" +// preload "movl diff, %%ecx \n\t" // (diff is in eax) + "movl %%eax, %%ecx \n\t" + "cmpl $0, %%ecx \n\t" + "jz end48 \n\t" +// preload "movl mask, %%edx \n\t" + "sall $24, %%edx \n\t" // make low byte, high byte + + "secondloop48: \n\t" + "sall %%edx \n\t" // move high bit to CF + "jnc skip48 \n\t" // if CF = 0 + "movl (%%esi), %%eax \n\t" + "movl %%eax, (%%edi) \n\t" + + "skip48: \n\t" + "addl $4, %%esi \n\t" + "addl $4, %%edi \n\t" + "decl %%ecx \n\t" + "jnz secondloop48 \n\t" + + "end48: \n\t" + "EMMS \n\t" // DONE + + : "=a" (dummy_value_a), // output regs (dummy) + "=d" (dummy_value_d), + "=c" (dummy_value_c), + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "3" (srcptr), // esi // input regs + "4" (dstptr), // edi + "0" (diff), // eax +// was (unmask) "b" RESERVED // ebx // Global Offset Table idx + "2" (len), // ecx + "1" (mask) // edx + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + else /* mmx _not supported - Use modified C routine */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + register png_uint_32 i; + png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP6 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP6; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + } /* end of else (_mmx_supported) */ + + break; + } /* end 48 bpp */ + + case 64: /* png_ptr->row_info.pixel_depth */ + { + png_bytep srcptr; + png_bytep dstptr; + register png_uint_32 i; + png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass]; + /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ + register int stride = BPP8 * png_pass_inc[png_ptr->pass]; + /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ + register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass]; + /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ + png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ + int diff = (int) (png_ptr->width & 7); /* amount lost */ + register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */ + + srcptr = png_ptr->row_buf + 1 + initial_val; + dstptr = row + initial_val; + + for (i = initial_val; i < final_val; i += stride) + { + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + if (diff) /* number of leftover pixels: 3 for pngtest */ + { + final_val+=diff*BPP8; + for (; i < final_val; i += stride) + { + if (rep_bytes > (int)(final_val-i)) + rep_bytes = (int)(final_val-i); + png_memcpy(dstptr, srcptr, rep_bytes); + srcptr += stride; + dstptr += stride; + } + } + + break; + } /* end 64 bpp */ + + default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ + { + /* this should never happen */ + png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd"); + break; + } + } /* end switch (png_ptr->row_info.pixel_depth) */ + + } /* end if (non-trivial mask) */ + +} /* end png_combine_row() */ + +#endif /* PNG_HAVE_MMX_COMBINE_ROW */ + + + + +/*===========================================================================*/ +/* */ +/* P N G _ D O _ R E A D _ I N T E R L A C E */ +/* */ +/*===========================================================================*/ + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +#if defined(PNG_HAVE_MMX_READ_INTERLACE) + +/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion + * has taken place. [GRR: what other steps come before and/or after?] + */ + +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + png_uint_32 transformations = png_ptr->transformations; +#endif + + png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n"); + +#if defined(PNG_MMX_CODE_SUPPORTED) + if (_mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif + + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_byte v; + png_uint_32 i; + int j; + + sp = row + (png_size_t)((row_info->width - 1) >> 3); + dp = row + (png_size_t)((final_width - 1) >> 3); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 7); + dshift = (int)((final_width + 7) & 7); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 7); + dshift = 7 - (int)((final_width + 7) & 7); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = row_info->width; i; i--) + { + v = (png_byte)((*sp >> sshift) & 0x1); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 2: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 2); + dp = row + (png_size_t)((final_width - 1) >> 2); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); + dshift = (png_size_t)(((final_width + 3) & 3) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); + dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 4: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 1); + dp = row + (png_size_t)((final_width - 1) >> 1); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); + dshift = (png_size_t)(((final_width + 1) & 1) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); + dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0xf); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + /*====================================================================*/ + + default: /* 8-bit or larger (this is where the routine is modified) */ + { +#if 0 +// static unsigned long long _const4 = 0x0000000000FFFFFFLL; no good +// static unsigned long long const4 = 0x0000000000FFFFFFLL; no good +// unsigned long long _const4 = 0x0000000000FFFFFFLL; no good +// unsigned long long const4 = 0x0000000000FFFFFFLL; no good +#endif + png_bytep sptr, dp; + png_uint_32 i; + png_size_t pixel_bytes; + int width = (int)row_info->width; + + pixel_bytes = (row_info->pixel_depth >> 3); + + /* point sptr at the last pixel in the pre-expanded row: */ + sptr = row + (width - 1) * pixel_bytes; + + /* point dp at the last pixel position in the expanded row: */ + dp = row + (final_width - 1) * pixel_bytes; + + /* New code by Nirav Chhatrapati - Intel Corporation */ + +#if defined(PNG_MMX_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif + { + //-------------------------------------------------------------- + if (pixel_bytes == 3) + { + if (((pass == 0) || (pass == 1)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + + __asm__ __volatile__ ( + "subl $21, %%edi \n\t" + // (png_pass_inc[pass] - 1)*pixel_bytes + + ".loop3_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 + "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0 + "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 + "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z + "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z + "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z + "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 + "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z + "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 + "movq %%mm0, %%mm3 \n\t" // 2 1 0 2 1 0 2 1 + "psllq $16, %%mm0 \n\t" // 0 2 1 0 2 1 z z + "movq %%mm3, %%mm4 \n\t" // 2 1 0 2 1 0 2 1 + "punpckhdq %%mm0, %%mm3 \n\t" // 0 2 1 0 2 1 0 2 + "movq %%mm4, 16(%%edi) \n\t" + "psrlq $32, %%mm0 \n\t" // z z z z 0 2 1 0 + "movq %%mm3, 8(%%edi) \n\t" + "punpckldq %%mm4, %%mm0 \n\t" // 1 0 2 1 0 2 1 0 + "subl $3, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $24, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop3_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a) + + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width), // ecx + "3" (&_const4) // %1(?) (0x0000000000FFFFFFLL) + +#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm3", "%mm4" +#endif + ); + } + else if (((pass == 2) || (pass == 3)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + + __asm__ __volatile__ ( + "subl $9, %%edi \n\t" + // (png_pass_inc[pass] - 1)*pixel_bytes + + ".loop3_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 + "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0 + "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 + "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z + "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z + "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z + "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 + "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z + "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 + "movq %%mm0, 4(%%edi) \n\t" + "psrlq $16, %%mm0 \n\t" // z z 2 1 0 2 1 0 + "subl $3, %%esi \n\t" + "movd %%mm0, (%%edi) \n\t" + "subl $12, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop3_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width), // ecx + "3" (&_const4) // (0x0000000000FFFFFFLL) + +#if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list +#endif + ); + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 1) << 1) - 8; // GRR: huh? + if (width_mmx < 0) + width_mmx = 0; + width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes + if (width_mmx) + { + // png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + // sptr points at last pixel in pre-expanded row + // dp points at last pixel position in expanded row + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + int dummy_value_a; + int dummy_value_d; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $9, %%edi \n\t" + // (png_pass_inc[pass] + 1)*pixel_bytes + + ".loop3_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // x x 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // x x 5 4 3 2 1 0 + "movq %%mm0, %%mm2 \n\t" // x x 5 4 3 2 1 0 + "psllq $24, %%mm0 \n\t" // 4 3 2 1 0 z z z + "pand (%3), %%mm1 \n\t" // z z z z z 2 1 0 + "psrlq $24, %%mm2 \n\t" // z z z x x 5 4 3 + "por %%mm1, %%mm0 \n\t" // 4 3 2 1 0 2 1 0 + "movq %%mm2, %%mm3 \n\t" // z z z x x 5 4 3 + "psllq $8, %%mm2 \n\t" // z z x x 5 4 3 z + "movq %%mm0, (%%edi) \n\t" + "psrlq $16, %%mm3 \n\t" // z z z z z x x 5 + "pand (%4), %%mm3 \n\t" // z z z z z z z 5 + "por %%mm3, %%mm2 \n\t" // z z x x 5 4 3 5 + "subl $6, %%esi \n\t" + "movd %%mm2, 8(%%edi) \n\t" + "subl $12, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop3_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D), + "=a" (dummy_value_a), + "=d" (dummy_value_d) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx), // ecx + "3" (&_const4), // 0x0000000000FFFFFFLL + "4" (&_const6) // 0x00000000000000FFLL + +#if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list + , "%mm2", "%mm3" +#endif + ); + } + + sptr -= width_mmx*3; + dp -= width_mmx*6; + for (i = width; i; i--) + { + png_byte v[8]; + int j; + + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + } /* end of pixel_bytes == 3 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 1) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $31, %%edi \n\t" + + ".loop1_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // x x x x 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "movq %%mm0, %%mm2 \n\t" // 3 3 2 2 1 1 0 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 + "movq %%mm0, %%mm3 \n\t" // 1 1 1 1 0 0 0 0 + "punpckldq %%mm0, %%mm0 \n\t" // 0 0 0 0 0 0 0 0 + "punpckhdq %%mm3, %%mm3 \n\t" // 1 1 1 1 1 1 1 1 + "movq %%mm0, (%%edi) \n\t" + "punpckhwd %%mm2, %%mm2 \n\t" // 3 3 3 3 2 2 2 2 + "movq %%mm3, 8(%%edi) \n\t" + "movq %%mm2, %%mm4 \n\t" // 3 3 3 3 2 2 2 2 + "punpckldq %%mm2, %%mm2 \n\t" // 2 2 2 2 2 2 2 2 + "punpckhdq %%mm4, %%mm4 \n\t" // 3 3 3 3 3 3 3 3 + "movq %%mm2, 16(%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm4, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "subl $4, %%ecx \n\t" + "jnz .loop1_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1", "%mm2" // clobber list + , "%mm3", "%mm4" +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*8; + for (i = width; i; i--) + { + int j; + + /* I simplified this part in version 1.0.4e + * here and in several other instances where + * pixel_bytes == 1 -- GR-P + * + * Original code: + * + * png_byte v[8]; + * png_memcpy(v, sptr, pixel_bytes); + * for (j = 0; j < png_pass_inc[pass]; j++) + * { + * png_memcpy(dp, v, pixel_bytes); + * dp -= pixel_bytes; + * } + * sptr -= pixel_bytes; + * + * Replacement code is in the next three lines: + */ + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $3, %%esi \n\t" + "subl $15, %%edi \n\t" + + ".loop1_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "movq %%mm0, %%mm1 \n\t" // 3 3 2 2 1 1 0 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 + "punpckhwd %%mm1, %%mm1 \n\t" // 3 3 3 3 2 2 2 2 + "movq %%mm0, (%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $4, %%ecx \n\t" + "jnz .loop1_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*4; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 3) << 3); + width -= width_mmx; // 0-3 pixels => 0-3 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $7, %%esi \n\t" + "subl $15, %%edi \n\t" + + ".loop1_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 + "punpckhbw %%mm1, %%mm1 \n\t" // 7 7 6 6 5 5 4 4 + "movq %%mm1, 8(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $8, %%ecx \n\t" + "jnz .loop1_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (none) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= width_mmx; + dp -= width_mmx*2; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + } /* end of pixel_bytes == 1 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 2) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $30, %%edi \n\t" + + ".loop2_pass0: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm1, 16(%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*16 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $14, %%edi \n\t" + + ".loop2_pass2: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 + "movq %%mm0, (%%edi) \n\t" + "subl $4, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*8 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,2 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $2, %%esi \n\t" + "subl $6, %%edi \n\t" + + ".loop2_pass4: \n\t" + "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 + "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 + "subl $4, %%esi \n\t" + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop2_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*4 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + } /* end of pixel_bytes == 2 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 4) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $60, %%edi \n\t" + + ".loop4_pass0: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "movq %%mm1, 32(%%edi) \n\t" + "movq %%mm1, 40(%%edi) \n\t" + "movq %%mm1, 48(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm1, 56(%%edi) \n\t" + "subl $64, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*32 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $28, %%edi \n\t" + + ".loop4_pass2: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm1, 16(%%edi) \n\t" + "movq %%mm1, 24(%%edi) \n\t" + "subl $8, %%esi \n\t" + "subl $32, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*16 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; // 0,1 pixels => 0,4 bytes + if (width_mmx) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $4, %%esi \n\t" + "subl $12, %%edi \n\t" + + ".loop4_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 + "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 + "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm1, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "subl $2, %%ecx \n\t" + "jnz .loop4_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width_mmx) // ecx + +#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0", "%mm1" // clobber list +#endif + ); + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*8 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + } /* end of pixel_bytes == 4 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 8) + { +// GRR TEST: should work, but needs testing (special 64-bit version of rpng2?) + // GRR NOTE: no need to combine passes here! + if (((pass == 0) || (pass == 1)) && width) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + // source is 8-byte RRGGBBAA + // dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ... + __asm__ __volatile__ ( + "subl $56, %%edi \n\t" // start of last block + + ".loop8_pass0: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "movq %%mm0, 32(%%edi) \n\t" + "movq %%mm0, 40(%%edi) \n\t" + "movq %%mm0, 48(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 56(%%edi) \n\t" + "subl $64, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass0 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + else if (((pass == 2) || (pass == 3)) && width) + { + // source is 8-byte RRGGBBAA + // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA + // (recall that expansion is _in place_: sptr and dp + // both point at locations within same row buffer) + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $24, %%edi \n\t" // start of last block + + ".loop8_pass2: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "movq %%mm0, 16(%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 24(%%edi) \n\t" + "subl $32, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass2 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + } + else if (width) // pass == 4 or 5 + { + // source is 8-byte RRGGBBAA + // dest is 16-byte RRGGBBAA RRGGBBAA + { + int dummy_value_c; // fix 'forbidden register spilled' + int dummy_value_S; + int dummy_value_D; + + __asm__ __volatile__ ( + "subl $8, %%edi \n\t" // start of last block + + ".loop8_pass4: \n\t" + "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 + "movq %%mm0, (%%edi) \n\t" + "subl $8, %%esi \n\t" + "movq %%mm0, 8(%%edi) \n\t" + "subl $16, %%edi \n\t" + "decl %%ecx \n\t" + "jnz .loop8_pass4 \n\t" + "EMMS \n\t" // DONE + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "1" (sptr), // esi // input regs + "2" (dp), // edi + "0" (width) // ecx + +#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ + : "%mm0" // clobber list +#endif + ); + } + } + + } /* end of pixel_bytes == 8 */ + + //-------------------------------------------------------------- + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } /* end of pixel_bytes == 6 */ + + //-------------------------------------------------------------- + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr-= pixel_bytes; + } + } + } // end of _mmx_supported ======================================== + + else /* MMX not supported: use modified C code - takes advantage + * of inlining of png_memcpy for a constant */ + /* GRR 19991007: does it? or should pixel_bytes in each + * block be replaced with immediate value (e.g., 1)? */ + /* GRR 19991017: replaced with constants in each case */ +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + if (pixel_bytes == 1) + { + for (i = width; i; i--) + { + int j; + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + --sptr; + } + } + else if (pixel_bytes == 3) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + else if (pixel_bytes == 2) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 2); + dp -= 2; + } + sptr -= 2; + } + } + else if (pixel_bytes == 4) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { +#ifdef PNG_DEBUG + if (dp < row || dp+3 > row+png_ptr->row_buf_size) + { + printf("dp out of bounds: row=%d, dp=%d, rp=%d\n", + row, dp, row+png_ptr->row_buf_size); + printf("row_buf=%d\n",png_ptr->row_buf_size); + } +#endif + png_memcpy(dp, v, 4); + dp -= 4; + } + sptr -= 4; + } + } + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } + else if (pixel_bytes == 8) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 8); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 8); + dp -= 8; + } + sptr -= 8; + } + } + else /* GRR: should never be reached */ + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + + } /* end if (MMX not supported) */ + break; + } + } /* end switch (row_info->pixel_depth) */ + + row_info->width = final_width; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } + +} /* end png_do_read_interlace() */ + +#endif /* PNG_HAVE_MMX_READ_INTERLACE */ +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + + +#if defined(PNG_HAVE_MMX_READ_FILTER_ROW) +#if defined(PNG_MMX_CODE_SUPPORTED) + +// These variables are utilized in the functions below. They are declared +// globally here to ensure alignment on 8-byte boundaries. + +union uAll { + long long use; + double align; +} _LBCarryMask = {0x0101010101010101LL}, + _HBClearMask = {0x7f7f7f7f7f7f7f7fLL}, + _ActiveMask, _ActiveMask2, _ActiveMaskEnd, _ShiftBpp, _ShiftRem; + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G // +// // +//===========================================================================// + +// Optimized code for PNG Average filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + int bpp; + int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // get # bytes per pixel + _FullLength = row_info->rowbytes; // # of bytes to filter + + __asm__ __volatile__ ( + // initialize address pointers and offset +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif +//pre "movl row, %%edi \n\t" // edi: Avg(x) + "xorl %%ebx, %%ebx \n\t" // ebx: x + "movl %%edi, %%edx \n\t" +//pre "movl prev_row, %%esi \n\t" // esi: Prior(x) +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + + "xorl %%eax,%%eax \n\t" + + // Compute the Raw value for the first bpp bytes + // Raw(x) = Avg(x) + (Prior(x)/2) + "avg_rlp: \n\t" + "movb (%%esi,%%ebx,),%%al \n\t" // load al with Prior(x) + "incl %%ebx \n\t" + "shrb %%al \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,),%%al \n\t" // add Avg(x); -1 to offset inc ebx +//pre "cmpl bpp, %%ebx \n\t" // (bpp is preloaded into ecx) + "cmpl %%ecx, %%ebx \n\t" + "movb %%al,-1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx + "jb avg_rlp \n\t" // mov does not affect flags + + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl %%ebx, _dif \n\t" // add bpp + "addl $0xf, _dif \n\t" // add 7+8 to incr past alignment bdry + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start => value ebx at + "jz avg_go \n\t" // alignment + + // fix alignment + // Compute the Raw value for the bytes up to the alignment boundary + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%ecx, %%ecx \n\t" + + "avg_lp1: \n\t" + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx + "cmpl _dif, %%ebx \n\t" // check if at alignment boundary + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx + "jb avg_lp1 \n\t" // repeat until at alignment boundary + + "avg_go: \n\t" + "movl _FullLength, %%eax \n\t" + "movl %%eax, %%ecx \n\t" + "subl %%ebx, %%eax \n\t" // subtract alignment fix + "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 + "subl %%eax, %%ecx \n\t" // drop over bytes from original length + "movl %%ecx, _MMXLength \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + // GRR: INCLUDE "memory" as clobbered? (_dif, _MMXLength) + // (seems to work fine without...) + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000000000ffffffLL; + _ShiftBpp.use = 24; // == 3 * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( + // re-init address pointers and offset + "movq _ActiveMask, %%mm7 \n\t" + "movl _dif, %%ecx \n\t" // ecx: x = offset to + "movq _LBCarryMask, %%mm5 \n\t" // alignment boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (correct pos. in loop below) + "avg_3lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" // load mm0 with Avg(x) + "movq %%mm5, %%mm3 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // correct position Raw(x-bpp) + // data + "movq (%%esi,%%ecx,), %%mm1 \n\t" // load mm1 with Prior(x) + "movq %%mm7, %%mm6 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + // add 1st active group (Raw(x-bpp)/2) to average with LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 3-5 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + + // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift mm6 mask to cover last + // two + // bytes + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "addl $8, %%ecx \n\t" + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // move updated Raw(x) to use as Raw(x-bpp) for next loop + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm0, %%mm2 \n\t" // mov updated Raw(x) to mm2 + "jb avg_3lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 3 bpp + + case 6: + case 4: + //case 7: // who wrote this? PNG doesn't support 5 or 7 bytes/pixel + //case 5: // GRR BOGUS + { + _ActiveMask.use = 0xffffffffffffffffLL; // use shift below to clear + // appropriate inactive bytes + _ShiftBpp.use = bpp << 3; + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( + "movq _HBClearMask, %%mm4 \n\t" + + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x = offset to + // alignment boundary + + // load _ActiveMask and clear all bytes except for 1st active group + "movq _ActiveMask, %%mm7 \n\t" +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "psrlq _ShiftRem, %%mm7 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movq %%mm7, %%mm6 \n\t" + "movq _LBCarryMask, %%mm5 \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // create mask for 2nd active + // group + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (we correct pos. in loop below) + "avg_4lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly + "movq (%%esi,%%ecx,), %%mm1 \n\t" + // add (Prev_row/2) to average + "movq %%mm5, %%mm3 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg + // for each Active + // byte + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "addl $8, %%ecx \n\t" + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active + // byte + "cmpl _MMXLength, %%ecx \n\t" + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // prep Raw(x-bpp) for next loop + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "jb avg_4lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 4,6 bpp + + case 2: + { + _ActiveMask.use = 0x000000000000ffffLL; + _ShiftBpp.use = 16; // == 2 * 8 + _ShiftRem.use = 48; // == 64 - 16 + + __asm__ __volatile__ ( + // load _ActiveMask + "movq _ActiveMask, %%mm7 \n\t" + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x = offset to alignment + // boundary + "movq _LBCarryMask, %%mm5 \n\t" +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (we correct pos. in loop below) + "avg_2lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly + "movq (%%esi,%%ecx,), %%mm1 \n\t" // (GRR BUGFIX: was psllq) + // add (Prev_row/2) to average + "movq %%mm5, %%mm3 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "movq %%mm7, %%mm6 \n\t" + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + + // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg + // for each Active byte + + // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 2 & 3 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 4 & 5 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + // (only valid for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + // add 4th active group (Raw(x-bpp)/2) to average with _LBCarry + "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover + // bytes 6 & 7 + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly + "addl $8, %%ecx \n\t" + "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting + // LBCarrys + "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte + // where both + // lsb's were == 1 (only valid + // for active group) + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) + // for each byte + "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 + // bytes to add to Avg + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to + // Avg for each Active byte + + "cmpl _MMXLength, %%ecx \n\t" + // now ready to write back to memory + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + // prep Raw(x-bpp) for next loop + "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 + "jb avg_2lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 2 bpp + + case 1: + { + __asm__ __volatile__ ( + // re-init address pointers and offset +#ifdef __PIC__ + "pushl %%ebx \n\t" // save Global Offset Table index +#endif + "movl _dif, %%ebx \n\t" // ebx: x = offset to alignment + // boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array + "jnb avg_1end \n\t" + // do Paeth decode for remaining bytes +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movl %%edi, %%edx \n\t" +// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx + // in loop below + "avg_1lp: \n\t" + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset + // inc ebx + "cmpl _FullLength, %%ebx \n\t" // check if at end of array + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + "jb avg_1lp \n\t" + + "avg_1end: \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // Global Offset Table index +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + } + return; // end 1 bpp + + case 8: + { + __asm__ __volatile__ ( + // re-init address pointers and offset + "movl _dif, %%ecx \n\t" // ecx: x == offset to alignment + "movq _LBCarryMask, %%mm5 \n\t" // boundary +// preload "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" +// preload "movl prev_row, %%esi \n\t" // esi: Prior(x) + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes + // (NO NEED to correct pos. in loop below) + + "avg_8lp: \n\t" + "movq (%%edi,%%ecx,), %%mm0 \n\t" + "movq %%mm5, %%mm3 \n\t" + "movq (%%esi,%%ecx,), %%mm1 \n\t" + "addl $8, %%ecx \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7, each byte + "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg, each byte + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7, each byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg, each + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm0, -8(%%edi,%%ecx,) \n\t" + "movq %%mm0, %%mm2 \n\t" // reuse as Raw(x-bpp) + "jb avg_8lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm5 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2" + , "%mm3", "%mm4", "%mm5" +#endif + ); + } + break; // end 8 bpp + + default: // bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8) + { + +#ifdef PNG_DEBUG + // GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED + png_debug(1, + "Internal logic error in pnggccrd (png_read_filter_row_mmx_avg())\n"); +#endif + +#if 0 + __asm__ __volatile__ ( + "movq _LBCarryMask, %%mm5 \n\t" + // re-init address pointers and offset + "movl _dif, %%ebx \n\t" // ebx: x = offset to + // alignment boundary + "movl row, %%edi \n\t" // edi: Avg(x) + "movq _HBClearMask, %%mm4 \n\t" + "movl %%edi, %%edx \n\t" + "movl prev_row, %%esi \n\t" // esi: Prior(x) + "subl bpp, %%edx \n\t" // edx: Raw(x-bpp) + "avg_Alp: \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "movq %%mm5, %%mm3 \n\t" + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte + "movq (%%edx,%%ebx,), %%mm2 \n\t" + "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 + "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte + // where both lsb's were == 1 + "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 + "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg for each + // byte + "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each + // byte + "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for + // each byte + "addl $8, %%ebx \n\t" + "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each + // byte + "cmpl _MMXLength, %%ebx \n\t" + "movq %%mm0, -8(%%edi,%%ebx,) \n\t" + "jb avg_Alp \n\t" + + : // FIXASM: output regs/vars go here, e.g.: "=m" (memory_var) + + : // FIXASM: input regs, e.g.: "c" (count), "S" (src), "D" (dest) + + : "%ebx", "%edx", "%edi", "%esi" // CHECKASM: clobber list + ); +#endif /* 0 - NEVER REACHED */ + } + break; + + } // end switch (bpp) + + __asm__ __volatile__ ( + // MMX acceleration complete; now do clean-up + // check if any remaining bytes left to decode +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "movl _MMXLength, %%ebx \n\t" // ebx: x == offset bytes after MMX +//pre "movl row, %%edi \n\t" // edi: Avg(x) + "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array + "jnb avg_end \n\t" + + // do Avg decode for remaining bytes +//pre "movl prev_row, %%esi \n\t" // esi: Prior(x) + "movl %%edi, %%edx \n\t" +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below + + "avg_lp2: \n\t" + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + "xorl %%eax, %%eax \n\t" + "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) + "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) + "addw %%cx, %%ax \n\t" + "incl %%ebx \n\t" + "shrw %%ax \n\t" // divide by 2 + "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx + "cmpl _FullLength, %%ebx \n\t" // check if at end of array + "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x) [mov does not + "jb avg_lp2 \n\t" // affect flags; -1 to offset inc ebx] + + "avg_end: \n\t" + "EMMS \n\t" // end MMX; prep for poss. FP instrs. +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + +} /* end png_read_filter_row_mmx_avg() */ +#endif + + + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H // +// // +//===========================================================================// + +// Optimized code for PNG Paeth filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + int bpp; + int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + _FullLength = row_info->rowbytes; // # of bytes to filter + + __asm__ __volatile__ ( +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "xorl %%ebx, %%ebx \n\t" // ebx: x offset +//pre "movl row, %%edi \n\t" + "xorl %%edx, %%edx \n\t" // edx: x-bpp offset +//pre "movl prev_row, %%esi \n\t" + "xorl %%eax, %%eax \n\t" + + // Compute the Raw value for the first bpp bytes + // Note: the formula works out to be always + // Paeth(x) = Raw(x) + Prior(x) where x < bpp + "paeth_rlp: \n\t" + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" +//pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx) + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" + "jb paeth_rlp \n\t" + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl %%ebx, _dif \n\t" // add bpp + "xorl %%ecx, %%ecx \n\t" + "addl $0xf, _dif \n\t" // add 7 + 8 to incr past alignment + // boundary + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start ==> value ebx + // at alignment + "jz paeth_go \n\t" + // fix alignment + + "paeth_lp1: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_pca \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_pca: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_pba \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_pba: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_paa \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_paa: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_abb \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_bbc \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth \n\t" + + "paeth_bbc: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_paeth \n\t" + + "paeth_abb: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_abc \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth \n\t" + + "paeth_abc: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_paeth: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _dif, %%ebx \n\t" + "jb paeth_lp1 \n\t" + + "paeth_go: \n\t" + "movl _FullLength, %%ecx \n\t" + "movl %%ecx, %%eax \n\t" + "subl %%ebx, %%eax \n\t" // subtract alignment fix + "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 + "subl %%eax, %%ecx \n\t" // drop over bytes from original length + "movl %%ecx, _MMXLength \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000000000ffffffLL; + _ActiveMaskEnd.use = 0xffff000000000000LL; + _ShiftBpp.use = 24; // == bpp(3) * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "paeth_3lp: \n\t" + "psrlq _ShiftRem, %%mm1 \n\t" // shift last 3 bytes to 1st + // 3 bytes + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // prep c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "psrlq _ShiftRem, %%mm3 \n\t" // shift last 3 bytes to 1st + // 3 bytes + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as + // Raw(x-bpp) + // now do Paeth for 2nd set of bytes (3-5) + "psrlq _ShiftBpp, %%mm2 \n\t" // load b=Prior(x) step 2 + "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "pxor %%mm7, %%mm7 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "psubw %%mm3, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = + // pav + pbv = pbv + pav + "movq %%mm5, %%mm6 \n\t" + "paddw %%mm4, %%mm6 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm5, %%mm0 \n\t" // create mask pbv bytes < 0 + "pcmpgtw %%mm4, %%mm7 \n\t" // create mask pav bytes < 0 + "pand %%mm5, %%mm0 \n\t" // only pbv bytes < 0 in mm0 + "pand %%mm4, %%mm7 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm5 \n\t" + "psubw %%mm7, %%mm4 \n\t" + "psubw %%mm0, %%mm5 \n\t" + "psubw %%mm7, %%mm4 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq %%mm2, %%mm3 \n\t" // load c=Prior(x-bpp) step 1 + "pand _ActiveMask, %%mm7 \n\t" + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "psllq _ShiftBpp, %%mm7 \n\t" // shift bytes to 2nd group of + // 3 bytes + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "psllq _ShiftBpp, %%mm3 \n\t" // load c=Prior(x-bpp) step 2 + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "psllq _ShiftBpp, %%mm1 \n\t" // shift bytes + // now mm1 will be used as Raw(x-bpp) + // now do Paeth for 3rd, and final, set of bytes (6-7) + "pxor %%mm7, %%mm7 \n\t" + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + "psubw %%mm3, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "paddw %%mm5, %%mm6 \n\t" + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "packuswb %%mm7, %%mm1 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "pand _ActiveMaskEnd, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with + // Raw(x) + + "cmpl _MMXLength, %%ecx \n\t" + "pxor %%mm0, %%mm0 \n\t" // pxor does not affect flags + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + // mm3 ready to be used as Prior(x-bpp) next loop + "jb paeth_3lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 3 bpp + + case 6: + //case 7: // GRR BOGUS + //case 5: // GRR BOGUS + { + _ActiveMask.use = 0x00000000ffffffffLL; + _ActiveMask2.use = 0xffffffff00000000LL; + _ShiftBpp.use = bpp << 3; // == bpp * 8 + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "pxor %%mm0, %%mm0 \n\t" + + "paeth_6lp: \n\t" + // must shift to position Raw(x-bpp) data + "psrlq _ShiftRem, %%mm1 \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + // must shift to position Prior(x-bpp) data + "psrlq _ShiftRem, %%mm3 \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "psrlq _ShiftRem, %%mm3 \n\t" + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor and Raw(x) + "movq %%mm2, %%mm6 \n\t" + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" + "movq %%mm7, %%mm5 \n\t" + "psrlq _ShiftRem, %%mm1 \n\t" + "por %%mm6, %%mm3 \n\t" + "psllq _ShiftBpp, %%mm5 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "por %%mm5, %%mm1 \n\t" + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_6lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 6 bpp + + case 4: + { + _ActiveMask.use = 0x00000000ffffffffLL; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read + // a=Raw(x-bpp) bytes + "paeth_4lp: \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpckhbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) + "pand _ActiveMask, %%mm7 \n\t" + "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as Raw(x-bpp) + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_4lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 4 bpp + + case 8: // bpp == 8 + { + _ActiveMask.use = 0x00000000ffffffffLL; + + __asm__ __volatile__ ( + "movl _dif, %%ecx \n\t" +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + "pxor %%mm0, %%mm0 \n\t" + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read + // a=Raw(x-bpp) bytes + "paeth_8lp: \n\t" + // do first set of 4 bytes + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm7 \n\t" + "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes + "pand _ActiveMask, %%mm7 \n\t" + "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) + "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) + "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c + "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value + "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // read a=Raw(x-bpp) bytes + + // do second set of 4 bytes + "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b + "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + "movq %%mm2, %%mm4 \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movq %%mm1, %%mm5 \n\t" + "psubw %%mm3, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "movq %%mm4, %%mm6 \n\t" + "psubw %%mm3, %%mm5 \n\t" + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 + "paddw %%mm5, %%mm6 \n\t" + "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 + "psubw %%mm0, %%mm4 \n\t" + "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 + "psubw %%mm0, %%mm4 \n\t" + "psubw %%mm7, %%mm5 \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 + "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 + "psubw %%mm7, %%mm5 \n\t" + "psubw %%mm0, %%mm6 \n\t" + // test pa <= pb + "movq %%mm4, %%mm7 \n\t" + "psubw %%mm0, %%mm6 \n\t" + "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? + "movq %%mm7, %%mm0 \n\t" + // use mm7 mask to merge pa & pb + "pand %%mm7, %%mm5 \n\t" + // use mm0 mask copy to merge a & b + "pand %%mm0, %%mm2 \n\t" + "pandn %%mm4, %%mm7 \n\t" + "pandn %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm7 \n\t" + "paddw %%mm2, %%mm0 \n\t" + // test ((pa <= pb)? pa:pb) <= pc + "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? + "pxor %%mm1, %%mm1 \n\t" + "pand %%mm7, %%mm3 \n\t" + "pandn %%mm0, %%mm7 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "paddw %%mm3, %%mm7 \n\t" + "pxor %%mm0, %%mm0 \n\t" + // step ecx to next set of 8 bytes and repeat loop til done + "addl $8, %%ecx \n\t" + "packuswb %%mm7, %%mm1 \n\t" + "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) + "cmpl _MMXLength, %%ecx \n\t" + "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + "jb paeth_8lp \n\t" + + : "=S" (dummy_value_S), // output regs (dummy) + "=D" (dummy_value_D) + + : "0" (prev_row), // esi // input regs + "1" (row) // edi + + : "%ecx" // clobber list +#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; // end 8 bpp + + case 1: // bpp = 1 + case 2: // bpp = 2 + default: // bpp > 8 + { + __asm__ __volatile__ ( +#ifdef __PIC__ + "pushl %%ebx \n\t" // save Global Offset Table index +#endif + "movl _dif, %%ebx \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jnb paeth_dend \n\t" + +// preload "movl row, %%edi \n\t" +// preload "movl prev_row, %%esi \n\t" + // do Paeth decode for remaining bytes + "movl %%ebx, %%edx \n\t" +// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx = ebx - bpp + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx + + "paeth_dlp: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_dpca \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_dpca: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_dpba \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_dpba: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_dpaa \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_dpaa: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_dabb \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_dbbc \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dbbc: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dabb: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_dabc \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_dpaeth \n\t" + + "paeth_dabc: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_dpaeth: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jb paeth_dlp \n\t" + + "paeth_dend: \n\t" +#ifdef __PIC__ + "popl %%ebx \n\t" // index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list +#ifndef __PIC__ + , "%ebx" +#endif + ); + } + return; // No need to go further with this one + + } // end switch (bpp) + + __asm__ __volatile__ ( + // MMX acceleration complete; now do clean-up + // check if any remaining bytes left to decode +#ifdef __PIC__ + "pushl %%ebx \n\t" // save index to Global Offset Table +#endif + "movl _MMXLength, %%ebx \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jnb paeth_end \n\t" +//pre "movl row, %%edi \n\t" +//pre "movl prev_row, %%esi \n\t" + // do Paeth decode for remaining bytes + "movl %%ebx, %%edx \n\t" +//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) + "subl %%ecx, %%edx \n\t" // edx = ebx - bpp + "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below + + "paeth_lp2: \n\t" + "xorl %%eax, %%eax \n\t" + // pav = p - a = (a + b - c) - a = b - c + "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, _patemp \n\t" // Save pav for later use + "xorl %%eax, %%eax \n\t" + // pbv = p - b = (a + b - c) - b = a - c + "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al + "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) + "movl %%eax, %%ecx \n\t" + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + "addl _patemp, %%eax \n\t" // pcv = pav + pbv + // pc = abs(pcv) + "testl $0x80000000, %%eax \n\t" + "jz paeth_pca2 \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_pca2: \n\t" + "movl %%eax, _pctemp \n\t" // save pc for later use + // pb = abs(pbv) + "testl $0x80000000, %%ecx \n\t" + "jz paeth_pba2 \n\t" + "negl %%ecx \n\t" // reverse sign of neg values + + "paeth_pba2: \n\t" + "movl %%ecx, _pbtemp \n\t" // save pb for later use + // pa = abs(pav) + "movl _patemp, %%eax \n\t" + "testl $0x80000000, %%eax \n\t" + "jz paeth_paa2 \n\t" + "negl %%eax \n\t" // reverse sign of neg values + + "paeth_paa2: \n\t" + "movl %%eax, _patemp \n\t" // save pa for later use + // test if pa <= pb + "cmpl %%ecx, %%eax \n\t" + "jna paeth_abb2 \n\t" + // pa > pb; now test if pb <= pc + "cmpl _pctemp, %%ecx \n\t" + "jna paeth_bbc2 \n\t" + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_bbc2: \n\t" + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_abb2: \n\t" + // pa <= pb; now test if pa <= pc + "cmpl _pctemp, %%eax \n\t" + "jna paeth_abc2 \n\t" + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl + "jmp paeth_paeth2 \n\t" + + "paeth_abc2: \n\t" + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl + + "paeth_paeth2: \n\t" + "incl %%ebx \n\t" + "incl %%edx \n\t" + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + "addb %%cl, -1(%%edi,%%ebx,) \n\t" + "cmpl _FullLength, %%ebx \n\t" + "jb paeth_lp2 \n\t" + + "paeth_end: \n\t" + "EMMS \n\t" // end MMX; prep for poss. FP instrs. +#ifdef __PIC__ + "popl %%ebx \n\t" // restore index to Global Offset Table +#endif + + : "=c" (dummy_value_c), // output regs (dummy) + "=S" (dummy_value_S), + "=D" (dummy_value_D) + + : "0" (bpp), // ecx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%edx" // clobber list (no input regs!) +#ifndef __PIC__ + , "%ebx" +#endif + ); + +} /* end png_read_filter_row_mmx_paeth() */ +#endif + + + + +#ifdef PNG_THREAD_UNSAFE_OK +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B // +// // +//===========================================================================// + +// Optimized code for PNG Sub filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) +{ + int bpp; + int dummy_value_a; + int dummy_value_D; + + bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel + _FullLength = row_info->rowbytes - bpp; // number of bytes to filter + + __asm__ __volatile__ ( +//pre "movl row, %%edi \n\t" + "movl %%edi, %%esi \n\t" // lp = row +//pre "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp +//irr "xorl %%eax, %%eax \n\t" + // get # of bytes to alignment + "movl %%edi, _dif \n\t" // take start of row + "addl $0xf, _dif \n\t" // add 7 + 8 to incr past + // alignment boundary + "xorl %%ecx, %%ecx \n\t" + "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary + "subl %%edi, _dif \n\t" // subtract from start ==> value + "jz sub_go \n\t" // ecx at alignment + + "sub_lp1: \n\t" // fix alignment + "movb (%%esi,%%ecx,), %%al \n\t" + "addb %%al, (%%edi,%%ecx,) \n\t" + "incl %%ecx \n\t" + "cmpl _dif, %%ecx \n\t" + "jb sub_lp1 \n\t" + + "sub_go: \n\t" + "movl _FullLength, %%eax \n\t" + "movl %%eax, %%edx \n\t" + "subl %%ecx, %%edx \n\t" // subtract alignment fix + "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 + "subl %%edx, %%eax \n\t" // drop over bytes from length + "movl %%eax, _MMXLength \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%esi", "%ecx", "%edx" // clobber list + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + + // now do the math for the rest of the row + switch (bpp) + { + case 3: + { + _ActiveMask.use = 0x0000ffffff000000LL; + _ShiftBpp.use = 24; // == 3 * 8 + _ShiftRem.use = 40; // == 64 - 24 + + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd + // active byte group + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "movq %%mm7, %%mm6 \n\t" + "movl _dif, %%edx \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover + // 3rd active byte group + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_3lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + // add 1st active group + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 3rd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_3lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm6", "%mm7" +#endif + ); + } + break; + + case 1: + { + __asm__ __volatile__ ( + "movl _dif, %%edx \n\t" +// preload "movl row, %%edi \n\t" + "cmpl _FullLength, %%edx \n\t" + "jnb sub_1end \n\t" + "movl %%edi, %%esi \n\t" // lp = row + "xorl %%eax, %%eax \n\t" +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + "sub_1lp: \n\t" + "movb (%%esi,%%edx,), %%al \n\t" + "addb %%al, (%%edi,%%edx,) \n\t" + "incl %%edx \n\t" + "cmpl _FullLength, %%edx \n\t" + "jb sub_1lp \n\t" + + "sub_1end: \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list + ); + } + return; + + case 6: + case 4: + //case 7: // GRR BOGUS + //case 5: // GRR BOGUS + { + _ShiftBpp.use = bpp << 3; + _ShiftRem.use = 64 - _ShiftBpp.use; + + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movl _dif, %%edx \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_4lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_4lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1" +#endif + ); + } + break; + + case 2: + { + _ActiveMask.use = 0x00000000ffff0000LL; + _ShiftBpp.use = 16; // == 2 * 8 + _ShiftRem.use = 48; // == 64 - 16 + + __asm__ __volatile__ ( + "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd + // active byte group + "movl _dif, %%edx \n\t" + "movq %%mm7, %%mm6 \n\t" +// preload "movl row, %%edi \n\t" + "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover + // 3rd active byte group + "movl %%edi, %%esi \n\t" // lp = row + "movq %%mm6, %%mm5 \n\t" +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "psllq _ShiftBpp, %%mm5 \n\t" // move mask in mm5 to cover + // 4th active byte group + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm1 \n\t" + + "sub_2lp: \n\t" // shift data for adding first + "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; + // shift clears inactive bytes) + // add 1st active group + "movq (%%edi,%%edx,), %%mm0 \n\t" + "paddb %%mm1, %%mm0 \n\t" + + // add 2nd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 3rd active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group + "paddb %%mm1, %%mm0 \n\t" + + // add 4th active group + "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 + "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly + "pand %%mm5, %%mm1 \n\t" // mask to use 4th active group + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array + "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop + "jb sub_2lp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; + + case 8: + { + __asm__ __volatile__ ( +// preload "movl row, %%edi \n\t" + "movl _dif, %%edx \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "movl _MMXLength, %%ecx \n\t" + + // prime the pump: load the first Raw(x-bpp) data set + "movq -8(%%edi,%%edx,), %%mm7 \n\t" + "andl $0x0000003f, %%ecx \n\t" // calc bytes over mult of 64 + + "sub_8lp: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" // load Sub(x) for 1st 8 bytes + "paddb %%mm7, %%mm0 \n\t" + "movq 8(%%edi,%%edx,), %%mm1 \n\t" // load Sub(x) for 2nd 8 bytes + "movq %%mm0, (%%edi,%%edx,) \n\t" // write Raw(x) for 1st 8 bytes + + // Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes. + // This will be repeated for each group of 8 bytes with the 8th + // group being used as the Raw(x-bpp) for the 1st group of the + // next loop. + + "paddb %%mm0, %%mm1 \n\t" + "movq 16(%%edi,%%edx,), %%mm2 \n\t" // load Sub(x) for 3rd 8 bytes + "movq %%mm1, 8(%%edi,%%edx,) \n\t" // write Raw(x) for 2nd 8 bytes + "paddb %%mm1, %%mm2 \n\t" + "movq 24(%%edi,%%edx,), %%mm3 \n\t" // load Sub(x) for 4th 8 bytes + "movq %%mm2, 16(%%edi,%%edx,) \n\t" // write Raw(x) for 3rd 8 bytes + "paddb %%mm2, %%mm3 \n\t" + "movq 32(%%edi,%%edx,), %%mm4 \n\t" // load Sub(x) for 5th 8 bytes + "movq %%mm3, 24(%%edi,%%edx,) \n\t" // write Raw(x) for 4th 8 bytes + "paddb %%mm3, %%mm4 \n\t" + "movq 40(%%edi,%%edx,), %%mm5 \n\t" // load Sub(x) for 6th 8 bytes + "movq %%mm4, 32(%%edi,%%edx,) \n\t" // write Raw(x) for 5th 8 bytes + "paddb %%mm4, %%mm5 \n\t" + "movq 48(%%edi,%%edx,), %%mm6 \n\t" // load Sub(x) for 7th 8 bytes + "movq %%mm5, 40(%%edi,%%edx,) \n\t" // write Raw(x) for 6th 8 bytes + "paddb %%mm5, %%mm6 \n\t" + "movq 56(%%edi,%%edx,), %%mm7 \n\t" // load Sub(x) for 8th 8 bytes + "movq %%mm6, 48(%%edi,%%edx,) \n\t" // write Raw(x) for 7th 8 bytes + "addl $64, %%edx \n\t" + "paddb %%mm6, %%mm7 \n\t" + "cmpl %%ecx, %%edx \n\t" + "movq %%mm7, -8(%%edi,%%edx,) \n\t" // write Raw(x) for 8th 8 bytes + "jb sub_8lp \n\t" + + "cmpl _MMXLength, %%edx \n\t" + "jnb sub_8lt8 \n\t" + + "sub_8lpA: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" + "addl $8, %%edx \n\t" + "paddb %%mm7, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // -8 to offset early addl edx + "movq %%mm0, %%mm7 \n\t" // move calculated Raw(x) data + // to mm1 to be new Raw(x-bpp) + // for next loop + "jb sub_8lpA \n\t" + + "sub_8lt8: \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%ecx", "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + } + break; + + default: // bpp greater than 8 bytes GRR BOGUS + { + __asm__ __volatile__ ( + "movl _dif, %%edx \n\t" +// preload "movl row, %%edi \n\t" + "movl %%edi, %%esi \n\t" // lp = row +// preload "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + + "sub_Alp: \n\t" + "movq (%%edi,%%edx,), %%mm0 \n\t" + "movq (%%esi,%%edx,), %%mm1 \n\t" + "addl $8, %%edx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl _MMXLength, %%edx \n\t" + "movq %%mm0, -8(%%edi,%%edx,) \n\t" // mov does not affect flags; + // -8 to offset addl edx + "jb sub_Alp \n\t" + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1" +#endif + ); + } + break; + + } // end switch (bpp) + + __asm__ __volatile__ ( + "movl _MMXLength, %%edx \n\t" +//pre "movl row, %%edi \n\t" + "cmpl _FullLength, %%edx \n\t" + "jnb sub_end \n\t" + + "movl %%edi, %%esi \n\t" // lp = row +//pre "movl bpp, %%eax \n\t" + "addl %%eax, %%edi \n\t" // rp = row + bpp + "xorl %%eax, %%eax \n\t" + + "sub_lp2: \n\t" + "movb (%%esi,%%edx,), %%al \n\t" + "addb %%al, (%%edi,%%edx,) \n\t" + "incl %%edx \n\t" + "cmpl _FullLength, %%edx \n\t" + "jb sub_lp2 \n\t" + + "sub_end: \n\t" + "EMMS \n\t" // end MMX instructions + + : "=a" (dummy_value_a), // 0 // output regs (dummy) + "=D" (dummy_value_D) // 1 + + : "0" (bpp), // eax // input regs + "1" (row) // edi + + : "%edx", "%esi" // clobber list + ); + +} // end of png_read_filter_row_mmx_sub() +#endif + + + + +//===========================================================================// +// // +// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P // +// // +//===========================================================================// + +// Optimized code for PNG Up filter decoder + +static void /* PRIVATE */ +png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 len; + int dummy_value_d; // fix 'forbidden register 3 (dx) was spilled' error + int dummy_value_S; + int dummy_value_D; + + len = row_info->rowbytes; // number of bytes to filter + + __asm__ __volatile__ ( +//pre "movl row, %%edi \n\t" + // get # of bytes to alignment +#ifdef __PIC__ + "pushl %%ebx \n\t" +#endif + "movl %%edi, %%ecx \n\t" + "xorl %%ebx, %%ebx \n\t" + "addl $0x7, %%ecx \n\t" + "xorl %%eax, %%eax \n\t" + "andl $0xfffffff8, %%ecx \n\t" +//pre "movl prev_row, %%esi \n\t" + "subl %%edi, %%ecx \n\t" + "jz up_go \n\t" + + "up_lp1: \n\t" // fix alignment + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to + "jb up_lp1 \n\t" // offset incl ebx + + "up_go: \n\t" +//pre "movl len, %%edx \n\t" + "movl %%edx, %%ecx \n\t" + "subl %%ebx, %%edx \n\t" // subtract alignment fix + "andl $0x0000003f, %%edx \n\t" // calc bytes over mult of 64 + "subl %%edx, %%ecx \n\t" // drop over bytes from length + + // unrolled loop - use all MMX registers and interleave to reduce + // number of branch instructions (loops) and reduce partial stalls + "up_loop: \n\t" + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "movq 8(%%esi,%%ebx,), %%mm3 \n\t" + "paddb %%mm1, %%mm0 \n\t" + "movq 8(%%edi,%%ebx,), %%mm2 \n\t" + "movq %%mm0, (%%edi,%%ebx,) \n\t" + "paddb %%mm3, %%mm2 \n\t" + "movq 16(%%esi,%%ebx,), %%mm5 \n\t" + "movq %%mm2, 8(%%edi,%%ebx,) \n\t" + "movq 16(%%edi,%%ebx,), %%mm4 \n\t" + "movq 24(%%esi,%%ebx,), %%mm7 \n\t" + "paddb %%mm5, %%mm4 \n\t" + "movq 24(%%edi,%%ebx,), %%mm6 \n\t" + "movq %%mm4, 16(%%edi,%%ebx,) \n\t" + "paddb %%mm7, %%mm6 \n\t" + "movq 32(%%esi,%%ebx,), %%mm1 \n\t" + "movq %%mm6, 24(%%edi,%%ebx,) \n\t" + "movq 32(%%edi,%%ebx,), %%mm0 \n\t" + "movq 40(%%esi,%%ebx,), %%mm3 \n\t" + "paddb %%mm1, %%mm0 \n\t" + "movq 40(%%edi,%%ebx,), %%mm2 \n\t" + "movq %%mm0, 32(%%edi,%%ebx,) \n\t" + "paddb %%mm3, %%mm2 \n\t" + "movq 48(%%esi,%%ebx,), %%mm5 \n\t" + "movq %%mm2, 40(%%edi,%%ebx,) \n\t" + "movq 48(%%edi,%%ebx,), %%mm4 \n\t" + "movq 56(%%esi,%%ebx,), %%mm7 \n\t" + "paddb %%mm5, %%mm4 \n\t" + "movq 56(%%edi,%%ebx,), %%mm6 \n\t" + "movq %%mm4, 48(%%edi,%%ebx,) \n\t" + "addl $64, %%ebx \n\t" + "paddb %%mm7, %%mm6 \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movq %%mm6, -8(%%edi,%%ebx,) \n\t" // (+56)movq does not affect flags; + "jb up_loop \n\t" // -8 to offset addl ebx + + "cmpl $0, %%edx \n\t" // test for bytes over mult of 64 + "jz up_end \n\t" + + "cmpl $8, %%edx \n\t" // test for less than 8 bytes + "jb up_lt8 \n\t" // [added by lcreeve at netins.net] + + "addl %%edx, %%ecx \n\t" + "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 + "subl %%edx, %%ecx \n\t" // drop over bytes from length + "jz up_lt8 \n\t" + + "up_lpA: \n\t" // use MMX regs to update 8 bytes sim. + "movq (%%esi,%%ebx,), %%mm1 \n\t" + "movq (%%edi,%%ebx,), %%mm0 \n\t" + "addl $8, %%ebx \n\t" + "paddb %%mm1, %%mm0 \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movq %%mm0, -8(%%edi,%%ebx,) \n\t" // movq does not affect flags; -8 to + "jb up_lpA \n\t" // offset add ebx + "cmpl $0, %%edx \n\t" // test for bytes over mult of 8 + "jz up_end \n\t" + + "up_lt8: \n\t" + "xorl %%eax, %%eax \n\t" + "addl %%edx, %%ecx \n\t" // move over byte count into counter + + "up_lp2: \n\t" // use x86 regs for remaining bytes + "movb (%%edi,%%ebx,), %%al \n\t" + "addb (%%esi,%%ebx,), %%al \n\t" + "incl %%ebx \n\t" + "cmpl %%ecx, %%ebx \n\t" + "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to + "jb up_lp2 \n\t" // offset inc ebx + + "up_end: \n\t" + "EMMS \n\t" // conversion of filtered row complete +#ifdef __PIC__ + "popl %%ebx \n\t" +#endif + + : "=d" (dummy_value_d), // 0 // output regs (dummy) + "=S" (dummy_value_S), // 1 + "=D" (dummy_value_D) // 2 + + : "0" (len), // edx // input regs + "1" (prev_row), // esi + "2" (row) // edi + + : "%eax", "%ecx" // clobber list (no input regs!) +#ifndef __PIC__ + , "%ebx" +#endif + +#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ + , "%mm0", "%mm1", "%mm2", "%mm3" + , "%mm4", "%mm5", "%mm6", "%mm7" +#endif + ); + +} // end of png_read_filter_row_mmx_up() + +#endif /* PNG_MMX_CODE_SUPPORTED */ + + + + +/*===========================================================================*/ +/* */ +/* P N G _ R E A D _ F I L T E R _ R O W */ +/* */ +/*===========================================================================*/ + + +/* Optimized png_read_filter_row routines */ + +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep + row, png_bytep prev_row, int filter) +{ +#ifdef PNG_DEBUG + char filnm[10]; +#endif + +#if defined(PNG_MMX_CODE_SUPPORTED) +/* GRR: these are superseded by png_ptr->asm_flags: */ +#define UseMMX_sub 1 // GRR: converted 20000730 +#define UseMMX_up 1 // GRR: converted 20000729 +#define UseMMX_avg 1 // GRR: converted 20000828 (+ 16-bit bugfix 20000916) +#define UseMMX_paeth 1 // GRR: converted 20000828 + + if (_mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ +#if !defined(PNG_1_0_X) + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } +#endif /* PNG_MMX_CODE_SUPPORTED */ + +#ifdef PNG_DEBUG + png_debug(1, "in png_read_filter_row (pnggccrd.c)\n"); + switch (filter) + { + case 0: sprintf(filnm, "none"); + break; + case 1: sprintf(filnm, "sub-%s", +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : +#endif +#endif +"x86"); + break; + case 2: sprintf(filnm, "up-%s", +#ifdef PNG_MMX_CODE_SUPPORTED +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : +#endif +#endif + "x86"); + break; + case 3: sprintf(filnm, "avg-%s", +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : +#endif +#endif + "x86"); + break; + case 4: sprintf(filnm, "Paeth-%s", +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": +#endif +#endif +"x86"); + break; + default: sprintf(filnm, "unknw"); + break; + } + png_debug2(0, "row_number=%5ld, %5s, ", png_ptr->row_number, filnm); + png_debug1(0, "row=0x%08lx, ", (unsigned long)row); + png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth, + (int)((row_info->pixel_depth + 7) >> 3)); + png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes); +#endif /* PNG_DEBUG */ + + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + + case PNG_FILTER_VALUE_SUB: +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_sub(row_info, row); + } + else +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + } /* end !UseMMX_sub */ + break; + + case PNG_FILTER_VALUE_UP: +#if defined(PNG_MMX_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_up(row_info, row, prev_row); + } + else +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; ++i) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + } /* end !UseMMX_up */ + break; + + case PNG_FILTER_VALUE_AVG: +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_avg(row_info, row, prev_row); + } + else +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) >> 1)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++ + *lp++) >> 1)) & 0xff); + rp++; + } + } /* end !UseMMX_avg */ + break; + + case PNG_FILTER_VALUE_PAETH: +#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif + { + png_read_filter_row_mmx_paeth(row_info, row, prev_row); + } + else +#endif /* PNG_MMX_CODE_SUPPORTED */ + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) /* use leftover rp,pp */ + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + 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 + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + } /* end !UseMMX_paeth */ + break; + + default: + png_warning(png_ptr, "Ignoring bad row-filter type"); + *row=0; + break; + } +} + +#endif /* PNG_HAVE_MMX_READ_FILTER_ROW */ + + +/*===========================================================================*/ +/* */ +/* P N G _ M M X _ S U P P O R T */ +/* */ +/*===========================================================================*/ + +/* GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl) + * (2) all instructions compile with gcc 2.7.2.3 and later + * (3) the function is moved down here to prevent gcc from + * inlining it in multiple places and then barfing be- + * cause the ".NOT_SUPPORTED" label is multiply defined + * [is there a way to signal that a *single* function should + * not be inlined? is there a way to modify the label for + * each inlined instance, e.g., by appending _1, _2, etc.? + * maybe if don't use leading "." in label name? (nope...sigh)] + */ + +int PNGAPI +png_mmx_support(void) +{ +#if defined(PNG_MMX_CODE_SUPPORTED) + int result; + __asm__ __volatile__ ( + "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction + "pushl %%ecx \n\t" // so does ecx... + "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux) +// ".byte 0x66 \n\t" // convert 16-bit pushf to 32-bit pushfd +// "pushf \n\t" // 16-bit pushf + "pushfl \n\t" // save Eflag to stack + "popl %%eax \n\t" // get Eflag from stack into eax + "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx + "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21) + "pushl %%eax \n\t" // save modified Eflag back to stack +// ".byte 0x66 \n\t" // convert 16-bit popf to 32-bit popfd +// "popf \n\t" // 16-bit popf + "popfl \n\t" // restore modified value to Eflag reg + "pushfl \n\t" // save Eflag to stack + "popl %%eax \n\t" // get Eflag from stack + "pushl %%ecx \n\t" // save original Eflag to stack + "popfl \n\t" // restore original Eflag + "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag + "jz 0f \n\t" // if same, CPUID instr. is not supported + + "xorl %%eax, %%eax \n\t" // set eax to zero +// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode) + "cpuid \n\t" // get the CPU identification info + "cmpl $1, %%eax \n\t" // make sure eax return non-zero value + "jl 0f \n\t" // if eax is zero, MMX is not supported + + "xorl %%eax, %%eax \n\t" // set eax to zero and... + "incl %%eax \n\t" // ...increment eax to 1. This pair is + // faster than the instruction "mov eax, 1" + "cpuid \n\t" // get the CPU identification info again + "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23) + "cmpl $0, %%edx \n\t" // 0 = MMX not supported + "jz 0f \n\t" // non-zero = yes, MMX IS supported + + "movl $1, %%eax \n\t" // set return value to 1 + "jmp 1f \n\t" // DONE: have MMX support + + "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions + "movl $0, %%eax \n\t" // set return value to 0 + "1: \n\t" // .RETURN: target label for jump instructions + "popl %%edx \n\t" // restore edx + "popl %%ecx \n\t" // restore ecx + "popl %%ebx \n\t" // restore ebx + +// "ret \n\t" // DONE: no MMX support + // (fall through to standard C "ret") + + : "=a" (result) // output list + + : // any variables used on input (none) + + // no clobber list +// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually +// , "memory" // if write to a variable gcc thought was in a reg +// , "cc" // "condition codes" (flag bits) + ); + _mmx_supported = result; +#else + _mmx_supported = 0; +#endif /* PNG_MMX_CODE_SUPPORTED */ + + return _mmx_supported; +} + + +#endif /* PNG_USE_PNGGCCRD */ diff --git a/src/dep/src/irrlicht/libpng/pngget.c b/src/dep/src/irrlicht/libpng/pngget.c new file mode 100644 index 0000000..fc41b9b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngget.c @@ -0,0 +1,955 @@ + +/* pngget.c - retrieval of values from info struct + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +png_uint_32 PNGAPI +png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->valid & flag); + else + return(0); +} + +png_uint_32 PNGAPI +png_get_rowbytes(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->rowbytes); + else + return(0); +} + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +png_bytepp PNGAPI +png_get_rows(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->row_pointers); + else + return(0); +} +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* easy access to info, added in libpng-0.99 */ +png_uint_32 PNGAPI +png_get_image_width(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->width; + } + return (0); +} + +png_uint_32 PNGAPI +png_get_image_height(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->height; + } + return (0); +} + +png_byte PNGAPI +png_get_bit_depth(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->bit_depth; + } + return (0); +} + +png_byte PNGAPI +png_get_color_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->color_type; + } + return (0); +} + +png_byte PNGAPI +png_get_filter_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->filter_type; + } + return (0); +} + +png_byte PNGAPI +png_get_interlace_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->interlace_type; + } + return (0); +} + +png_byte PNGAPI +png_get_compression_type(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + { + return info_ptr->compression_type; + } + return (0); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) + return (0); + else return (info_ptr->x_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) + return (0); + else return (info_ptr->y_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter"); + if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER || + info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit) + return (0); + else return (info_ptr->x_pixels_per_unit); + } +#else + return (0); +#endif + return (0); +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio"); + if (info_ptr->x_pixels_per_unit == 0) + return ((float)0.0); + else + return ((float)((float)info_ptr->y_pixels_per_unit + /(float)info_ptr->x_pixels_per_unit)); + } +#else + return (0.0); +#endif + return ((float)0.0); +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + return (0); + else return (info_ptr->x_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + return (0); + else return (info_ptr->y_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + return (0); + else return (info_ptr->x_offset); + } +#else + return (0); +#endif + return (0); +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) +#if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + { + png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); + if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + return (0); + else return (info_ptr->y_offset); + } +#else + return (0); +#endif + return (0); +} + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +png_uint_32 PNGAPI +png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) +{ + return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr) + *.0254 +.5)); +} + +float PNGAPI +png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr) +{ + return ((float)png_get_x_offset_microns(png_ptr, info_ptr) + *.00003937); +} + +float PNGAPI +png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr) +{ + return ((float)png_get_y_offset_microns(png_ptr, info_ptr) + *.00003937); +} + +#if defined(PNG_pHYs_SUPPORTED) +png_uint_32 PNGAPI +png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function\n", "pHYs"); + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + if(*unit_type == 1) + { + if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); + if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); + } + } + } + return (retval); +} +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* png_get_channels really belongs in here, too, but it's been around longer */ + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +png_byte PNGAPI +png_get_channels(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); + else + return (0); +} + +png_bytep PNGAPI +png_get_signature(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + else + return (NULL); +} + +#if defined(PNG_bKGD_SUPPORTED) +png_uint_32 PNGAPI +png_get_bKGD(png_structp png_ptr, png_infop info_ptr, + png_color_16p *background) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) + && background != NULL) + { + png_debug1(1, "in %s retrieval function\n", "bKGD"); + *background = &(info_ptr->background); + return (PNG_INFO_bKGD); + } + return (0); +} +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_structp png_ptr, png_infop info_ptr, + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_debug1(1, "in %s retrieval function\n", "cHRM"); + if (white_x != NULL) + *white_x = (double)info_ptr->x_white; + if (white_y != NULL) + *white_y = (double)info_ptr->y_white; + if (red_x != NULL) + *red_x = (double)info_ptr->x_red; + if (red_y != NULL) + *red_y = (double)info_ptr->y_red; + if (green_x != NULL) + *green_x = (double)info_ptr->x_green; + if (green_y != NULL) + *green_y = (double)info_ptr->y_green; + if (blue_x != NULL) + *blue_x = (double)info_ptr->x_blue; + if (blue_y != NULL) + *blue_y = (double)info_ptr->y_blue; + return (PNG_INFO_cHRM); + } + return (0); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, + png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + { + png_debug1(1, "in %s retrieval function\n", "cHRM"); + if (white_x != NULL) + *white_x = info_ptr->int_x_white; + if (white_y != NULL) + *white_y = info_ptr->int_y_white; + if (red_x != NULL) + *red_x = info_ptr->int_x_red; + if (red_y != NULL) + *red_y = info_ptr->int_y_red; + if (green_x != NULL) + *green_x = info_ptr->int_x_green; + if (green_y != NULL) + *green_y = info_ptr->int_y_green; + if (blue_x != NULL) + *blue_x = info_ptr->int_x_blue; + if (blue_y != NULL) + *blue_y = info_ptr->int_y_blue; + return (PNG_INFO_cHRM); + } + return (0); +} +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && file_gamma != NULL) + { + png_debug1(1, "in %s retrieval function\n", "gAMA"); + *file_gamma = (double)info_ptr->gamma; + return (PNG_INFO_gAMA); + } + return (0); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *int_file_gamma) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && int_file_gamma != NULL) + { + png_debug1(1, "in %s retrieval function\n", "gAMA"); + *int_file_gamma = info_ptr->int_gamma; + return (PNG_INFO_gAMA); + } + return (0); +} +#endif +#endif + +#if defined(PNG_sRGB_SUPPORTED) +png_uint_32 PNGAPI +png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) + && file_srgb_intent != NULL) + { + png_debug1(1, "in %s retrieval function\n", "sRGB"); + *file_srgb_intent = (int)info_ptr->srgb_intent; + return (PNG_INFO_sRGB); + } + return (0); +} +#endif + +#if defined(PNG_iCCP_SUPPORTED) +png_uint_32 PNGAPI +png_get_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) + && name != NULL && profile != NULL && proflen != NULL) + { + png_debug1(1, "in %s retrieval function\n", "iCCP"); + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; + /* compression_type is a dummy so the API won't have to change + if we introduce multiple compression types later. */ + *proflen = (int)info_ptr->iccp_proflen; + *compression_type = (int)info_ptr->iccp_compression; + return (PNG_INFO_iCCP); + } + return (0); +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +png_uint_32 PNGAPI +png_get_sPLT(png_structp png_ptr, png_infop info_ptr, + png_sPLT_tpp spalettes) +{ + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + *spalettes = info_ptr->splt_palettes; + return ((png_uint_32)info_ptr->splt_palettes_num); +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +png_uint_32 PNGAPI +png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) + && hist != NULL) + { + png_debug1(1, "in %s retrieval function\n", "hIST"); + *hist = info_ptr->hist; + return (PNG_INFO_hIST); + } + return (0); +} +#endif + +png_uint_32 PNGAPI +png_get_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) + +{ + if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && + bit_depth != NULL && color_type != NULL) + { + png_debug1(1, "in %s retrieval function\n", "IHDR"); + *width = info_ptr->width; + *height = info_ptr->height; + *bit_depth = info_ptr->bit_depth; + if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) + png_error(png_ptr, "Invalid bit depth"); + *color_type = info_ptr->color_type; + if (info_ptr->color_type > 6) + png_error(png_ptr, "Invalid color type"); + if (compression_type != NULL) + *compression_type = info_ptr->compression_type; + if (filter_type != NULL) + *filter_type = info_ptr->filter_type; + if (interlace_type != NULL) + *interlace_type = info_ptr->interlace_type; + + /* check for potential overflow of rowbytes */ + if (*width == 0 || *width > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image width"); + if (*height == 0 || *height > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image height"); + if (info_ptr->width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + { + png_warning(png_ptr, + "Width too large for libpng to process image data."); + } + return (1); + } + return (0); +} + +#if defined(PNG_oFFs_SUPPORTED) +png_uint_32 PNGAPI +png_get_oFFs(png_structp png_ptr, png_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) + && offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + png_debug1(1, "in %s retrieval function\n", "oFFs"); + *offset_x = info_ptr->x_offset; + *offset_y = info_ptr->y_offset; + *unit_type = (int)info_ptr->offset_unit_type; + return (PNG_INFO_oFFs); + } + return (0); +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +png_uint_32 PNGAPI +png_get_pCAL(png_structp png_ptr, png_infop info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) + && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) + { + png_debug1(1, "in %s retrieval function\n", "pCAL"); + *purpose = info_ptr->pcal_purpose; + *X0 = info_ptr->pcal_X0; + *X1 = info_ptr->pcal_X1; + *type = (int)info_ptr->pcal_type; + *nparams = (int)info_ptr->pcal_nparams; + *units = info_ptr->pcal_units; + *params = info_ptr->pcal_params; + return (PNG_INFO_pCAL); + } + return (0); +} +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_structp png_ptr, png_infop info_ptr, + int *unit, double *width, double *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_pixel_width; + *height = info_ptr->scal_pixel_height; + return (PNG_INFO_sCAL); + } + return(0); +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int *unit, png_charpp width, png_charpp height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; + *height = info_ptr->scal_s_height; + return (PNG_INFO_sCAL); + } + return(0); +} +#endif +#endif +#endif + +#if defined(PNG_pHYs_SUPPORTED) +png_uint_32 PNGAPI +png_get_pHYs(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function\n", "pHYs"); + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + } + } + return (retval); +} +#endif + +png_uint_32 PNGAPI +png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, + int *num_palette) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) + && palette != NULL) + { + png_debug1(1, "in %s retrieval function\n", "PLTE"); + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; + png_debug1(3, "num_palette = %d\n", *num_palette); + return (PNG_INFO_PLTE); + } + return (0); +} + +#if defined(PNG_sBIT_SUPPORTED) +png_uint_32 PNGAPI +png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) + && sig_bit != NULL) + { + png_debug1(1, "in %s retrieval function\n", "sBIT"); + *sig_bit = &(info_ptr->sig_bit); + return (PNG_INFO_sBIT); + } + return (0); +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) +png_uint_32 PNGAPI +png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, + int *num_text) +{ + if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) + { + png_debug1(1, "in %s retrieval function\n", + (png_ptr->chunk_name[0] == '\0' ? "text" + : (png_const_charp)png_ptr->chunk_name)); + if (text_ptr != NULL) + *text_ptr = info_ptr->text; + if (num_text != NULL) + *num_text = info_ptr->num_text; + return ((png_uint_32)info_ptr->num_text); + } + if (num_text != NULL) + *num_text = 0; + return(0); +} +#endif + +#if defined(PNG_tIME_SUPPORTED) +png_uint_32 PNGAPI +png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) + && mod_time != NULL) + { + png_debug1(1, "in %s retrieval function\n", "tIME"); + *mod_time = &(info_ptr->mod_time); + return (PNG_INFO_tIME); + } + return (0); +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +png_uint_32 PNGAPI +png_get_tRNS(png_structp png_ptr, png_infop info_ptr, + png_bytep *trans, int *num_trans, png_color_16p *trans_values) +{ + png_uint_32 retval = 0; + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_debug1(1, "in %s retrieval function\n", "tRNS"); + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (trans != NULL) + { + *trans = info_ptr->trans; + retval |= PNG_INFO_tRNS; + } + if (trans_values != NULL) + *trans_values = &(info_ptr->trans_values); + } + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ + { + if (trans_values != NULL) + { + *trans_values = &(info_ptr->trans_values); + retval |= PNG_INFO_tRNS; + } + if(trans != NULL) + *trans = NULL; + } + if(num_trans != NULL) + { + *num_trans = info_ptr->num_trans; + retval |= PNG_INFO_tRNS; + } + } + return (retval); +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +png_uint_32 PNGAPI +png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, + png_unknown_chunkpp unknowns) +{ + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) + *unknowns = info_ptr->unknown_chunks; + return ((png_uint_32)info_ptr->unknown_chunks_num); +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +png_byte PNGAPI +png_get_rgb_to_gray_status (png_structp png_ptr) +{ + return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0); +} +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +png_voidp PNGAPI +png_get_user_chunk_ptr(png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_chunk_ptr : NULL); +} +#endif + +#ifdef PNG_WRITE_SUPPORTED +png_uint_32 PNGAPI +png_get_compression_buffer_size(png_structp png_ptr) +{ + return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L); +} +#endif + +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#ifndef PNG_1_0_X +/* this function was added to libpng 1.2.0 and should exist by default */ +png_uint_32 PNGAPI +png_get_asm_flags (png_structp png_ptr) +{ +#ifdef PNG_MMX_CODE_SUPPORTED + return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L); +#else + return (png_ptr? 0L: 0L); +#endif +} + +/* this function was added to libpng 1.2.0 and should exist by default */ +png_uint_32 PNGAPI +png_get_asm_flagmask (int flag_select) +{ +#ifdef PNG_MMX_CODE_SUPPORTED + png_uint_32 settable_asm_flags = 0; + + if (flag_select & PNG_SELECT_READ) + settable_asm_flags |= + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | + PNG_ASM_FLAG_MMX_READ_INTERLACE | + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; + /* no non-MMX flags yet */ + +#if 0 + /* GRR: no write-flags yet, either, but someday... */ + if (flag_select & PNG_SELECT_WRITE) + settable_asm_flags |= + PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; +#endif /* 0 */ + + return settable_asm_flags; /* _theoretically_ settable capabilities only */ +#else + return (0L); +#endif /* PNG_MMX_CODE_SUPPORTED */ +} + + + /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ +/* this function was added to libpng 1.2.0 */ +png_uint_32 PNGAPI +png_get_mmx_flagmask (int flag_select, int *compilerID) +{ +#if defined(PNG_MMX_CODE_SUPPORTED) + png_uint_32 settable_mmx_flags = 0; + + if (flag_select & PNG_SELECT_READ) + settable_mmx_flags |= + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | + PNG_ASM_FLAG_MMX_READ_INTERLACE | + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; +#if 0 + /* GRR: no MMX write support yet, but someday... */ + if (flag_select & PNG_SELECT_WRITE) + settable_mmx_flags |= + PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; +#endif /* 0 */ + + if (compilerID != NULL) { +#ifdef PNG_USE_PNGVCRD + *compilerID = 1; /* MSVC */ +#else +#ifdef PNG_USE_PNGGCCRD + *compilerID = 2; /* gcc/gas */ +#else + *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */ +#endif +#endif + } + + return settable_mmx_flags; /* _theoretically_ settable capabilities only */ +#else + return (0L); +#endif /* ?PNG_MMX_CODE_SUPPORTED */ +} + +/* this function was added to libpng 1.2.0 */ +png_byte PNGAPI +png_get_mmx_bitdepth_threshold (png_structp png_ptr) +{ +#if defined(PNG_MMX_CODE_SUPPORTED) + return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0); +#else + return (png_ptr? 0: 0); +#endif /* ?PNG_MMX_CODE_SUPPORTED */ +} + +/* this function was added to libpng 1.2.0 */ +png_uint_32 PNGAPI +png_get_mmx_rowbytes_threshold (png_structp png_ptr) +{ +#if defined(PNG_MMX_CODE_SUPPORTED) + return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); +#else + return (png_ptr? 0L: 0L); +#endif /* ?PNG_MMX_CODE_SUPPORTED */ +} +#endif /* ?PNG_1_0_X */ +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* these functions were added to libpng 1.2.6 */ +png_uint_32 PNGAPI +png_get_user_width_max (png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_width_max : 0); +} +png_uint_32 PNGAPI +png_get_user_height_max (png_structp png_ptr) +{ + return (png_ptr? png_ptr->user_height_max : 0); +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngmem.c b/src/dep/src/irrlicht/libpng/pngmem.c new file mode 100644 index 0000000..6aa70af --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngmem.c @@ -0,0 +1,608 @@ + +/* pngmem.c - stub functions for 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 memory allocation. Users who + * need special memory handling are expected to supply replacement + * functions for png_malloc() and png_free(), and to use + * png_create_read_struct_2() and png_create_write_struct_2() to + * identify the replacement functions. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +/* Borland DOS special memory handler */ +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* if you change this, be sure to change the one in png.h also */ + +/* Allocate memory for a png_struct. The malloc and memset can be replaced + by a single call to calloc() if this is thought to improve performance. */ +png_voidp /* PRIVATE */ +png_create_struct(int type) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); +} + +/* Alternate version of png_create_struct, for use with user-defined malloc. */ +png_voidp /* PRIVATE */ +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + else + return (png_get_copyright(NULL)); + +#ifdef PNG_USER_MEM_SUPPORTED + if(malloc_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); + } + else +#endif /* PNG_USER_MEM_SUPPORTED */ + struct_ptr = (png_voidp)farmalloc(size); + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + return (struct_ptr); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +#endif + if (struct_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + if(free_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + (*(free_fn))(png_ptr, struct_ptr); + return; + } +#endif /* PNG_USER_MEM_SUPPORTED */ + farfree (struct_ptr); + } +} + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + * + * Borland seems to have a problem in DOS mode for exactly 64K. + * It gives you a segment with an offset of 8 (perhaps to store its + * memory stuff). zlib doesn't like this at all, so we have to + * detect and deal with it. This code should not be needed in + * Windows or OS/2 modes, and only in 16 bit mode. This code has + * been updated by Alexander Lehmann for version 0.89 to waste less + * memory. + * + * Note that we can't use png_size_t for the "size" declaration, + * since on some systems a png_size_t is a 16-bit quantity, and as a + * result, we would be truncating potentially larger memory requests + * (which should cause a fatal error) and introducing major problems. + */ + +png_voidp PNGAPI +png_malloc(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; + + if (png_ptr == NULL || size == 0) + return (NULL); + +#ifdef PNG_USER_MEM_SUPPORTED + if(png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else + ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory!"); + return (ret); +} + +png_voidp PNGAPI +png_malloc_default(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || size == 0) + return (NULL); + +#ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { + png_warning(png_ptr, "Cannot Allocate > 64K"); + ret = NULL; + } + else +#endif + + if (size != (size_t)size) + ret = NULL; + else if (size == (png_uint_32)65536L) + { + if (png_ptr->offset_table == NULL) + { + /* try to see if we need to do any of this fancy stuff */ + ret = farmalloc(size); + if (ret == NULL || ((png_size_t)ret & 0xffff)) + { + int num_blocks; + png_uint_32 total_size; + png_bytep table; + int i; + png_byte huge * hptr; + + if (ret != NULL) + { + farfree(ret); + ret = NULL; + } + + if(png_ptr->zlib_window_bits > 14) + num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); + else + num_blocks = 1; + if (png_ptr->zlib_mem_level >= 7) + num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); + else + num_blocks++; + + total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; + + table = farmalloc(total_size); + + if (table == NULL) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of Memory."); +#endif + return (NULL); + } + + if ((png_size_t)table & 0xfff0) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, + "Farmalloc didn't return normalized pointer"); + else + png_warning(png_ptr, + "Farmalloc didn't return normalized pointer"); +#endif + return (NULL); + } + + png_ptr->offset_table = table; + png_ptr->offset_table_ptr = farmalloc(num_blocks * + png_sizeof (png_bytep)); + + if (png_ptr->offset_table_ptr == NULL) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of memory."); +#endif + return (NULL); + } + + hptr = (png_byte huge *)table; + if ((png_size_t)hptr & 0xf) + { + hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); + hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ + } + for (i = 0; i < num_blocks; i++) + { + png_ptr->offset_table_ptr[i] = (png_bytep)hptr; + hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ + } + + png_ptr->offset_table_number = num_blocks; + png_ptr->offset_table_count = 0; + png_ptr->offset_table_count_free = 0; + } + } + + if (png_ptr->offset_table_count >= png_ptr->offset_table_number) + { +#ifndef PNG_USER_MEM_SUPPORTED + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ + else + png_warning(png_ptr, "Out of Memory."); +#endif + return (NULL); + } + + ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; + } + else + ret = farmalloc(size); + +#ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL) + { + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ + else + png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ + } +#endif + + return (ret); +} + +/* free a pointer allocated by png_malloc(). In the default + configuration, png_ptr is not used, but is passed in case it + is needed. If ptr is NULL, return without taking any action. */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + else png_free_default(png_ptr, ptr); +} + +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + + if(png_ptr == NULL) return; + + if (png_ptr->offset_table != NULL) + { + int i; + + for (i = 0; i < png_ptr->offset_table_count; i++) + { + if (ptr == png_ptr->offset_table_ptr[i]) + { + ptr = NULL; + png_ptr->offset_table_count_free++; + break; + } + } + if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) + { + farfree(png_ptr->offset_table); + farfree(png_ptr->offset_table_ptr); + png_ptr->offset_table = NULL; + png_ptr->offset_table_ptr = NULL; + } + } + + if (ptr != NULL) + { + farfree(ptr); + } +} + +#else /* Not the Borland DOS special memory handler */ + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +png_voidp /* PRIVATE */ +png_create_struct(int type) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); +} + +/* Allocate memory for a png_struct or a png_info. The malloc and + memset can be replaced by a single call to calloc() if this is thought + to improve performance noticably. */ +png_voidp /* PRIVATE */ +png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_size_t size; + png_voidp struct_ptr; + + if (type == PNG_STRUCT_INFO) + size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) + size = png_sizeof(png_struct); + else + return (NULL); + +#ifdef PNG_USER_MEM_SUPPORTED + if(malloc_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + struct_ptr = (*(malloc_fn))(png_ptr, size); + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + return (struct_ptr); + } +#endif /* PNG_USER_MEM_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(__FLAT__) + struct_ptr = (png_voidp)farmalloc(size); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + struct_ptr = (png_voidp)halloc(size,1); +# else + struct_ptr = (png_voidp)malloc(size); +# endif +#endif + if (struct_ptr != NULL) + png_memset(struct_ptr, 0, size); + + return (struct_ptr); +} + + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct(png_voidp struct_ptr) +{ +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); +} + +/* Free memory allocated by a png_create_struct() call */ +void /* PRIVATE */ +png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, + png_voidp mem_ptr) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + if (struct_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + if(free_fn != NULL) + { + png_struct dummy_struct; + png_structp png_ptr = &dummy_struct; + png_ptr->mem_ptr=mem_ptr; + (*(free_fn))(png_ptr, struct_ptr); + return; + } +#endif /* PNG_USER_MEM_SUPPORTED */ +#if defined(__TURBOC__) && !defined(__FLAT__) + farfree(struct_ptr); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(struct_ptr); +# else + free(struct_ptr); +# endif +#endif + } +} + +/* Allocate memory. For reasonable files, size should never exceed + 64K. However, zlib may allocate more then 64K if you don't tell + it not to. See zconf.h and png.h for more information. zlib does + need to allocate exactly 64K, so whatever you call here must + have the ability to do that. */ + +png_voidp PNGAPI +png_malloc(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr == NULL || size == 0) + return (NULL); + + if(png_ptr->malloc_fn != NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else + ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory!"); + return (ret); +} + +png_voidp PNGAPI +png_malloc_default(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ret; +#endif /* PNG_USER_MEM_SUPPORTED */ + + if (png_ptr == NULL || size == 0) + return (NULL); + +#ifdef PNG_MAX_MALLOC_64K + if (size > (png_uint_32)65536L) + { +#ifndef PNG_USER_MEM_SUPPORTED + if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Cannot Allocate > 64K"); + else +#endif + return NULL; + } +#endif + + /* Check for overflow */ +#if defined(__TURBOC__) && !defined(__FLAT__) + if (size != (unsigned long)size) + ret = NULL; + else + ret = farmalloc(size); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + if (size != (unsigned long)size) + ret = NULL; + else + ret = halloc(size, 1); +# else + if (size != (size_t)size) + ret = NULL; + else + ret = malloc((size_t)size); +# endif +#endif + +#ifndef PNG_USER_MEM_SUPPORTED + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory"); +#endif + + return (ret); +} + +/* Free a pointer allocated by png_malloc(). If ptr is NULL, return + without taking any action. */ +void PNGAPI +png_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + { + (*(png_ptr->free_fn))(png_ptr, ptr); + return; + } + else png_free_default(png_ptr, ptr); +} +void PNGAPI +png_free_default(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#endif /* PNG_USER_MEM_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(__FLAT__) + farfree(ptr); +#else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(ptr); +# else + free(ptr); +# endif +#endif +} + +#endif /* Not Borland DOS special memory handler */ + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will set up png_malloc() to issue a png_warning and return NULL + * instead of issuing a png_error, if it fails to allocate the requested + * memory. + */ +png_voidp PNGAPI +png_malloc_warn(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ptr; + png_uint_32 save_flags; + if(png_ptr == NULL) return (NULL); + + save_flags=png_ptr->flags; + png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); + png_ptr->flags=save_flags; + return(ptr); +} +#endif + +png_voidp PNGAPI +png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, + png_uint_32 length) +{ + png_size_t size; + + size = (png_size_t)length; + if ((png_uint_32)size != length) + png_error(png_ptr,"Overflow in png_memcpy_check."); + + return(png_memcpy (s1, s2, size)); +} + +png_voidp PNGAPI +png_memset_check (png_structp png_ptr, png_voidp s1, int value, + png_uint_32 length) +{ + png_size_t size; + + size = (png_size_t)length; + if ((png_uint_32)size != length) + png_error(png_ptr,"Overflow in png_memset_check."); + + return (png_memset (s1, value, size)); + +} + +#ifdef PNG_USER_MEM_SUPPORTED +/* This function is called when the application wants to use another method + * of allocating and freeing memory. + */ +void PNGAPI +png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr + malloc_fn, png_free_ptr free_fn) +{ + if(png_ptr != NULL) { + png_ptr->mem_ptr = mem_ptr; + png_ptr->malloc_fn = malloc_fn; + png_ptr->free_fn = free_fn; + } +} + +/* This function returns a pointer to the mem_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_mem_ptr(png_structp png_ptr) +{ + if(png_ptr == NULL) return (NULL); + return ((png_voidp)png_ptr->mem_ptr); +} +#endif /* PNG_USER_MEM_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngnow.png b/src/dep/src/irrlicht/libpng/pngnow.png new file mode 100644 index 0000000000000000000000000000000000000000..82793ebddb7863266a66ffc6ab2c01ca32100808 GIT binary patch literal 2069 zcmWkudpuN&7T#yD z0ALXk%;6bOV2GtAMuxod+KXid08{XL`q<{m10|OLLYbYp~ zqD01zCx~Qa;aTH3$83tYNL5@^&dW%qu3E?~lv;*N57-E2|bs(K#(iIEOmeFx% zkcfvMOG`)&LHQ673#pIPl0s5bu0h@0>CO<}7a`Ws2_Xc#K~M$^F+q|Eqco5dLWna2 z#X^t(LKqoD8nRJmzN=KPsmsFupvRG!&XgFV8A;Y6t95Zm1LFa^q z^92erLk2B|aULIYLrE_dC!DV+A~6Qa3B~AUAmL0W(=n6@Y2+%tkPyj9RsagyA*csN zrps7?xTc~3G=mlSYRm(ZDb=D31>#001TxH*!;$k@LY&S-QNy%At*T6qc|mvuj(MT{ zShXyF6!Ad#Eru11piDK&6sbyVIXSpO33CD}%6q-XYOk*K|bUdDgx`AW{hwjYa zM<-xjEZA^`|H~$2a>8bLQKZ} zLB^Jd#VHvwfGx?~A>ERiCUg3J?OJcAAZbdf6Hk&Nk_fY$mS?2o%GPH}1d{E{WQll1 z=-8g42GdW4aQykf``V&Q6W}O#EGzZC`E*NWZcMk35*qfRc}Z6Nnc{k=W$S9olPI;+ z@nk_TpA-koOx36tuc^5+8y2dJKCX$4z2CENV(>!in*_$fq1N2jW1W6k7j=WW!K2we zQx6hfTZ3TdyW^y&(Mek}jvhFo%!~{*FP%!sE17a%?j{}9boS=;RS0g0Vl+OX*4!KG zS9cV3_T@Rcztag#Ba8Akz?VEN{KY|&-cj^8X4hI9rOS7jb^I*rs9{W6y2#E2G^qzi zdmWmqMl3bFs8=?8X$*f<{;;}lLq--wF|=g=DWXjt<5enf565lt)AmHV zIxOb73llA}$8Ct~8-~_=j#_ZB`OnsJr4>ai);+T_!|ZPhrkXB?{B)};+#9l2+7C4G z(7Hc=^#UXHmZ|>h%+um(yvmbWw|yz{+FO@id!cP~py}<7RoWpJ*Fa-`$lS+tJjBR& z6tlD4Ti8JxCZ9NMtT44qLLkP~+BFVn!|dbm^=AtK$C64)M~7nwq6^V!syIo2Oxw z>Q`G3RCIQRk}|{IuYEXq#p2PEEha{j+{?DX0X|%93;f$J-{g|;y0D)gO{G>+cUcD` z4y@ax<21CZK45QAznB)#Ufr}OXGc|jX9Ltdv+b8XbyW6-6`@zUuVY!hSGtpO`!`Qz z&NQEk%buN|_~W2YVMOhus;$a%yh2m*KG^m|>9yn4nuBHYyEpCJ)0$=kK9Wtr0td+%|?D^-C{{MH<3%xF3Nr{}sKhiFd5L0;yj%{mN`D2E@j zb9elGv{mRmpa=e4(SIT%(x!E1a$=RXWcVrny?jLXA=RCjub+PYvh*imzV73lzO2;z z^IhX}vi&XOSKIaiO6bz9{*4VIPX4pcSiyJsOr)&7MIV0tt;fiC&DW%|Q{u`km5!dp z!Uvmke~-D&46c>G#Z1ofQ!2y69!2#V?{T-pgjb1Z<)$Z0{jJ!Cd*WSVOiYG2O~X$e zkOZV!x9`)jqV>P+UU{SXLBcfJe~UZ${fApm5?rT^HZwk-)*@r4(symdMMs05ch4L& zKD%kQ5%->$aqgk4nHpEI84+blJ(2ds3O8Z;4>JTe4@PSyKg=thMLwxcsc|nVEJ)aH z*B04qWpUia=q@`HDRXoAnzt<~x%EzDW7^4`nuh7CO5MicxId`hJsvyinB5bmk2>6A rInt*5>ynshr7qiTo&3Aj@9hWbNS~fK{3iQ`;bQ_J+;C1~K%(-0k;znQ literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/pngpread.c b/src/dep/src/irrlicht/libpng/pngpread.c new file mode 100644 index 0000000..69c5959 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngpread.c @@ -0,0 +1,1589 @@ + +/* pngpread.c - read a png file in push mode + * + * Last changed in libpng 1.2.17 May 15, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + +/* push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_SKIP_MODE 3 +#define PNG_READ_tEXt_MODE 4 +#define PNG_READ_zTXt_MODE 5 +#define PNG_READ_DONE_MODE 6 +#define PNG_READ_iTXt_MODE 7 +#define PNG_ERROR_MODE 8 + +void PNGAPI +png_process_data(png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size) +{ + if(png_ptr == NULL) return; + png_push_restore_buffer(png_ptr, buffer, buffer_size); + + while (png_ptr->buffer_size) + { + png_process_some_data(png_ptr, info_ptr); + } +} + +/* What we do with the incoming data depends on what we were previously + * doing before we ran out of data... + */ +void /* PRIVATE */ +png_process_some_data(png_structp png_ptr, png_infop info_ptr) +{ + if(png_ptr == NULL) return; + switch (png_ptr->process_mode) + { + case PNG_READ_SIG_MODE: + { + png_push_read_sig(png_ptr, info_ptr); + break; + } + case PNG_READ_CHUNK_MODE: + { + png_push_read_chunk(png_ptr, info_ptr); + break; + } + case PNG_READ_IDAT_MODE: + { + png_push_read_IDAT(png_ptr); + break; + } +#if defined(PNG_READ_tEXt_SUPPORTED) + case PNG_READ_tEXt_MODE: + { + png_push_read_tEXt(png_ptr, info_ptr); + break; + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + case PNG_READ_zTXt_MODE: + { + png_push_read_zTXt(png_ptr, info_ptr); + break; + } +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + case PNG_READ_iTXt_MODE: + { + png_push_read_iTXt(png_ptr, info_ptr); + break; + } +#endif + case PNG_SKIP_MODE: + { + png_push_crc_finish(png_ptr); + break; + } + default: + { + png_ptr->buffer_size = 0; + break; + } + } +} + +/* Read any remaining signature bytes from the stream and compare them with + * the correct PNG signature. It is possible that this routine is called + * with bytes already read from the signature, either because they have been + * checked by the calling application, or because of multiple calls to this + * routine. + */ +void /* PRIVATE */ +png_push_read_sig(png_structp png_ptr, png_infop info_ptr) +{ + png_size_t num_checked = png_ptr->sig_bytes, + num_to_check = 8 - num_checked; + + if (png_ptr->buffer_size < num_to_check) + { + num_to_check = png_ptr->buffer_size; + } + + png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), + num_to_check); + png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check); + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + else + { + if (png_ptr->sig_bytes >= 8) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + } +} + +void /* PRIVATE */ +png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + /* First we make sure we have enough data for the 4 byte chunk name + * and the 4 byte chunk length before proceeding with decoding the + * chunk data. To fully decode each of these chunks, we also make + * sure we have enough data in the buffer for the 4 byte CRC at the + * end of every chunk (except IDAT, which is handled separately). + */ + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + + if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + if(png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); + } + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + + png_ptr->process_mode = PNG_READ_DONE_MODE; + png_push_have_end(png_ptr, info_ptr); + } +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + } + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); + } + else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + { + /* If we reach an IDAT chunk, this means we have read all of the + * header chunks, and we can start reading the image (or if this + * is called after the image has been read - we have an error). + */ + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + { + if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + if (png_ptr->push_length == 0) + return; + + if (png_ptr->mode & PNG_AFTER_IDAT) + png_error(png_ptr, "Too many IDAT's found"); + } + + png_ptr->idat_size = png_ptr->push_length; + png_ptr->mode |= PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info_ptr); + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream.next_out = png_ptr->row_buf; + return; + } +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); + } +#endif + else + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; +} + +void /* PRIVATE */ +png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) +{ + png_ptr->process_mode = PNG_SKIP_MODE; + png_ptr->skip_length = skip; +} + +void /* PRIVATE */ +png_push_crc_finish(png_structp png_ptr) +{ + if (png_ptr->skip_length && png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) + save_size = (png_size_t)png_ptr->skip_length; + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->skip_length && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) + save_size = (png_size_t)png_ptr->skip_length; + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->skip_length) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +} + +void PNGAPI +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) +{ + png_bytep ptr; + + if(png_ptr == NULL) return; + ptr = buffer; + if (png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->save_buffer_size) + save_size = length; + else + save_size = png_ptr->save_buffer_size; + + png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (length && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (length < png_ptr->current_buffer_size) + save_size = length; + else + save_size = png_ptr->current_buffer_size; + + png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +} + +void /* PRIVATE */ +png_push_save_buffer(png_structp png_ptr) +{ + if (png_ptr->save_buffer_size) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { + png_size_t i,istop; + png_bytep sp; + png_bytep dp; + + istop = png_ptr->save_buffer_size; + for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; + i < istop; i++, sp++, dp++) + { + *dp = *sp; + } + } + } + if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > + png_ptr->save_buffer_max) + { + png_size_t new_max; + png_bytep old_buffer; + + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + (png_ptr->current_buffer_size + 256)) + { + png_error(png_ptr, "Potential overflow of save_buffer"); + } + new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; + old_buffer = png_ptr->save_buffer; + png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, + (png_uint_32)new_max); + png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + png_free(png_ptr, old_buffer); + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { + png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; + } + png_ptr->save_buffer_ptr = png_ptr->save_buffer; + png_ptr->buffer_size = 0; +} + +void /* PRIVATE */ +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + png_ptr->current_buffer = buffer; + png_ptr->current_buffer_size = buffer_length; + png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; + png_ptr->current_buffer_ptr = png_ptr->current_buffer; +} + +void /* PRIVATE */ +png_push_read_IDAT(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) + { + png_byte chunk_length[4]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_error(png_ptr, "Not enough compressed data"); + return; + } + + png_ptr->idat_size = png_ptr->push_length; + } + if (png_ptr->idat_size && png_ptr->save_buffer_size) + { + png_size_t save_size; + + if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) + { + save_size = (png_size_t)png_ptr->idat_size; + /* check for overflow */ + if((png_uint_32)save_size != png_ptr->idat_size) + png_error(png_ptr, "save_size overflowed in pngpread"); + } + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->idat_size && png_ptr->current_buffer_size) + { + png_size_t save_size; + + if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) + { + save_size = (png_size_t)png_ptr->idat_size; + /* check for overflow */ + if((png_uint_32)save_size != png_ptr->idat_size) + png_error(png_ptr, "save_size overflowed in pngpread"); + } + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->idat_size) + { + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_crc_finish(png_ptr, 0); + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_AFTER_IDAT; + } +} + +void /* PRIVATE */ +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, + png_size_t buffer_length) +{ + int ret; + + if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) + png_error(png_ptr, "Extra compression data"); + + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = (uInt)buffer_length; + for(;;) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK) + { + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream.avail_in) + png_error(png_ptr, "Extra compressed data"); + if (!(png_ptr->zstream.avail_out)) + { + png_push_process_row(png_ptr); + } + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + else if (ret == Z_BUF_ERROR) + break; + else + png_error(png_ptr, "Decompression Error"); + } + if (!(png_ptr->zstream.avail_out)) + { + if (( +#if defined(PNG_READ_INTERLACING_SUPPORTED) + png_ptr->interlaced && png_ptr->pass > 6) || + (!png_ptr->interlaced && +#endif + png_ptr->row_number == png_ptr->num_rows)) + { + if (png_ptr->zstream.avail_in) + png_warning(png_ptr, "Too much data in IDAT chunks"); + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + png_push_process_row(png_ptr); + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream.next_out = png_ptr->row_buf; + } + else + break; + } +} + +void /* PRIVATE */ +png_push_process_row(png_structp png_ptr) +{ + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->iwidth; + png_ptr->row_info.channels = png_ptr->channels; + png_ptr->row_info.bit_depth = png_ptr->bit_depth; + png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + png_read_filter_row(png_ptr, &(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); + + png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, + png_ptr->rowbytes + 1); + + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* blow up interlaced rows to full size */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) +/* old interface (pre-1.0.9): + png_do_read_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + */ + png_do_read_interlace(png_ptr); + + switch (png_ptr->pass) + { + case 0: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 0; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */ + } + if (png_ptr->pass == 2) /* pass 1 might be empty */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + if (png_ptr->pass == 4 && png_ptr->height <= 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + if (png_ptr->pass == 6 && png_ptr->height <= 4) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 1: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 1; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 2) /* skip top 4 generated rows */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 2: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 4) /* pass 3 might be empty */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 3: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 3; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 4) /* skip top two generated rows */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 4: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 6) /* pass 5 might be empty */ + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 5: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 5; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 6) /* skip top generated row */ + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 6: + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + if (png_ptr->pass != 6) + break; + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } + } + } + else +#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } +} + +void /* PRIVATE */ +png_read_push_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + + /* Width of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; + */ + + /* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ +#endif + + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset_check(png_ptr, png_ptr->prev_row, 0, + png_ptr->rowbytes + 1); + do + { + png_ptr->pass++; + if ((png_ptr->pass == 1 && png_ptr->width < 5) || + (png_ptr->pass == 3 && png_ptr->width < 3) || + (png_ptr->pass == 5 && png_ptr->width < 2)) + png_ptr->pass++; + + if (png_ptr->pass > 7) + png_ptr->pass--; + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + if (png_ptr->transformations & PNG_INTERLACE) + break; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); + } +} + +#if defined(PNG_READ_tEXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place tEXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_tEXt_MODE; +} + +void /* PRIVATE */ +png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#if defined(PNG_MAX_MALLOC_64K) + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* empty loop */ ; + + if (text != key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; +#endif + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + png_ptr->current_text = NULL; + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); + } +} +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place zTXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + /* We can't handle zTXt chunks > 64K, since we don't have enough space + * to be able to store the uncompressed data. Actually, the threshold + * is probably around 32K, but it isn't as definite as 64K is. + */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_push_crc_skip(png_ptr, length); + return; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_zTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp key; + int ret; + png_size_t text_size, key_size; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + + key = png_ptr->current_text; + + for (text = key; *text; text++) + /* empty loop */ ; + + /* zTXt can't have zero text */ + if (text == key + png_ptr->current_text_size) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + return; + } + + text++; + + png_ptr->zstream.next_in = (png_bytep )text; + png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - + (text - key)); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + key_size = text - key; + text_size = 0; + text = NULL; + ret = Z_STREAM_END; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) + { + if (text == NULL) + { + text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + + key_size + 1)); + png_memcpy(text + key_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_memcpy(text, key, key_size); + text_size = key_size + png_ptr->zbuf_size - + png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; + } + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc(png_ptr, text_size + + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + + 1)); + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; + } + if (ret != Z_STREAM_END) + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + else + { + break; + } + + if (ret == Z_STREAM_END) + break; + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (ret != Z_STREAM_END) + { + png_ptr->current_text = NULL; + png_free(png_ptr, key); + png_free(png_ptr, text); + return; + } + + png_ptr->current_text = NULL; + png_free(png_ptr, key); + key = text; + text += key_size; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; +#endif + text_ptr->text = text; + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); + } +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +void /* PRIVATE */ +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) + { + png_error(png_ptr, "Out of place iTXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ + { + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_iTXt_MODE; +} + +void /* PRIVATE */ +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) +{ + + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp key; + int comp_flag; + png_charp lang; + png_charp lang_key; + png_charp text; + int ret; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#if defined(PNG_MAX_MALLOC_64K) + if (png_ptr->skip_length) + return; +#endif + + key = png_ptr->current_text; + + for (lang = key; *lang; lang++) + /* empty loop */ ; + + if (lang != key + png_ptr->current_text_size) + lang++; + + comp_flag = *lang++; + lang++; /* skip comp_type, always zero */ + + for (lang_key = lang; *lang_key; lang_key++) + /* empty loop */ ; + lang_key++; /* skip NUL separator */ + + for (text = lang_key; *text; text++) + /* empty loop */ ; + + if (text != key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, + (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = comp_flag + 2; + text_ptr->key = key; + text_ptr->lang = lang; + text_ptr->lang_key = lang_key; + text_ptr->text = text; + text_ptr->text_length = 0; + text_ptr->itxt_length = png_strlen(text); + + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_ptr->current_text = NULL; + + png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); + } +} +#endif + +/* This function is called when we haven't found a handler for this + * chunk. If there isn't a problem with the chunk itself (ie a bad chunk + * name or a critical chunk), the chunk is (currently) silently ignored. + */ +void /* PRIVATE */ +png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 + length) +{ + png_uint_32 skip=0; + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + + if (!(png_ptr->chunk_name[0] & 0x20)) + { +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + + /* to quiet compiler warnings about unused info_ptr */ + if (info_ptr == NULL) + return; + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) + { +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + png_strcpy((png_charp)png_ptr->unknown_chunk.name, + (png_charp)png_ptr->chunk_name); + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); + png_ptr->unknown_chunk.size = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if(png_ptr->read_user_chunk_fn != NULL) + { + /* callback to user unknown chunk handler */ + int ret; + ret = (*(png_ptr->read_user_chunk_fn)) + (png_ptr, &png_ptr->unknown_chunk); + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + if (ret == 0) + { + if (!(png_ptr->chunk_name[0] & 0x20)) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) + png_chunk_error(png_ptr, "unknown critical chunk"); + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } +#else + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); +#endif + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + else +#endif + skip=length; + png_push_crc_skip(png_ptr, skip); +} + +void /* PRIVATE */ +png_push_have_info(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_end(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr->row_fn != NULL) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, + (int)png_ptr->pass); +} + +void PNGAPI +png_progressive_combine_row (png_structp png_ptr, + png_bytep old_row, png_bytep new_row) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + const int FARDATA png_pass_dsp_mask[7] = + {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; +#endif + if(png_ptr == NULL) return; + if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ + png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); +} + +void PNGAPI +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) +{ + if(png_ptr == NULL) return; + png_ptr->info_fn = info_fn; + png_ptr->row_fn = row_fn; + png_ptr->end_fn = end_fn; + + png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); +} + +png_voidp PNGAPI +png_get_progressive_ptr(png_structp png_ptr) +{ + if(png_ptr == NULL) return (NULL); + return png_ptr->io_ptr; +} +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngread.c b/src/dep/src/irrlicht/libpng/pngread.c new file mode 100644 index 0000000..0d0a7c9 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngread.c @@ -0,0 +1,1473 @@ + +/* pngread.c - read a PNG file + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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 contains routines that an application calls directly to + * read a PNG file or stream. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +/* Create a PNG structure for reading, and allocate any memory needed. */ +png_structp PNGAPI +png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn) +{ + +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); +} + +/* Alternate create PNG structure for reading, and allocate any memory needed. */ +png_structp PNGAPI +png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + + png_structp png_ptr; + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + + int i; + + png_debug(1, "in png_create_read_struct\n"); +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif + if (png_ptr == NULL) + return (NULL); + +#if !defined(PNG_1_0_X) +#ifdef PNG_MMX_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif /* PNG_1_0_X */ + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_ptr->jmpbuf)) +#endif + { + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf=NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, + (png_free_ptr)free_fn, (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + return (NULL); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif + + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + i=0; + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || + (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[80]; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); +#endif +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "Incompatible libpng version in application and library"); + } + } + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: /* Do nothing */ break; + case Z_MEM_ERROR: + case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break; + case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break; + default: png_error(png_ptr, "Unknown zlib error"); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif + return (png_ptr); +} + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Initialize PNG structure for reading, and allocate any memory needed. + This interface is deprecated in favour of the png_create_read_struct(), + and it will disappear as of libpng-1.3.0. */ +#undef png_read_init +void PNGAPI +png_read_init(png_structp png_ptr) +{ + /* We only come here via pre-1.0.7-compiled applications */ + png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); +} + +void PNGAPI +png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size, png_size_t png_info_size) +{ + /* We only come here via pre-1.0.12-compiled applications */ + if(png_ptr == NULL) return; +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + if(png_sizeof(png_struct) > png_struct_size || + png_sizeof(png_info) > png_info_size) + { + char msg[80]; + png_ptr->warning_fn=NULL; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); + } +#endif + if(png_sizeof(png_struct) > png_struct_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The png struct allocated by the application for reading is too small."); + } + if(png_sizeof(png_info) > png_info_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The info struct allocated by application for reading is too small."); + } + png_read_init_3(&png_ptr, user_png_ver, png_struct_size); +} +#endif /* PNG_1_0_X || PNG_1_2_X */ + +void PNGAPI +png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* to save current jump buffer */ +#endif + + int i=0; + + png_structp png_ptr=*ptr_ptr; + + if(png_ptr == NULL) return; + + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + { +#ifdef PNG_LEGACY_SUPPORTED + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; +#else + png_ptr->warning_fn=NULL; + png_warning(png_ptr, + "Application uses deprecated png_read_init() and should be recompiled."); + break; +#endif + } + } while (png_libpng_ver[i++]); + + png_debug(1, "in png_read_init_3\n"); + +#ifdef PNG_SETJMP_SUPPORTED + /* save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + if(png_sizeof(png_struct) > png_struct_size) + { + png_destroy_struct(png_ptr); + *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); + png_ptr = *ptr_ptr; + } + + /* reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof (png_struct)); + +#ifdef PNG_SETJMP_SUPPORTED + /* restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + + switch (inflateInit(&png_ptr->zstream)) + { + case Z_OK: /* Do nothing */ break; + case Z_MEM_ERROR: + case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break; + case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break; + default: png_error(png_ptr, "Unknown zlib error"); + } + + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); +} + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. This has been + * changed in v0.90 to allow reading a file that already has the magic + * bytes read from the stream. You can tell libpng how many bytes have + * been read from the beginning of the stream (up to the maximum of 8) + * via png_set_sig_bytes(), and we will only check the remaining bytes + * here. The application can then have access to the signature bytes we + * read if it is determined that this isn't a valid PNG file. + */ +void PNGAPI +png_read_info(png_structp png_ptr, png_infop info_ptr) +{ + if(png_ptr == NULL) return; + png_debug(1, "in png_read_info\n"); + /* If we haven't checked all of the PNG signature bytes, do so now. */ + if (png_ptr->sig_bytes < 8) + { + png_size_t num_checked = png_ptr->sig_bytes, + num_to_check = 8 - num_checked; + + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); + png_ptr->sig_bytes = 8; + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + if (num_checked < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; + } + + for(;;) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + png_byte chunk_length[4]; + png_uint_32 length; + + png_read_data(png_ptr, chunk_length, 4); + length = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + + png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, + length); + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ + if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + if(png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + png_handle_IEND(png_ptr, info_ptr, length); +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + break; + } + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_handle_PLTE(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + + png_ptr->idat_size = length; + png_ptr->mode |= PNG_HAVE_IDAT; + break; + } +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + png_handle_hIST(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + png_handle_tIME(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + else + png_handle_unknown(png_ptr, info_ptr, length); + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +/* optional call to update the users info_ptr structure */ +void PNGAPI +png_read_update_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_update_info\n"); + if(png_ptr == NULL) return; + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + else + png_warning(png_ptr, + "Ignoring extra png_read_update_info() call; row buffer not reallocated"); + png_read_transform_info(png_ptr, info_ptr); +} + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Initialize palette, background, etc, after transformations + * are set, but before any reading takes place. This allows + * the user to obtain a gamma-corrected palette, for example. + * If the user doesn't call this, we will do it ourselves. + */ +void PNGAPI +png_start_read_image(png_structp png_ptr) +{ + png_debug(1, "in png_start_read_image\n"); + if(png_ptr == NULL) return; + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +void PNGAPI +png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; + const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; + const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; +#endif + int ret; + if(png_ptr == NULL) return; + png_debug2(1, "in png_read_row (row %lu, pass %d)\n", + png_ptr->row_number, png_ptr->pass); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + png_read_start_row(png_ptr); + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* check for transforms that have been set but were defined out */ +#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined."); +#endif +#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined."); +#endif + } + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* if interlaced and we do not need a new row, combine row and return */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + if (dsp_row != NULL && (png_ptr->row_number & 4)) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 3: + if ((png_ptr->row_number & 3) || png_ptr->width < 3) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 4: + if ((png_ptr->row_number & 3) != 2) + { + if (dsp_row != NULL && (png_ptr->row_number & 2)) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 5: + if ((png_ptr->row_number & 1) || png_ptr->width < 2) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); + return; + } + break; + case 6: + if (!(png_ptr->row_number & 1)) + { + png_read_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "Invalid attempt to read row data"); + + png_ptr->zstream.next_out = png_ptr->row_buf; + png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + do + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_byte chunk_length[4]; + + png_crc_finish(png_ptr, 0); + + png_read_data(png_ptr, chunk_length, 4); + png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); + } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, + (png_size_t)png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_error(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression error"); + + } while (png_ptr->zstream.avail_out); + + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->iwidth; + png_ptr->row_info.channels = png_ptr->channels; + png_ptr->row_info.bit_depth = png_ptr->bit_depth; + png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + if(png_ptr->row_buf[0]) + png_read_filter_row(png_ptr, &(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); + + png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, + png_ptr->rowbytes + 1); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +#endif + + + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) + png_do_read_transformations(png_ptr); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* blow up interlaced rows to full size */ + if (png_ptr->interlaced && + (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) +/* old interface (pre-1.0.9): + png_do_read_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + */ + png_do_read_interlace(png_ptr); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, + png_pass_dsp_mask[png_ptr->pass]); + if (row != NULL) + png_combine_row(png_ptr, row, + png_pass_mask[png_ptr->pass]); + } + else +#endif + { + if (row != NULL) + png_combine_row(png_ptr, row, 0xff); + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 0xff); + } + png_read_finish_row(png_ptr); + + if (png_ptr->read_row_fn != NULL) + (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. If the image is interlaced, + * and png_set_interlace_handling() has been called, the rows need to + * contain the contents of the rows from the previous pass. If the + * image has alpha or transparency, and png_handle_alpha()[*] has been + * called, the rows contents must be initialized to the contents of the + * screen. + * + * "row" holds the actual image, and pixels are placed in it + * as they arrive. If the image is displayed after each pass, it will + * appear to "sparkle" in. "display_row" can be used to display a + * "chunky" progressive image, with finer detail added as it becomes + * available. If you do not want this "chunky" display, you may pass + * NULL for display_row. If you do not want the sparkle display, and + * you have not called png_handle_alpha(), you may pass NULL for rows. + * If you have called png_handle_alpha(), and the image has either an + * alpha channel or a transparency chunk, you must provide a buffer for + * rows. In this case, you do not have to provide a display_row buffer + * also, but you may. If the image is not interlaced, or if you have + * not called png_set_interlace_handling(), the display_row buffer will + * be ignored, so pass NULL to it. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ + +void PNGAPI +png_read_rows(png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) +{ + png_uint_32 i; + png_bytepp rp; + png_bytepp dp; + + png_debug(1, "in png_read_rows\n"); + if(png_ptr == NULL) return; + rp = row; + dp = display_row; + if (rp != NULL && dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp++; + png_bytep dptr = *dp++; + + png_read_row(png_ptr, rptr, dptr); + } + else if(rp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp; + png_read_row(png_ptr, rptr, png_bytep_NULL); + rp++; + } + else if(dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep dptr = *dp; + png_read_row(png_ptr, png_bytep_NULL, dptr); + dp++; + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the entire image. If the image has an alpha channel or a tRNS + * chunk, and you have called png_handle_alpha()[*], you will need to + * initialize the image to the current image that PNG will be overlaying. + * We set the num_rows again here, in case it was incorrectly set in + * png_read_start_row() by a call to png_read_update_info() or + * png_start_read_image() if png_set_interlace_handling() wasn't called + * prior to either of these functions like it should have been. You can + * only call this function once. If you desire to have an image for + * each pass of a interlaced image, use png_read_rows() instead. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ +void PNGAPI +png_read_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i,image_height; + int pass, j; + png_bytepp rp; + + png_debug(1, "in png_read_image\n"); + if(png_ptr == NULL) return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + pass = png_set_interlace_handling(png_ptr); +#else + if (png_ptr->interlaced) + png_error(png_ptr, + "Cannot read interlaced image -- interlace handler disabled."); + pass = 1; +#endif + + + image_height=png_ptr->height; + png_ptr->num_rows = image_height; /* Make sure this is set correctly */ + + for (j = 0; j < pass; j++) + { + rp = image; + for (i = 0; i < image_height; i++) + { + png_read_row(png_ptr, *rp, png_bytep_NULL); + rp++; + } + } +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. Will not read past the end of the + * file, will verify the end is accurate, and will read any comments + * or time information at the end of the file, if info is not NULL. + */ +void PNGAPI +png_read_end(png_structp png_ptr, png_infop info_ptr) +{ + png_byte chunk_length[4]; + png_uint_32 length; + + png_debug(1, "in png_read_end\n"); + if(png_ptr == NULL) return; + png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ + + do + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ + + png_read_data(png_ptr, chunk_length, 4); + length = png_get_uint_31(png_ptr,chunk_length); + + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + + png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); + + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + png_handle_IEND(png_ptr, info_ptr, length); +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + { + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_error(png_ptr, "Too many IDAT's found"); + } + png_handle_unknown(png_ptr, info_ptr, length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + { + /* Zero length IDATs are legal after the last IDAT has been + * read, but not after other chunks have been read. + */ + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + png_error(png_ptr, "Too many IDAT's found"); + png_crc_finish(png_ptr, length); + } + else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + png_handle_PLTE(png_ptr, info_ptr, length); +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + png_handle_bKGD(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + png_handle_cHRM(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + png_handle_gAMA(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + png_handle_hIST(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + png_handle_oFFs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + png_handle_pCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + png_handle_pHYs(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + png_handle_sBIT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + png_handle_sRGB(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + png_handle_tEXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + png_handle_tIME(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + png_handle_tRNS(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); +#endif + else + png_handle_unknown(png_ptr, info_ptr, length); + } while (!(png_ptr->mode & PNG_HAVE_IEND)); +} +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ + +/* free all memory used by the read */ +void PNGAPI +png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, + png_infopp end_info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL, end_info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; + png_voidp mem_ptr; +#endif + + png_debug(1, "in png_destroy_read_struct\n"); + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (end_info_ptr_ptr != NULL) + end_info_ptr = *end_info_ptr_ptr; + +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif + + png_read_destroy(png_ptr, info_ptr, end_info_ptr); + + if (info_ptr != NULL) + { +#if defined(PNG_TEXT_SUPPORTED) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (end_info_ptr != NULL) + { +#if defined(PNG_READ_TEXT_SUPPORTED) + png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); +#endif +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)end_info_ptr); +#endif + *end_info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + +/* free all memory used by the read (old method) */ +void /* PRIVATE */ +png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; +#endif + png_error_ptr error_fn; + png_error_ptr warning_fn; + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_read_destroy\n"); + if (info_ptr != NULL) + png_info_destroy(png_ptr, info_ptr); + + if (end_info_ptr != NULL) + png_info_destroy(png_ptr, end_info_ptr); + + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->prev_row); +#if defined(PNG_READ_DITHER_SUPPORTED) + png_free(png_ptr, png_ptr->palette_lookup); + png_free(png_ptr, png_ptr->dither_index); +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_table); +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_from_1); + png_free(png_ptr, png_ptr->gamma_to_1); +#endif +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->free_me &= ~PNG_FREE_PLTE; +#else + if (png_ptr->flags & PNG_FLAG_FREE_PLTE) + png_zfree(png_ptr, png_ptr->palette); + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; +#endif +#if defined(PNG_tRNS_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans); + png_ptr->free_me &= ~PNG_FREE_TRNS; +#else + if (png_ptr->flags & PNG_FLAG_FREE_TRNS) + png_free(png_ptr, png_ptr->trans); + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; +#endif +#endif +#if defined(PNG_READ_hIST_SUPPORTED) +#ifdef PNG_FREE_ME_SUPPORTED + if (png_ptr->free_me & PNG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->free_me &= ~PNG_FREE_HIST; +#else + if (png_ptr->flags & PNG_FLAG_FREE_HIST) + png_free(png_ptr, png_ptr->hist); + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; +#endif +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->gamma_16_table != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_table[i]); + } + png_free(png_ptr, png_ptr->gamma_16_table); + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_from_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_from_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_from_1); + } + if (png_ptr->gamma_16_to_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_to_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_to_1); + } +#endif +#endif +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_free(png_ptr, png_ptr->time_buffer); +#endif + + inflateEnd(&png_ptr->zstream); +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +#ifdef PNG_TEXT_SUPPORTED + png_free(png_ptr, png_ptr->current_text); +#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + + /* Save the important info out of the png_struct, in case it is + * being used again. + */ +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; + warning_fn = png_ptr->warning_fn; + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + png_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + +} + +void PNGAPI +png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) +{ + if(png_ptr == NULL) return; + png_ptr->read_row_fn = read_row_fn; +} + + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_read_png(png_structp png_ptr, png_infop info_ptr, + int transforms, + voidp params) +{ + int row; + + if(png_ptr == NULL) return; +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel from opacity to transparency + */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + + /* png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); + if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) + png_error(png_ptr,"Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + /* tell libpng to strip 16 bit/color files down to 8 bits per color + */ + if (transforms & PNG_TRANSFORM_STRIP_16) + png_set_strip_16(png_ptr); +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ + if (transforms & PNG_TRANSFORM_STRIP_ALPHA) + png_set_strip_alpha(png_ptr); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) + /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + /* Expand paletted colors into true RGB triplets + * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel + * Expand paletted or RGB images with transparency to full alpha + * channels so the data will be available as RGBA quartets. + */ + if (transforms & PNG_TRANSFORM_EXPAND) + if ((png_ptr->bit_depth < 8) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) + png_set_expand(png_ptr); +#endif + + /* We don't handle background color or gamma transformation or dithering. + */ + +#if defined(PNG_READ_INVERT_SUPPORTED) + /* invert monochrome files to have 0 as white and 1 as black + */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) + { + png_color_8p sig_bit; + + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, sig_bit); + } +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) + /* flip the RGB pixels to BGR (or RGBA to BGRA) + */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) + /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) + */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) + /* swap bytes of 16 bit files to least significant byte first + */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + + /* We don't handle adding filler bytes */ + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (i.e., you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* -------------- image transformations end here ------------------- */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); +#endif + if(info_ptr->row_pointers == NULL) + { + info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, + info_ptr->height * png_sizeof(png_bytep)); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_ROWS; +#endif + for (row = 0; row < (int)info_ptr->height; row++) + { + info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr)); + } + } + + png_read_image(png_ptr, info_ptr->row_pointers); + info_ptr->valid |= PNG_INFO_IDAT; + + /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + if(transforms == 0 || params == NULL) + /* quiet compiler warnings */ return; + +} +#endif /* PNG_INFO_IMAGE_SUPPORTED */ +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngrio.c b/src/dep/src/irrlicht/libpng/pngrio.c new file mode 100644 index 0000000..2275683 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngrio.c @@ -0,0 +1,167 @@ + +/* 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 */ diff --git a/src/dep/src/irrlicht/libpng/pngrtran.c b/src/dep/src/irrlicht/libpng/pngrtran.c new file mode 100644 index 0000000..87de5b5 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngrtran.c @@ -0,0 +1,4247 @@ + +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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 contains functions optionally called by an application + * in order to tell libpng how to handle data when reading a PNG. + * Transformations that are used in both reading and writing are + * in pngtrans.c. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +/* Set the action on getting a CRC error for an ancillary or critical chunk. */ +void PNGAPI +png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) +{ + png_debug(1, "in png_set_crc_action\n"); + /* Tell libpng how we react to CRC errors in critical chunks */ + if(png_ptr == NULL) return; + switch (crit_action) + { + case PNG_CRC_NO_CHANGE: /* leave setting as is */ + break; + case PNG_CRC_WARN_USE: /* warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; + break; + case PNG_CRC_QUIET_USE: /* quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | + PNG_FLAG_CRC_CRITICAL_IGNORE; + break; + case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */ + png_warning(png_ptr, "Can't discard critical data on CRC error."); + case PNG_CRC_ERROR_QUIT: /* error/quit */ + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + break; + } + + switch (ancil_action) + { + case PNG_CRC_NO_CHANGE: /* leave setting as is */ + break; + case PNG_CRC_WARN_USE: /* warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; + break; + case PNG_CRC_QUIET_USE: /* quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | + PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + case PNG_CRC_ERROR_QUIT: /* error/quit */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + case PNG_CRC_WARN_DISCARD: /* warn/discard data */ + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + break; + } +} + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* handle alpha and tRNS via a background color */ +void PNGAPI +png_set_background(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_debug(1, "in png_set_background\n"); + if(png_ptr == NULL) return; + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + { + png_warning(png_ptr, "Application must supply a known background gamma"); + return; + } + + png_ptr->transformations |= PNG_BACKGROUND; + png_memcpy(&(png_ptr->background), background_color, + png_sizeof(png_color_16)); + png_ptr->background_gamma = (float)background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); +} +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip 16 bit depth files to 8 bit depth */ +void PNGAPI +png_set_strip_16(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_16\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +void PNGAPI +png_set_strip_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha\n"); + if(png_ptr == NULL) return; + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; +} +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Dither file to 8 bit. Supply a palette, the current number + * of elements in the palette, the maximum number of elements + * allowed, and a histogram if possible. If the current number + * of colors is greater then the maximum number, the palette will be + * modified to fit in the maximum number. "full_dither" indicates + * whether we need a dithering cube set up for RGB images, or if we + * simply are reducing the number of colors in a paletted image. + */ + +typedef struct png_dsort_struct +{ + struct png_dsort_struct FAR * next; + png_byte left; + png_byte right; +} png_dsort; +typedef png_dsort FAR * png_dsortp; +typedef png_dsort FAR * FAR * png_dsortpp; + +void PNGAPI +png_set_dither(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_uint_16p histogram, + int full_dither) +{ + png_debug(1, "in png_set_dither\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_DITHER; + + if (!full_dither) + { + int i; + + png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + for (i = 0; i < num_palette; i++) + png_ptr->dither_index[i] = (png_byte)i; + } + + if (num_palette > maximum_colors) + { + if (histogram != NULL) + { + /* This is easy enough, just throw out the least used colors. + Perhaps not the best solution, but good enough. */ + + int i; + + /* initialize an array to sort colors */ + png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + + /* initialize the dither_sort array */ + for (i = 0; i < num_palette; i++) + png_ptr->dither_sort[i] = (png_byte)i; + + /* Find the least used palette entries by starting a + bubble sort, and running it until we have sorted + out enough colors. Note that we don't care about + sorting all the colors, just finding which are + least used. */ + + for (i = num_palette - 1; i >= maximum_colors; i--) + { + int done; /* to stop early if the list is pre-sorted */ + int j; + + done = 1; + for (j = 0; j < i; j++) + { + if (histogram[png_ptr->dither_sort[j]] + < histogram[png_ptr->dither_sort[j + 1]]) + { + png_byte t; + + t = png_ptr->dither_sort[j]; + png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; + png_ptr->dither_sort[j + 1] = t; + done = 0; + } + } + if (done) + break; + } + + /* swap the palette around, and set up a table, if necessary */ + if (full_dither) + { + int j = num_palette; + + /* put all the useful colors within the max, but don't + move the others */ + for (i = 0; i < maximum_colors; i++) + { + if ((int)png_ptr->dither_sort[i] >= maximum_colors) + { + do + j--; + while ((int)png_ptr->dither_sort[j] >= maximum_colors); + palette[i] = palette[j]; + } + } + } + else + { + int j = num_palette; + + /* move all the used colors inside the max limit, and + develop a translation table */ + for (i = 0; i < maximum_colors; i++) + { + /* only move the colors we need to */ + if ((int)png_ptr->dither_sort[i] >= maximum_colors) + { + png_color tmp_color; + + do + j--; + while ((int)png_ptr->dither_sort[j] >= maximum_colors); + + tmp_color = palette[j]; + palette[j] = palette[i]; + palette[i] = tmp_color; + /* indicate where the color went */ + png_ptr->dither_index[j] = (png_byte)i; + png_ptr->dither_index[i] = (png_byte)j; + } + } + + /* find closest color for those colors we are not using */ + for (i = 0; i < num_palette; i++) + { + if ((int)png_ptr->dither_index[i] >= maximum_colors) + { + int min_d, k, min_k, d_index; + + /* find the closest color to one we threw out */ + d_index = png_ptr->dither_index[i]; + min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); + for (k = 1, min_k = 0; k < maximum_colors; k++) + { + int d; + + d = PNG_COLOR_DIST(palette[d_index], palette[k]); + + if (d < min_d) + { + min_d = d; + min_k = k; + } + } + /* point to closest color */ + png_ptr->dither_index[i] = (png_byte)min_k; + } + } + } + png_free(png_ptr, png_ptr->dither_sort); + png_ptr->dither_sort=NULL; + } + else + { + /* This is much harder to do simply (and quickly). Perhaps + we need to go through a median cut routine, but those + don't always behave themselves with only a few colors + as input. So we will just find the closest two colors, + and throw out one of them (chosen somewhat randomly). + [We don't understand this at all, so if someone wants to + work on improving it, be our guest - AED, GRP] + */ + int i; + int max_d; + int num_new_palette; + png_dsortp t; + png_dsortpp hash; + + t=NULL; + + /* initialize palette index arrays */ + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * png_sizeof (png_byte))); + + /* initialize the sort array */ + for (i = 0; i < num_palette; i++) + { + png_ptr->index_to_palette[i] = (png_byte)i; + png_ptr->palette_to_index[i] = (png_byte)i; + } + + hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * + png_sizeof (png_dsortp))); + for (i = 0; i < 769; i++) + hash[i] = NULL; +/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */ + + num_new_palette = num_palette; + + /* initial wild guess at how far apart the farthest pixel + pair we will be eliminating will be. Larger + numbers mean more areas will be allocated, Smaller + numbers run the risk of not saving enough data, and + having to do this all over again. + + I have not done extensive checking on this number. + */ + max_d = 96; + + while (num_new_palette > maximum_colors) + { + for (i = 0; i < num_new_palette - 1; i++) + { + int j; + + for (j = i + 1; j < num_new_palette; j++) + { + int d; + + d = PNG_COLOR_DIST(palette[i], palette[j]); + + if (d <= max_d) + { + + t = (png_dsortp)png_malloc_warn(png_ptr, + (png_uint_32)(png_sizeof(png_dsort))); + if (t == NULL) + break; + t->next = hash[d]; + t->left = (png_byte)i; + t->right = (png_byte)j; + hash[d] = t; + } + } + if (t == NULL) + break; + } + + if (t != NULL) + for (i = 0; i <= max_d; i++) + { + if (hash[i] != NULL) + { + png_dsortp p; + + for (p = hash[i]; p; p = p->next) + { + if ((int)png_ptr->index_to_palette[p->left] + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) + { + int j, next_j; + + if (num_new_palette & 0x01) + { + j = p->left; + next_j = p->right; + } + else + { + j = p->right; + next_j = p->left; + } + + num_new_palette--; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; + if (!full_dither) + { + int k; + + for (k = 0; k < num_palette; k++) + { + if (png_ptr->dither_index[k] == + png_ptr->index_to_palette[j]) + png_ptr->dither_index[k] = + png_ptr->index_to_palette[next_j]; + if ((int)png_ptr->dither_index[k] == + num_new_palette) + png_ptr->dither_index[k] = + png_ptr->index_to_palette[j]; + } + } + + png_ptr->index_to_palette[png_ptr->palette_to_index + [num_new_palette]] = png_ptr->index_to_palette[j]; + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] + = png_ptr->palette_to_index[num_new_palette]; + + png_ptr->index_to_palette[j] = (png_byte)num_new_palette; + png_ptr->palette_to_index[num_new_palette] = (png_byte)j; + } + if (num_new_palette <= maximum_colors) + break; + } + if (num_new_palette <= maximum_colors) + break; + } + } + + for (i = 0; i < 769; i++) + { + if (hash[i] != NULL) + { + png_dsortp p = hash[i]; + while (p) + { + t = p->next; + png_free(png_ptr, p); + p = t; + } + } + hash[i] = 0; + } + max_d += 96; + } + png_free(png_ptr, hash); + png_free(png_ptr, png_ptr->palette_to_index); + png_free(png_ptr, png_ptr->index_to_palette); + png_ptr->palette_to_index=NULL; + png_ptr->index_to_palette=NULL; + } + num_palette = maximum_colors; + } + if (png_ptr->palette == NULL) + { + png_ptr->palette = palette; + } + png_ptr->num_palette = (png_uint_16)num_palette; + + if (full_dither) + { + int i; + png_bytep distance; + int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + + PNG_DITHER_BLUE_BITS; + int num_red = (1 << PNG_DITHER_RED_BITS); + int num_green = (1 << PNG_DITHER_GREEN_BITS); + int num_blue = (1 << PNG_DITHER_BLUE_BITS); + png_size_t num_entries = ((png_size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, + (png_uint_32)(num_entries * png_sizeof (png_byte))); + + png_memset(png_ptr->palette_lookup, 0, num_entries * + png_sizeof (png_byte)); + + distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + png_sizeof(png_byte))); + + png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); + + for (i = 0; i < num_palette; i++) + { + int ir, ig, ib; + int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); + int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); + int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); + + for (ir = 0; ir < num_red; ir++) + { + /* int dr = abs(ir - r); */ + int dr = ((ir > r) ? ir - r : r - ir); + int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS)); + + for (ig = 0; ig < num_green; ig++) + { + /* int dg = abs(ig - g); */ + int dg = ((ig > g) ? ig - g : g - ig); + int dt = dr + dg; + int dm = ((dr > dg) ? dr : dg); + int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); + + for (ib = 0; ib < num_blue; ib++) + { + int d_index = index_g | ib; + /* int db = abs(ib - b); */ + int db = ((ib > b) ? ib - b : b - ib); + int dmax = ((dm > db) ? dm : db); + int d = dmax + dt + db; + + if (d < (int)distance[d_index]) + { + distance[d_index] = (png_byte)d; + png_ptr->palette_lookup[d_index] = (png_byte)i; + } + } + } + } + } + + png_free(png_ptr, distance); + } +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +/* Transform the image from the file_gamma to the screen_gamma. We + * only do transformations on images where the file_gamma and screen_gamma + * are not close reciprocals, otherwise it slows things down slightly, and + * also needlessly introduces small errors. + * + * We will turn off gamma transformation later if no semitransparent entries + * are present in the tRNS array for palette images. We can't do it here + * because we don't necessarily have the tRNS chunk yet. + */ +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_debug(1, "in png_set_gamma\n"); + if(png_ptr == NULL) return; + if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + png_ptr->transformations |= PNG_GAMMA; + png_ptr->gamma = (float)file_gamma; + png_ptr->screen_gamma = (float)scrn_gamma; +} +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand paletted images to RGB, expand grayscale images of + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks + * to alpha channels. + */ +void PNGAPI +png_set_expand(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* GRR 19990627: the following three functions currently are identical + * to png_set_expand(). However, it is entirely reasonable that someone + * might wish to expand an indexed image to RGB but *not* expand a single, + * fully transparent palette entry to a full alpha channel--perhaps instead + * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace + * the transparent color with a particular RGB value, or drop tRNS entirely. + * IOW, a future version of the library may make the transformations flag + * a bit more fine-grained, with separate bits for each of these three + * functions. + * + * More to the point, these functions make it obvious what libpng will be + * doing, whereas "expand" can (and does) mean any number of things. + * + * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha. + */ + +/* Expand paletted images to RGB. */ +void PNGAPI +png_set_palette_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_palette_to_rgb\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +#if !defined(PNG_1_0_X) +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_EXPAND; +} +#endif + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +/* Deprecated as of libpng-1.2.9 */ +void PNGAPI +png_set_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_gray_1_2_4_to_8\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif + + +/* Expand tRNS chunks to alpha channels. */ +void PNGAPI +png_set_tRNS_to_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand\n"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +void PNGAPI +png_set_gray_to_rgb(png_structp png_ptr) +{ + png_debug(1, "in png_set_gray_to_rgb\n"); + png_ptr->transformations |= PNG_GRAY_TO_RGB; +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) +/* Convert a RGB image to a grayscale of the same width. This allows us, + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. + */ + +void PNGAPI +png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, + double green) +{ + int red_fixed = (int)((float)red*100000.0 + 0.5); + int green_fixed = (int)((float)green*100000.0 + 0.5); + if(png_ptr == NULL) return; + png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); +} +#endif + +void PNGAPI +png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) +{ + png_debug(1, "in png_set_rgb_to_gray\n"); + if(png_ptr == NULL) return; + switch(error_action) + { + case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#if defined(PNG_READ_EXPAND_SUPPORTED) + png_ptr->transformations |= PNG_EXPAND; +#else + { + png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); + png_ptr->transformations &= ~PNG_RGB_TO_GRAY; + } +#endif + { + png_uint_16 red_int, green_int; + if(red < 0 || green < 0) + { + red_int = 6968; /* .212671 * 32768 + .5 */ + green_int = 23434; /* .715160 * 32768 + .5 */ + } + else if(red + green < 100000L) + { + red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); + green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); + } + else + { + png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); + red_int = 6968; + green_int = 23434; + } + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; + png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int); + } +} +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +void PNGAPI +png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + read_user_transform_fn) +{ + png_debug(1, "in png_set_read_user_transform_fn\n"); + if(png_ptr == NULL) return; +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +#endif +#ifdef PNG_LEGACY_SUPPORTED + if(read_user_transform_fn) + png_warning(png_ptr, + "This version of libpng does not support user transforms"); +#endif +} +#endif + +/* Initialize everything needed for the read. This includes modifying + * the palette. + */ +void /* PRIVATE */ +png_init_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_init_read_transformations\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if(png_ptr != NULL) +#endif + { +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ + || defined(PNG_READ_GAMMA_SUPPORTED) + int color_type = png_ptr->color_type; +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* Detect gray background and attempt to enable optimization + * for gray --> RGB case */ + /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or + * RGB_ALPHA (in which case need_expand is superfluous anyway), the + * background color might actually be gray yet not be flagged as such. + * This is not a problem for the current code, which uses + * PNG_BACKGROUND_IS_GRAY only to decide when to do the + * png_do_gray_to_rgb() transformation. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + !(color_type & PNG_COLOR_MASK_COLOR)) + { + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } else if ((png_ptr->transformations & PNG_BACKGROUND) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_GRAY_TO_RGB) && + png_ptr->background.red == png_ptr->background.green && + png_ptr->background.red == png_ptr->background.blue) + { + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; + } +#endif + + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_EXPAND)) + { + if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ + { + /* expand background and tRNS chunks */ + switch (png_ptr->bit_depth) + { + case 1: + png_ptr->background.gray *= (png_uint_16)0xff; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0xff; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 2: + png_ptr->background.gray *= (png_uint_16)0x55; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x55; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 4: + png_ptr->background.gray *= (png_uint_16)0x11; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x11; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } + break; + case 8: + case 16: + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + break; + } + } + else if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_ptr->background.red = + png_ptr->palette[png_ptr->background.index].red; + png_ptr->background.green = + png_ptr->palette[png_ptr->background.index].green; + png_ptr->background.blue = + png_ptr->palette[png_ptr->background.index].blue; + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + { +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) +#endif + { + /* invert the alpha channel (in tRNS) unless the pixels are + going to be expanded, in which case leave it for later */ + int i,istop; + istop=(int)png_ptr->num_trans; + for (i=0; itrans[i] = (png_byte)(255 - png_ptr->trans[i]); + } + } +#endif + + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) + png_ptr->background_1 = png_ptr->background; +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + + if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) + && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) + < PNG_GAMMA_THRESHOLD)) + { + int i,k; + k=0; + for (i=0; inum_trans; i++) + { + if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) + k=1; /* partial transparency is present */ + } + if (k == 0) + png_ptr->transformations &= (~PNG_GAMMA); + } + + if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && + png_ptr->gamma != 0.0) + { + png_build_gamma_table(png_ptr); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + /* could skip if no transparency and + */ + png_color back, back_1; + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + double g, gs; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = 1.0; + break; + case PNG_BACKGROUND_GAMMA_FILE: + g = 1.0 / (png_ptr->gamma); + gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + break; + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = 1.0 / (png_ptr->background_gamma); + gs = 1.0 / (png_ptr->background_gamma * + png_ptr->screen_gamma); + break; + default: + g = 1.0; /* back_1 */ + gs = 1.0; /* back */ + } + + if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) + { + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + } + else + { + back.red = (png_byte)(pow( + (double)png_ptr->background.red/255, gs) * 255.0 + .5); + back.green = (png_byte)(pow( + (double)png_ptr->background.green/255, gs) * 255.0 + .5); + back.blue = (png_byte)(pow( + (double)png_ptr->background.blue/255, gs) * 255.0 + .5); + } + + back_1.red = (png_byte)(pow( + (double)png_ptr->background.red/255, g) * 255.0 + .5); + back_1.green = (png_byte)(pow( + (double)png_ptr->background.green/255, g) * 255.0 + .5); + back_1.blue = (png_byte)(pow( + (double)png_ptr->background.blue/255, g) * 255.0 + .5); + } + for (i = 0; i < num_palette; i++) + { + if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) + { + if (png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else /* if (png_ptr->trans[i] != 0xff) */ + { + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, png_ptr->trans[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite(w, v, png_ptr->trans[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite(w, v, png_ptr->trans[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else + /* color_type != PNG_COLOR_TYPE_PALETTE */ + { + double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); + double g = 1.0; + double gs = 1.0; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = 1.0; + break; + case PNG_BACKGROUND_GAMMA_FILE: + g = 1.0 / (png_ptr->gamma); + gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + break; + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = 1.0 / (png_ptr->background_gamma); + gs = 1.0 / (png_ptr->background_gamma * + png_ptr->screen_gamma); + break; + } + + png_ptr->background_1.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, g) * m + .5); + png_ptr->background.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, gs) * m + .5); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) + { + /* RGB or RGBA with color background */ + png_ptr->background_1.red = (png_uint_16)(pow( + (double)png_ptr->background.red / m, g) * m + .5); + png_ptr->background_1.green = (png_uint_16)(pow( + (double)png_ptr->background.green / m, g) * m + .5); + png_ptr->background_1.blue = (png_uint_16)(pow( + (double)png_ptr->background.blue / m, g) * m + .5); + png_ptr->background.red = (png_uint_16)(pow( + (double)png_ptr->background.red / m, gs) * m + .5); + png_ptr->background.green = (png_uint_16)(pow( + (double)png_ptr->background.green / m, gs) * m + .5); + png_ptr->background.blue = (png_uint_16)(pow( + (double)png_ptr->background.blue / m, gs) * m + .5); + } + else + { + /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ + png_ptr->background_1.red = png_ptr->background_1.green + = png_ptr->background_1.blue = png_ptr->background_1.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + } + } + } + else + /* transformation does not include PNG_BACKGROUND */ +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + else +#endif +#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + /* No GAMMA transformation */ + if ((png_ptr->transformations & PNG_BACKGROUND) && + (color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = (int)png_ptr->num_trans; + png_color back; + png_colorp palette = png_ptr->palette; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < istop; i++) + { + if (png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else if (png_ptr->trans[i] != 0xff) + { + /* The png_composite() macro is defined in png.h */ + png_composite(palette[i].red, palette[i].red, + png_ptr->trans[i], back.red); + png_composite(palette[i].green, palette[i].green, + png_ptr->trans[i], back.green); + png_composite(palette[i].blue, palette[i].blue, + png_ptr->trans[i], back.blue); + } + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED */ + +#if defined(PNG_READ_SHIFT_SUPPORTED) + if ((png_ptr->transformations & PNG_SHIFT) && + (color_type == PNG_COLOR_TYPE_PALETTE)) + { + png_uint_16 i; + png_uint_16 istop = png_ptr->num_palette; + int sr = 8 - png_ptr->sig_bit.red; + int sg = 8 - png_ptr->sig_bit.green; + int sb = 8 - png_ptr->sig_bit.blue; + + if (sr < 0 || sr > 8) + sr = 0; + if (sg < 0 || sg > 8) + sg = 0; + if (sb < 0 || sb > 8) + sb = 0; + for (i = 0; i < istop; i++) + { + png_ptr->palette[i].red >>= sr; + png_ptr->palette[i].green >>= sg; + png_ptr->palette[i].blue >>= sb; + } + } +#endif /* PNG_READ_SHIFT_SUPPORTED */ + } +#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ + && !defined(PNG_READ_BACKGROUND_SUPPORTED) + if(png_ptr) + return; +#endif +} + +/* Modify the info structure to reflect the transformations. The + * info should be updated so a PNG file could be written with it, + * assuming the transformations result in valid PNG data. + */ +void /* PRIVATE */ +png_read_transform_info(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_read_transform_info\n"); +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + info_ptr->color_type = PNG_COLOR_TYPE_RGB; + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + else + { + if (png_ptr->num_trans) + { + if (png_ptr->transformations & PNG_EXPAND_tRNS) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + else + info_ptr->color_type |= PNG_COLOR_MASK_COLOR; + } + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->num_trans = 0; + info_ptr->background = png_ptr->background; + } +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->transformations & PNG_GAMMA) + { +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->gamma = png_ptr->gamma; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = png_ptr->int_gamma; +#endif + } +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) + info_ptr->bit_depth = 8; +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + info_ptr->color_type |= PNG_COLOR_MASK_COLOR; +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + if (png_ptr->transformations & PNG_DITHER) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } + } +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) + info_ptr->bit_depth = 8; +#endif + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + else + info_ptr->channels = 1; + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) + info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; +#endif + + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + +#if defined(PNG_READ_FILLER_SUPPORTED) + /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ + if ((png_ptr->transformations & PNG_FILLER) && + ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) + { + info_ptr->channels++; + /* if adding a true alpha channel not just filler */ +#if !defined(PNG_1_0_X) + if (png_ptr->transformations & PNG_ADD_ALPHA) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; +#endif + } +#endif + +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ +defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if(png_ptr->transformations & PNG_USER_TRANSFORM) + { + if(info_ptr->bit_depth < png_ptr->user_transform_depth) + info_ptr->bit_depth = png_ptr->user_transform_depth; + if(info_ptr->channels < png_ptr->user_transform_channels) + info_ptr->channels = png_ptr->user_transform_channels; + } +#endif + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * + info_ptr->bit_depth); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width); + +#if !defined(PNG_READ_EXPAND_SUPPORTED) + if(png_ptr) + return; +#endif +} + +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ +void /* PRIVATE */ +png_do_read_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_do_read_transformations\n"); +#if !defined(PNG_USELESS_TESTS_SUPPORTED) + if (png_ptr->row_buf == NULL) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[50]; + + sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number, + png_ptr->pass); + png_error(png_ptr, msg); +#else + png_error(png_ptr, "NULL row buffer"); +#endif + } +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) + { + png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans, png_ptr->num_trans); + } + else + { + if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) + png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->trans_values)); + else + png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + NULL); + } + } +#endif + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) + if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) + png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); + if(rgb_error) + { + png_ptr->rgb_to_gray_status=1; + if(png_ptr->transformations & PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + if(png_ptr->transformations & PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + } + } +#endif + +/* +From Andreas Dilger e-mail to png-implement, 26 March 1998: + + In most cases, the "simple transparency" should be done prior to doing + gray-to-RGB, or you will have to test 3x as many bytes to check if a + pixel is transparent. You would also need to make sure that the + transparency information is upgraded to RGB. + + To summarize, the current flow is: + - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + with background "in place" if transparent, + convert to RGB if necessary + - Gray + alpha -> composite with gray background and remove alpha bytes, + convert to RGB if necessary + + To support RGB backgrounds for gray images we need: + - Gray + simple transparency -> convert to RGB + simple transparency, compare + 3 or 6 bytes and composite with background + "in place" if transparent (3x compare/pixel + compared to doing composite with gray bkgrnd) + - Gray + alpha -> convert to RGB + alpha, composite with background and + remove alpha bytes (3x float operations/pixel + compared with composite on gray background) + + Greg's change will do this. The reason it wasn't done before is for + performance, as this increases the per-pixel operations. If we would check + in advance if the background was gray or RGB, and position the gray-to-RGB + transform appropriately, then it would save a lot of work/time. + */ + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* if gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if ((png_ptr->transformations & PNG_BACKGROUND) && + ((png_ptr->num_trans != 0 ) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) + png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->trans_values), &(png_ptr->background) +#if defined(PNG_READ_GAMMA_SUPPORTED) + , &(png_ptr->background_1), + png_ptr->gamma_table, png_ptr->gamma_from_1, + png_ptr->gamma_to_1, png_ptr->gamma_16_table, + png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, + png_ptr->gamma_shift +#endif +); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) + if ((png_ptr->transformations & PNG_GAMMA) && +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + !((png_ptr->transformations & PNG_BACKGROUND) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && +#endif + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->gamma_table, png_ptr->gamma_16_table, + png_ptr->gamma_shift); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + if (png_ptr->transformations & PNG_DITHER) + { + png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->dither_index); + if(png_ptr->row_info.rowbytes == (png_uint_32)0) + png_error(png_ptr, "png_do_dither returned rowbytes=0"); + } +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* if gray -> RGB, do so now only if we did not do so above */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + { + if(png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* user read transform function */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_uint_32 rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if(png_ptr->user_transform_depth) + png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; + if(png_ptr->user_transform_channels) + png_ptr->row_info.channels = png_ptr->user_transform_channels; +#endif + png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * + png_ptr->row_info.channels); + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + } +#endif + +} + +#if defined(PNG_READ_PACK_SUPPORTED) +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with + * a bit depth of 1, you would end up with bytes that only contained + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. + */ +void /* PRIVATE */ +png_do_unpack(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_unpack\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && row_info->bit_depth < 8) +#else + if (row_info->bit_depth < 8) +#endif + { + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + switch (row_info->bit_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x01); + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + + png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x03); + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x0f); + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift = 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_width * row_info->channels; + } +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +/* Reverse the effects of png_do_shift. This routine merely shifts the + * pixels back to their significant bits values. Thus, if you have + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +void /* PRIVATE */ +png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) +{ + png_debug(1, "in png_do_unshift\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && sig_bits != NULL && +#endif + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; + int c; + png_uint_16 value = 0; + png_uint_32 row_width = row_info->width; + + if (row_info->color_type & PNG_COLOR_MASK_COLOR) + { + shift[channels++] = row_info->bit_depth - sig_bits->red; + shift[channels++] = row_info->bit_depth - sig_bits->green; + shift[channels++] = row_info->bit_depth - sig_bits->blue; + } + else + { + shift[channels++] = row_info->bit_depth - sig_bits->gray; + } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + shift[channels++] = row_info->bit_depth - sig_bits->alpha; + } + + for (c = 0; c < channels; c++) + { + if (shift[c] <= 0) + shift[c] = 0; + else + value = 1; + } + + if (!value) + return; + + switch (row_info->bit_depth) + { + case 2: + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (bp = row, i = 0; i < istop; i++) + { + *bp >>= 1; + *bp++ &= 0x55; + } + break; + } + case 4: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | + (png_byte)((int)0xf >> shift[0])); + + for (i = 0; i < istop; i++) + { + *bp >>= shift[0]; + *bp++ &= mask; + } + break; + } + case 8: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = row_width * channels; + + for (i = 0; i < istop; i++) + { + *bp++ >>= shift[i%channels]; + } + break; + } + case 16: + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_width; + + for (i = 0; i < istop; i++) + { + value = (png_uint_16)((*bp << 8) + *(bp + 1)); + value >>= shift[i%channels]; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + break; + } + } + } +} +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* chop rows of bit depth 16 down to 8 */ +void /* PRIVATE */ +png_do_chop(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_chop\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && row_info->bit_depth == 16) +#else + if (row_info->bit_depth == 16) +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + png_uint_32 istop = row_info->width * row_info->channels; + + for (i = 0; i> 8)) >> 8; + * + * Approximate calculation with shift/add instead of multiply/divide: + * *dp = ((((png_uint_32)(*sp) << 8) | + * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; + * + * What we actually do to avoid extra shifting and conversion: + */ + + *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); +#else + /* Simply discard the low order byte */ + *dp = *sp; +#endif + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_info->width * row_info->channels; + } +} +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_swap_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from RGBA to ARGB */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + /* This converts from RRGGBBAA to AARRGGBB */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from GA to AG */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + /* This converts from GGAA to AAGG */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } + } + } +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_invert_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This inverts the alpha channel in RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=3; + dp=sp; + } + } + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=6; + dp=sp; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This inverts the alpha channel in GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = *(--sp); + } + } + /* This inverts the alpha channel in GGAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); +/* + *(--dp) = *(--sp); + *(--dp) = *(--sp); +*/ + sp-=2; + dp=sp; + } + } + } + } +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) +/* Add filler channel if we have RGB color */ +void /* PRIVATE */ +png_do_read_filler(png_row_infop row_info, png_bytep row, + png_uint_32 filler, png_uint_32 flags) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_byte hi_filler = (png_byte)((filler>>8) & 0xff); + png_byte lo_filler = (png_byte)(filler & 0xff); + + png_debug(1, "in png_do_read_filler\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if(row_info->bit_depth == 8) + { + /* This changes the data from G to GX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + /* This changes the data from G to XG */ + else + { + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + } + else if(row_info->bit_depth == 16) + { + /* This changes the data from GG to GGXX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + /* This changes the data from GG to XXGG */ + else + { + png_bytep sp = row + (png_size_t)row_width * 2; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } + } /* COLOR_TYPE == GRAY */ + else if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if(row_info->bit_depth == 8) + { + /* This changes the data from RGB to RGBX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + /* This changes the data from RGB to XRGB */ + else + { + png_bytep sp = row + (png_size_t)row_width * 3; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + } + } + else if(row_info->bit_depth == 16) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = hi_filler; + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = hi_filler; + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + /* This changes the data from RRGGBB to XXRRGGBB */ + else + { + png_bytep sp = row + (png_size_t)row_width * 6; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = hi_filler; + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = row_width * 8; + } + } + } /* COLOR_TYPE == RGB */ +} +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* expand grayscale files to RGB, with or without alpha */ +void /* PRIVATE */ +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_gray_to_rgb\n"); + if (row_info->bit_depth >= 8 && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + png_bytep sp = row + (png_size_t)row_width - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + else + { + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + png_bytep sp = row + (png_size_t)row_width * 2 - 1; + png_bytep dp = sp + (png_size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + else + { + png_bytep sp = row + (png_size_t)row_width * 4 - 1; + png_bytep dp = sp + (png_size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + row_info->channels += (png_byte)2; + row_info->color_type |= PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } +} +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* reduce RGB files to grayscale, with or without alpha + * using the equation given in Poynton's ColorFAQ at + * + * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * + * We approximate this with + * + * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B + * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * + * The calculation is to be done in a linear colorspace. + * + * Other integer coefficents can be used via png_set_rgb_to_gray(). + */ +int /* PRIVATE */ +png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) + +{ + png_uint_32 i; + + png_uint_32 row_width = row_info->width; + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + + for (i = 0; i < row_width; i++) + { + png_byte red = png_ptr->gamma_to_1[*(sp++)]; + png_byte green = png_ptr->gamma_to_1[*(sp++)]; + png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if(red != green || red != blue) + { + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red+gc*green+bc*blue)>>15]; + } + else + *(dp++) = *(sp-1); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + if(red != green || red != blue) + { + rgb_error |= 1; + *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15); + } + else + *(dp++) = *(sp-1); + } + } + } + + else /* RGB bit_depth == 16 */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_to_1 != NULL && + png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red == green && red == blue) + w = red; + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> + png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> + png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + + bc*blue_1)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red != green || red != blue) + rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + } + } + } + } + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = png_ptr->gamma_to_1[*(sp++)]; + png_byte green = png_ptr->gamma_to_1[*(sp++)]; + png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if(red != green || red != blue) + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1 + [(rc*red + gc*green + bc*blue)>>15]; + *(dp++) = *(sp++); /* alpha */ + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + if(red != green || red != blue) + rgb_error |= 1; + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = *(sp++); /* alpha */ + } + } + } + else /* RGBA bit_depth == 16 */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->gamma_16_to_1 != NULL && + png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + + if(red == green && red == blue) + w = red; + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> + png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> + png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc * red_1 + + gc * green_1 + bc * blue_1)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + if(red != green || red != blue) + rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); + } + } + } + } + row_info->channels -= (png_byte)2; + row_info->color_type &= ~PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + return rgb_error; +} +#endif + +/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth + * large of png_color. This lets grayscale images be treated as + * paletted. Most useful for gamma correction and simplification + * of code. + */ +void PNGAPI +png_build_grayscale_palette(int bit_depth, png_colorp palette) +{ + int num_palette; + int color_inc; + int i; + int v; + + png_debug(1, "in png_do_build_grayscale_palette\n"); + if (palette == NULL) + return; + + switch (bit_depth) + { + case 1: + num_palette = 2; + color_inc = 0xff; + break; + case 2: + num_palette = 4; + color_inc = 0x55; + break; + case 4: + num_palette = 16; + color_inc = 0x11; + break; + case 8: + num_palette = 256; + color_inc = 1; + break; + default: + num_palette = 0; + color_inc = 0; + break; + } + + for (i = 0, v = 0; i < num_palette; i++, v += color_inc) + { + palette[i].red = (png_byte)v; + palette[i].green = (png_byte)v; + palette[i].blue = (png_byte)v; + } +} + +/* This function is currently unused. Do we really need it? */ +#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED) +void /* PRIVATE */ +png_correct_palette(png_structp png_ptr, png_colorp palette, + int num_palette) +{ + png_debug(1, "in png_correct_palette\n"); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) + { + png_color back, back_1; + + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + double g; + + g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); + + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN || + fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) + { + back.red = png_ptr->background.red; + back.green = png_ptr->background.green; + back.blue = png_ptr->background.blue; + } + else + { + back.red = + (png_byte)(pow((double)png_ptr->background.red/255, g) * + 255.0 + 0.5); + back.green = + (png_byte)(pow((double)png_ptr->background.green/255, g) * + 255.0 + 0.5); + back.blue = + (png_byte)(pow((double)png_ptr->background.blue/255, g) * + 255.0 + 0.5); + } + + g = 1.0 / png_ptr->background_gamma; + + back_1.red = + (png_byte)(pow((double)png_ptr->background.red/255, g) * + 255.0 + 0.5); + back_1.green = + (png_byte)(pow((double)png_ptr->background.green/255, g) * + 255.0 + 0.5); + back_1.blue = + (png_byte)(pow((double)png_ptr->background.blue/255, g) * + 255.0 + 0.5); + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_uint_32 i; + + for (i = 0; i < (png_uint_32)num_palette; i++) + { + if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) + { + palette[i] = back; + } + else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) + { + png_byte v, w; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; + png_composite(w, v, png_ptr->trans[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; + png_composite(w, v, png_ptr->trans[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; + png_composite(w, v, png_ptr->trans[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + else + { + int i; + + for (i = 0; i < num_palette; i++) + { + if (palette[i].red == (png_byte)png_ptr->trans_values.gray) + { + palette[i] = back; + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + } + } + else +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (png_ptr->transformations & PNG_GAMMA) + { + int i; + + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + else +#endif +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_color back; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < (int)png_ptr->num_trans; i++) + { + if (png_ptr->trans[i] == 0) + { + palette[i].red = back.red; + palette[i].green = back.green; + palette[i].blue = back.blue; + } + else if (png_ptr->trans[i] != 0xff) + { + png_composite(palette[i].red, png_ptr->palette[i].red, + png_ptr->trans[i], back.red); + png_composite(palette[i].green, png_ptr->palette[i].green, + png_ptr->trans[i], back.green); + png_composite(palette[i].blue, png_ptr->palette[i].blue, + png_ptr->trans[i], back.blue); + } + } + } + else /* assume grayscale palette (what else could it be?) */ + { + int i; + + for (i = 0; i < num_palette; i++) + { + if (i == (png_byte)png_ptr->trans_values.gray) + { + palette[i].red = (png_byte)png_ptr->background.red; + palette[i].green = (png_byte)png_ptr->background.green; + palette[i].blue = (png_byte)png_ptr->background.blue; + } + } + } + } +#endif +} +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Replace any alpha or transparency with the supplied background color. + * "background" is already in the screen gamma, while "background_1" is + * at a gamma of 1.0. Paletted files have already been taken care of. + */ +void /* PRIVATE */ +png_do_background(png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background +#if defined(PNG_READ_GAMMA_SUPPORTED) + , png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift +#endif + ) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + int shift; + + png_debug(1, "in png_do_background\n"); + if (background != NULL && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || + (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_GRAY: + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row; + shift = 7; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x01) + == trans_values->gray) + { + *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 7; + sp++; + } + else + shift--; + } + break; + } + case 2: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == trans_values->gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x03); + png_byte g = (png_byte)((gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03); + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + if (!shift) + { + shift = 6; + sp++; + } + else + shift -= 2; + } + } + else +#endif + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == trans_values->gray) + { + *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 6; + sp++; + } + else + shift -= 2; + } + } + break; + } + case 4: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == trans_values->gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + else + { + png_byte p = (png_byte)((*sp >> shift) & 0x0f); + png_byte g = (png_byte)((gamma_table[p | + (p << 4)] >> 4) & 0x0f); + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(g << shift); + } + if (!shift) + { + shift = 4; + sp++; + } + else + shift -= 4; + } + } + else +#endif + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == trans_values->gray) + { + *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *sp |= (png_byte)(background->gray << shift); + } + if (!shift) + { + shift = 4; + sp++; + } + else + shift -= 4; + } + } + break; + } + case 8: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == trans_values->gray) + { + *sp = (png_byte)background->gray; + } + else + { + *sp = gamma_table[*sp]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == trans_values->gray) + { + *sp = (png_byte)background->gray; + } + } + } + break; + } + case 16: + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_values->gray) + { + /* background is already in screen gamma */ + *sp = (png_byte)((background->gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->gray & 0xff); + } + else + { + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_values->gray) + { + *sp = (png_byte)((background->gray >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->gray & 0xff); + } + } + } + break; + } + } + break; + } + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == trans_values->red && + *(sp + 1) == trans_values->green && + *(sp + 2) == trans_values->blue) + { + *sp = (png_byte)background->red; + *(sp + 1) = (png_byte)background->green; + *(sp + 2) = (png_byte)background->blue; + } + else + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == trans_values->red && + *(sp + 1) == trans_values->green && + *(sp + 2) == trans_values->blue) + { + *sp = (png_byte)background->red; + *(sp + 1) = (png_byte)background->green; + *(sp + 2) = (png_byte)background->blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + if (r == trans_values->red && g == trans_values->green && + b == trans_values->blue) + { + /* background is already in screen gamma */ + *sp = (png_byte)((background->red >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->red & 0xff); + *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(sp + 3) = (png_byte)(background->green & 0xff); + *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); + png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + + if (r == trans_values->red && g == trans_values->green && + b == trans_values->blue) + { + *sp = (png_byte)((background->red >> 8) & 0xff); + *(sp + 1) = (png_byte)(background->red & 0xff); + *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(sp + 3) = (png_byte)(background->green & 0xff); + *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(sp + 5) = (png_byte)(background->blue & 0xff); + } + } + } + } + break; + } + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 2, dp++) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + { + *dp = gamma_table[*sp]; + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)background->gray; + } + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, background_1->gray); + *dp = gamma_from_1[w]; + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 2, dp++) + { + png_byte a = *(sp + 1); + + if (a == 0xff) + { + *dp = *sp; + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) + { + *dp = (png_byte)background->gray; + } + else + { + png_composite(*dp, *sp, a, background_1->gray); + } +#else + *dp = (png_byte)background->gray; +#endif + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 2) + { + png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) +#else + else +#endif + { + /* background is already in screen gamma */ + *dp = (png_byte)((background->gray >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->gray & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, background_1->gray); + w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + *dp = (png_byte)((w >> 8) & 0xff); + *(dp + 1) = (png_byte)(w & 0xff); + } +#endif + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 2) + { + png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + if (a == (png_uint_16)0xffff) + { + png_memcpy(dp, sp, 2); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else if (a == 0) +#else + else +#endif + { + *dp = (png_byte)((background->gray >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->gray & 0xff); + } +#if defined(PNG_READ_GAMMA_SUPPORTED) + else + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, background_1->gray); + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + } +#endif + } + } + } + break; + } + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 3) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *dp = gamma_table[*sp]; + *(dp + 1) = gamma_table[*(sp + 1)]; + *(dp + 2) = gamma_table[*(sp + 2)]; + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)background->red; + *(dp + 1) = (png_byte)background->green; + *(dp + 2) = (png_byte)background->blue; + } + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, background_1->red); + *dp = gamma_from_1[w]; + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, background_1->green); + *(dp + 1) = gamma_from_1[w]; + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, background_1->blue); + *(dp + 2) = gamma_from_1[w]; + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 4, dp += 3) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *dp = *sp; + *(dp + 1) = *(sp + 1); + *(dp + 2) = *(sp + 2); + } + else if (a == 0) + { + *dp = (png_byte)background->red; + *(dp + 1) = (png_byte)background->green; + *(dp + 2) = (png_byte)background->blue; + } + else + { + png_composite(*dp, *sp, a, background->red); + png_composite(*(dp + 1), *(sp + 1), a, + background->green); + png_composite(*(dp + 2), *(sp + 2), a, + background->blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#if defined(PNG_READ_GAMMA_SUPPORTED) + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 8, dp += 6) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(dp + 2) = (png_byte)((v >> 8) & 0xff); + *(dp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(dp + 4) = (png_byte)((v >> 8) & 0xff); + *(dp + 5) = (png_byte)(v & 0xff); + } + else if (a == 0) + { + /* background is already in screen gamma */ + *dp = (png_byte)((background->red >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->red & 0xff); + *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(dp + 3) = (png_byte)(background->green & 0xff); + *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(dp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v, w, x; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, background_1->red); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *dp = (png_byte)((x >> 8) & 0xff); + *(dp + 1) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, background_1->green); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + *(dp + 2) = (png_byte)((x >> 8) & 0xff); + *(dp + 3) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, background_1->blue); + x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; + *(dp + 4) = (png_byte)((x >> 8) & 0xff); + *(dp + 5) = (png_byte)(x & 0xff); + } + } + } + else +#endif + { + sp = row; + dp = row; + for (i = 0; i < row_width; i++, sp += 8, dp += 6) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) + { + png_memcpy(dp, sp, 6); + } + else if (a == 0) + { + *dp = (png_byte)((background->red >> 8) & 0xff); + *(dp + 1) = (png_byte)(background->red & 0xff); + *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); + *(dp + 3) = (png_byte)(background->green & 0xff); + *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); + *(dp + 5) = (png_byte)(background->blue & 0xff); + } + else + { + png_uint_16 v; + + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + png_composite_16(v, r, a, background->red); + *dp = (png_byte)((v >> 8) & 0xff); + *(dp + 1) = (png_byte)(v & 0xff); + png_composite_16(v, g, a, background->green); + *(dp + 2) = (png_byte)((v >> 8) & 0xff); + *(dp + 3) = (png_byte)(v & 0xff); + png_composite_16(v, b, a, background->blue); + *(dp + 4) = (png_byte)((v >> 8) & 0xff); + *(dp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + } + + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->channels--; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + } +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Gamma correct the image, avoiding the alpha channel. Make sure + * you do this after you deal with the transparency issue on grayscale + * or RGB images. If your bit depth is 8, use gamma_table, if it + * is 16, use gamma_16_table and gamma_shift. Build these with + * build_gamma_table(). + */ +void /* PRIVATE */ +png_do_gamma(png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift) +{ + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + ((row_info->bit_depth <= 8 && gamma_table != NULL) || + (row_info->bit_depth == 16 && gamma_16_table != NULL))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + sp++; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp += 2; + } + } + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + case PNG_COLOR_TYPE_GRAY: + { + if (row_info->bit_depth == 2) + { + sp = row; + for (i = 0; i < row_width; i += 4) + { + int a = *sp & 0xc0; + int b = *sp & 0x30; + int c = *sp & 0x0c; + int d = *sp & 0x03; + + *sp = (png_byte)( + ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| + ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| + ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| + ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); + sp++; + } + } + if (row_info->bit_depth == 4) + { + sp = row; + for (i = 0; i < row_width; i += 2) + { + int msb = *sp & 0xf0; + int lsb = *sp & 0x0f; + + *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) + | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); + sp++; + } + } + else if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + } + } + else if (row_info->bit_depth == 16) + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + } + } +} +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expands a palette row to an RGB or RGBA row depending + * upon whether you supply trans and num_trans. + */ +void /* PRIVATE */ +png_do_expand_palette(png_row_infop row_info, png_bytep row, + png_colorp palette, png_bytep trans, int num_trans) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand_palette\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 1; + else + *dp = 0; + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)value; + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((row_width & 0x01) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)value; + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift += 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + switch (row_info->bit_depth) + { + case 8: + { + if (trans != NULL) + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + + for (i = 0; i < row_width; i++) + { + if ((int)(*sp) >= num_trans) + *dp-- = 0xff; + else + *dp-- = trans[*sp]; + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 32; + row_info->rowbytes = row_width * 4; + row_info->color_type = 6; + row_info->channels = 4; + } + else + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width * 3) - 1; + + for (i = 0; i < row_width; i++) + { + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 24; + row_info->rowbytes = row_width * 3; + row_info->color_type = 2; + row_info->channels = 3; + } + break; + } + } + } +} + +/* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. + */ +void /* PRIVATE */ +png_do_expand(png_row_infop row_info, png_bytep row, + png_color_16p trans_value) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); + + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + gray = (png_uint_16)(gray*0xff); + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 0xff; + else + *dp = 0; + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; + + dp--; + } + break; + } + case 2: + { + gray = (png_uint_16)(gray*0x55); + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; + + dp--; + } + break; + } + case 4: + { + gray = (png_uint_16)(gray*0x11); + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift = 4; + + dp--; + } + break; + } + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (trans_value != NULL) + { + if (row_info->bit_depth == 8) + { + sp = row + (png_size_t)row_width - 1; + dp = row + (png_size_t)(row_width << 1) - 1; + for (i = 0; i < row_width; i++) + { + if (*sp == gray) + *dp-- = 0; + else + *dp-- = 0xff; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + sp = row + row_info->rowbytes - 1; + dp = row + (row_info->rowbytes << 1) - 1; + for (i = 0; i < row_width; i++) + { + if (((png_uint_16)*(sp) | + ((png_uint_16)*(sp - 1) << 8)) == gray) + { + *dp-- = 0; + *dp-- = 0; + } + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_width); + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) + { + if (row_info->bit_depth == 8) + { + sp = row + (png_size_t)row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 2) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 2) == trans_value->red && + *(sp - 1) == trans_value->green && + *(sp - 0) == trans_value->blue) + *dp-- = 0; + else + *dp-- = 0xff; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + sp = row + row_info->rowbytes - 1; + dp = row + (png_size_t)(row_width << 3) - 1; + for (i = 0; i < row_width; i++) + { + if ((((png_uint_16)*(sp - 4) | + ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) && + (((png_uint_16)*(sp - 2) | + ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) && + (((png_uint_16)*(sp - 0) | + ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue)) + { + *dp-- = 0; + *dp-- = 0; + } + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + row_info->channels = 4; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + } +} +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +void /* PRIVATE */ +png_do_dither(png_row_infop row_info, png_bytep row, + png_bytep palette_lookup, png_bytep dither_lookup) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_dither\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB && + palette_lookup && row_info->bit_depth == 8) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + + /* this looks real messy, but the compiler will reduce + it down to a reasonable formula. For example, with + 5 bits per color, we get: + p = (((r >> 3) & 0x1f) << 10) | + (((g >> 3) & 0x1f) << 5) | + ((b >> 3) & 0x1f); + */ + p = (((r >> (8 - PNG_DITHER_RED_BITS)) & + ((1 << PNG_DITHER_RED_BITS) - 1)) << + (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | + (((g >> (8 - PNG_DITHER_GREEN_BITS)) & + ((1 << PNG_DITHER_GREEN_BITS) - 1)) << + (PNG_DITHER_BLUE_BITS)) | + ((b >> (8 - PNG_DITHER_BLUE_BITS)) & + ((1 << PNG_DITHER_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + palette_lookup != NULL && row_info->bit_depth == 8) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + sp++; + + p = (((r >> (8 - PNG_DITHER_RED_BITS)) & + ((1 << PNG_DITHER_RED_BITS) - 1)) << + (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | + (((g >> (8 - PNG_DITHER_GREEN_BITS)) & + ((1 << PNG_DITHER_GREEN_BITS) - 1)) << + (PNG_DITHER_BLUE_BITS)) | + ((b >> (8 - PNG_DITHER_BLUE_BITS)) & + ((1 << PNG_DITHER_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + } + else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + dither_lookup && row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + *sp = dither_lookup[*sp]; + } + } + } +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +#if defined(PNG_READ_GAMMA_SUPPORTED) +const static int png_gamma_shift[] = + {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * the future. Note also how the gamma_16 tables are segmented so that + * we don't need to allocate > 64K chunks for a full 16-bit table. + */ +void /* PRIVATE */ +png_build_gamma_table(png_structp png_ptr) +{ + png_debug(1, "in png_build_gamma_table\n"); + + if (png_ptr->bit_depth <= 8) + { + int i; + double g; + + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + else + g = 1.0; + + png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) + { + + g = 1.0 / (png_ptr->gamma); + + png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + } + + + png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, + (png_uint_32)256); + + if(png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; + else + g = png_ptr->gamma; /* probably doing rgb_to_gray */ + + for (i = 0; i < 256; i++) + { + png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, + g) * 255.0 + .5); + + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } + else + { + double g; + int i, j, shift, num; + int sig_bit; + png_uint_32 ig; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = (int)png_ptr->sig_bit.red; + if ((int)png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + if ((int)png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + { + sig_bit = (int)png_ptr->sig_bit.gray; + } + + if (sig_bit > 0) + shift = 16 - sig_bit; + else + shift = 0; + + if (png_ptr->transformations & PNG_16_TO_8) + { + if (shift < (16 - PNG_MAX_GAMMA_8)) + shift = (16 - PNG_MAX_GAMMA_8); + } + + if (shift > 8) + shift = 8; + if (shift < 0) + shift = 0; + + png_ptr->gamma_shift = (png_byte)shift; + + num = (1 << (8 - shift)); + + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + else + g = 1.0; + + png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p))); + + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) + { + double fin, fout; + png_uint_32 last, max; + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + } + + g = 1.0 / g; + last = 0; + for (i = 0; i < 256; i++) + { + fout = ((double)i + 0.5) / 256.0; + fin = pow(fout, g); + max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); + while (last <= max) + { + png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] + [(int)(last >> (8 - shift))] = (png_uint_16)( + (png_uint_16)i | ((png_uint_16)i << 8)); + last++; + } + } + while (last < ((png_uint_32)num << 8)) + { + png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] + [(int)(last >> (8 - shift))] = (png_uint_16)65535L; + last++; + } + } + else + { + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_table[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + } + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) + { + + g = 1.0 / (png_ptr->gamma); + + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p ))); + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * + (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_to_1[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + + if(png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; + else + g = png_ptr->gamma; /* probably doing rgb_to_gray */ + + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof (png_uint_16p))); + + for (i = 0; i < num; i++) + { + png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(256 * png_sizeof (png_uint_16))); + + ig = (((png_uint_32)i * + (png_uint_32)png_gamma_shift[shift]) >> 4); + for (j = 0; j < 256; j++) + { + png_ptr->gamma_16_from_1[i][j] = + (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / + 65535.0, g) * 65535.0 + .5); + } + } + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } +} +#endif +/* To do: install integer version of png_build_gamma_table here */ +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +/* undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_intrapixel\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); + *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); + png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); + png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); + png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp+1) = (png_byte)(red & 0xff); + *(rp+4) = (png_byte)((blue >> 8) & 0xff); + *(rp+5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngrutil.c b/src/dep/src/irrlicht/libpng/pngrutil.c new file mode 100644 index 0000000..9860768 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngrutil.c @@ -0,0 +1,3132 @@ + +/* pngrutil.c - utilities to read a PNG file + * + * Last changed in libpng 1.2.17 May 15, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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 contains routines that are only called from within + * libpng itself during the course of reading an image. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) + +#ifdef PNG_FLOATING_POINT_SUPPORTED +# if defined(_WIN32_WCE) +/* strtod() function is not supported on WindowsCE */ +__inline double png_strtod(png_structp png_ptr, const char *nptr, char **endptr) +{ + double result = 0; + int len; + wchar_t *str, *end; + + len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); + str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t)); + if ( NULL != str ) + { + MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); + result = wcstod(str, &end); + len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); + *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); + png_free(str); + } + return result; +} +# else +# define png_strtod(p,a,b) strtod(a,b) +# endif +#endif + +png_uint_32 PNGAPI +png_get_uint_31(png_structp png_ptr, png_bytep buf) +{ + png_uint_32 i = png_get_uint_32(buf); + if (i > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range."); + return (i); +} +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ +png_uint_32 PNGAPI +png_get_uint_32(png_bytep buf) +{ + png_uint_32 i = ((png_uint_32)(*buf) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + (png_uint_32)(*(buf + 3)); + + return (i); +} + +/* Grab a signed 32-bit integer from a buffer in big-endian format. The + * data is stored in the PNG file in two's complement format, and it is + * assumed that the machine format for signed integers is the same. */ +png_int_32 PNGAPI +png_get_int_32(png_bytep buf) +{ + png_int_32 i = ((png_int_32)(*buf) << 24) + + ((png_int_32)(*(buf + 1)) << 16) + + ((png_int_32)(*(buf + 2)) << 8) + + (png_int_32)(*(buf + 3)); + + return (i); +} + +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ +png_uint_16 PNGAPI +png_get_uint_16(png_bytep buf) +{ + png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + + (png_uint_16)(*(buf + 1))); + + return (i); +} +#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ + +/* Read data, and (optionally) run it through the CRC. */ +void /* PRIVATE */ +png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) +{ + if(png_ptr == NULL) return; + png_read_data(png_ptr, buf, length); + png_calculate_crc(png_ptr, buf, length); +} + +/* Optionally skip data and then check the CRC. Depending on whether we + are reading a ancillary or critical chunk, and how the program has set + things up, we may calculate the CRC on the data and print a message. + Returns '1' if there was a CRC error, '0' otherwise. */ +int /* PRIVATE */ +png_crc_finish(png_structp png_ptr, png_uint_32 skip) +{ + png_size_t i; + png_size_t istop = png_ptr->zbuf_size; + + for (i = (png_size_t)skip; i > istop; i -= istop) + { + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + } + if (i) + { + png_crc_read(png_ptr, png_ptr->zbuf, i); + } + + if (png_crc_error(png_ptr)) + { + if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || + (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) + { + png_chunk_warning(png_ptr, "CRC error"); + } + else + { + png_chunk_error(png_ptr, "CRC error"); + } + return (1); + } + + return (0); +} + +/* Compare the CRC stored in the PNG file with that calculated by libpng from + the data it has read thus far. */ +int /* PRIVATE */ +png_crc_error(png_structp png_ptr) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + else /* critical */ + { + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + need_crc = 0; + } + + png_read_data(png_ptr, crc_bytes, 4); + + if (need_crc) + { + crc = png_get_uint_32(crc_bytes); + return ((int)(crc != png_ptr->crc)); + } + else + return (0); +} + +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ + defined(PNG_READ_iCCP_SUPPORTED) +/* + * Decompress trailing data in a chunk. The assumption is that chunkdata + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ +png_charp /* PRIVATE */ +png_decompress_chunk(png_structp png_ptr, int comp_type, + png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_size, png_size_t *newlength) +{ + const static char msg[] = "Error decoding compressed text"; + png_charp text; + png_size_t text_size; + + if (comp_type == PNG_COMPRESSION_TYPE_BASE) + { + int ret = Z_OK; + png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); + png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + text_size = 0; + text = NULL; + + while (png_ptr->zstream.avail_in) + { + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_warning(png_ptr, png_ptr->zstream.msg); + else + png_warning(png_ptr, msg); + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (text == NULL) + { + text_size = prefix_size + png_sizeof(msg) + 1; + text = (png_charp)png_malloc_warn(png_ptr, text_size); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk"); + } + png_memcpy(text, chunkdata, prefix_size); + } + + text[text_size - 1] = 0x00; + + /* Copy what we can of the error message into the text chunk */ + text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); + text_size = png_sizeof(msg) > text_size ? text_size : + png_sizeof(msg); + png_memcpy(text + prefix_size, msg, text_size + 1); + break; + } + if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) + { + if (text == NULL) + { + text_size = prefix_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk."); + } + png_memcpy(text + prefix_size, png_ptr->zbuf, + text_size - prefix_size); + png_memcpy(text, chunkdata, prefix_size); + *(text + text_size) = 0x00; + } + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc_warn(png_ptr, + (png_uint_32)(text_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); + if (text == NULL) + { + png_free(png_ptr, tmp); + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk.."); + } + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, + (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = 0x00; + } + if (ret == Z_STREAM_END) + break; + else + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + } + if (ret != Z_STREAM_END) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char umsg[52]; + + if (ret == Z_BUF_ERROR) + sprintf(umsg,"Buffer error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else if (ret == Z_DATA_ERROR) + sprintf(umsg,"Data error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else + sprintf(umsg,"Incomplete compressed datastream in %s chunk", + png_ptr->chunk_name); + png_warning(png_ptr, umsg); +#else + png_warning(png_ptr, + "Incomplete compressed datastream in chunk other than IDAT"); +#endif + text_size=prefix_size; + if (text == NULL) + { + text = (png_charp)png_malloc_warn(png_ptr, text_size+1); + if (text == NULL) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory for text."); + } + png_memcpy(text, chunkdata, prefix_size); + } + *(text + text_size) = 0x00; + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + png_free(png_ptr, chunkdata); + chunkdata = text; + *newlength=text_size; + } + else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char umsg[50]; + + sprintf(umsg, "Unknown zTXt compression type %d", comp_type); + png_warning(png_ptr, umsg); +#else + png_warning(png_ptr, "Unknown zTXt compression type"); +#endif + + *(chunkdata + prefix_size) = 0x00; + *newlength=prefix_size; + } + + return chunkdata; +} +#endif + +/* read and check the IDHR chunk */ +void /* PRIVATE */ +png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[13]; + png_uint_32 width, height; + int bit_depth, color_type, compression_type, filter_type; + int interlace_type; + + png_debug(1, "in png_handle_IHDR\n"); + + if (png_ptr->mode & PNG_HAVE_IHDR) + png_error(png_ptr, "Out of place IHDR"); + + /* check the length */ + if (length != 13) + png_error(png_ptr, "Invalid IHDR chunk"); + + png_ptr->mode |= PNG_HAVE_IHDR; + + png_crc_read(png_ptr, buf, 13); + png_crc_finish(png_ptr, 0); + + width = png_get_uint_31(png_ptr, buf); + height = png_get_uint_31(png_ptr, buf + 4); + bit_depth = buf[8]; + color_type = buf[9]; + compression_type = buf[10]; + filter_type = buf[11]; + interlace_type = buf[12]; + + /* set internal variables */ + png_ptr->width = width; + png_ptr->height = height; + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->interlaced = (png_byte)interlace_type; + png_ptr->color_type = (png_byte)color_type; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + + /* find number of channels */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_PALETTE: + png_ptr->channels = 1; + break; + case PNG_COLOR_TYPE_RGB: + png_ptr->channels = 3; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_ptr->channels = 2; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + png_ptr->channels = 4; + break; + } + + /* set up other useful info */ + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * + png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); + png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth); + png_debug1(3,"channels = %d\n", png_ptr->channels); + png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + color_type, interlace_type, compression_type, filter_type); +} + +/* read and check the palette */ +void /* PRIVATE */ +png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_color palette[PNG_MAX_PALETTE_LENGTH]; + int num, i; +#ifndef PNG_NO_POINTER_INDEXING + png_colorp pal_ptr; +#endif + + png_debug(1, "in png_handle_PLTE\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before PLTE"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid PLTE after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + png_error(png_ptr, "Duplicate PLTE chunk"); + + png_ptr->mode |= PNG_HAVE_PLTE; + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring PLTE chunk in grayscale PNG"); + png_crc_finish(png_ptr, length); + return; + } +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_crc_finish(png_ptr, length); + return; + } +#endif + + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) + { + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + png_warning(png_ptr, "Invalid palette chunk"); + png_crc_finish(png_ptr, length); + return; + } + else + { + png_error(png_ptr, "Invalid palette chunk"); + } + } + + num = (int)length / 3; + +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + pal_ptr->red = buf[0]; + pal_ptr->green = buf[1]; + pal_ptr->blue = buf[2]; + } +#else + for (i = 0; i < num; i++) + { + png_byte buf[3]; + + png_crc_read(png_ptr, buf, 3); + /* don't depend upon png_color being any order */ + palette[i].red = buf[0]; + palette[i].green = buf[1]; + palette[i].blue = buf[2]; + } +#endif + + /* If we actually NEED the PLTE chunk (ie for a paletted image), we do + whatever the normal CRC configuration tells us. However, if we + have an RGB image, the PLTE can be considered ancillary, so + we will act as though it is. */ +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#endif + { + png_crc_finish(png_ptr, 0); + } +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ + { + /* If we don't want to use the data from an ancillary chunk, + we have two options: an error abort, or a warning and we + ignore the data in this chunk (which should be OK, since + it's considered ancillary for a RGB or RGBA image). */ + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) + { + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) + { + png_chunk_error(png_ptr, "CRC error"); + } + else + { + png_chunk_warning(png_ptr, "CRC error"); + return; + } + } + /* Otherwise, we (optionally) emit a warning and use the chunk. */ + else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) + { + png_chunk_warning(png_ptr, "CRC error"); + } + } +#endif + + png_set_PLTE(png_ptr, info_ptr, palette, num); + +#if defined(PNG_READ_tRNS_SUPPORTED) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + if (png_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); + png_ptr->num_trans = (png_uint_16)num; + } + if (info_ptr->num_trans > (png_uint_16)num) + { + png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); + info_ptr->num_trans = (png_uint_16)num; + } + } + } +#endif + +} + +void /* PRIVATE */ +png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_debug(1, "in png_handle_IEND\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) + { + png_error(png_ptr, "No image in file"); + } + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + + if (length != 0) + { + png_warning(png_ptr, "Incorrect IEND chunk length"); + } + png_crc_finish(png_ptr, length); + + if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ + return; +} + +#if defined(PNG_READ_gAMA_SUPPORTED) +void /* PRIVATE */ +png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_fixed_point igamma; +#ifdef PNG_FLOATING_POINT_SUPPORTED + float file_gamma; +#endif + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before gAMA"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid gAMA after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place gAMA chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) +#if defined(PNG_READ_sRGB_SUPPORTED) + && !(info_ptr->valid & PNG_INFO_sRGB) +#endif + ) + { + png_warning(png_ptr, "Duplicate gAMA chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 4) + { + png_warning(png_ptr, "Incorrect gAMA chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 4); + if (png_crc_finish(png_ptr, 0)) + return; + + igamma = (png_fixed_point)png_get_uint_32(buf); + /* check for zero gamma */ + if (igamma == 0) + { + png_warning(png_ptr, + "Ignoring gAMA chunk with gamma=0"); + return; + } + +#if defined(PNG_READ_sRGB_SUPPORTED) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + { + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO + fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); +#endif + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + file_gamma = (float)igamma / (float)100000.0; +# ifdef PNG_READ_GAMMA_SUPPORTED + png_ptr->gamma = file_gamma; +# endif + png_set_gAMA(png_ptr, info_ptr, file_gamma); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, igamma); +#endif +} +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +void /* PRIVATE */ +png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[4]; + + png_debug(1, "in png_handle_sBIT\n"); + + buf[0] = buf[1] = buf[2] = buf[3] = 0; + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sBIT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sBIT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + { + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sBIT chunk"); + } + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) + { + png_warning(png_ptr, "Duplicate sBIT chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 3; + else + truelen = (png_size_t)png_ptr->channels; + + if (length != truelen || length > 4) + { + png_warning(png_ptr, "Incorrect sBIT chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) + return; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; + png_ptr->sig_bit.blue = buf[2]; + png_ptr->sig_bit.alpha = buf[3]; + } + else + { + png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[0]; + png_ptr->sig_bit.blue = buf[0]; + png_ptr->sig_bit.alpha = buf[1]; + } + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); +} +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +void /* PRIVATE */ +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[4]; +#ifdef PNG_FLOATING_POINT_SUPPORTED + float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; +#endif + png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, + int_y_green, int_x_blue, int_y_blue; + + png_uint_32 uint_x, uint_y; + + png_debug(1, "in png_handle_cHRM\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before cHRM"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid cHRM after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Missing PLTE before cHRM"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) +#if defined(PNG_READ_sRGB_SUPPORTED) + && !(info_ptr->valid & PNG_INFO_sRGB) +#endif + ) + { + png_warning(png_ptr, "Duplicate cHRM chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 32) + { + png_warning(png_ptr, "Incorrect cHRM chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM white point"); + png_crc_finish(png_ptr, 24); + return; + } + int_x_white = (png_fixed_point)uint_x; + int_y_white = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM red point"); + png_crc_finish(png_ptr, 16); + return; + } + int_x_red = (png_fixed_point)uint_x; + int_y_red = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM green point"); + png_crc_finish(png_ptr, 8); + return; + } + int_x_green = (png_fixed_point)uint_x; + int_y_green = (png_fixed_point)uint_y; + + png_crc_read(png_ptr, buf, 4); + uint_x = png_get_uint_32(buf); + + png_crc_read(png_ptr, buf, 4); + uint_y = png_get_uint_32(buf); + + if (uint_x + uint_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM blue point"); + png_crc_finish(png_ptr, 0); + return; + } + int_x_blue = (png_fixed_point)uint_x; + int_y_blue = (png_fixed_point)uint_y; + +#ifdef PNG_FLOATING_POINT_SUPPORTED + white_x = (float)int_x_white / (float)100000.0; + white_y = (float)int_y_white / (float)100000.0; + red_x = (float)int_x_red / (float)100000.0; + red_y = (float)int_y_red / (float)100000.0; + green_x = (float)int_x_green / (float)100000.0; + green_y = (float)int_y_green / (float)100000.0; + blue_x = (float)int_x_blue / (float)100000.0; + blue_y = (float)int_y_blue / (float)100000.0; +#endif + +#if defined(PNG_READ_sRGB_SUPPORTED) + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_FLOATING_POINT_SUPPORTED + fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n", + white_x, white_y, red_x, red_y); + fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n", + green_x, green_y, blue_x, blue_y); +#else + fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", + int_x_white, int_y_white, int_x_red, int_y_red); + fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n", + int_x_green, int_y_green, int_x_blue, int_y_blue); +#endif +#endif /* PNG_NO_CONSOLE_IO */ + } + png_crc_finish(png_ptr, 0); + return; + } +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_set_cHRM(png_ptr, info_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, + int_y_green, int_x_blue, int_y_blue); +#endif + if (png_crc_finish(png_ptr, 0)) + return; +} +#endif + +#if defined(PNG_READ_sRGB_SUPPORTED) +void /* PRIVATE */ +png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + int intent; + png_byte buf[1]; + + png_debug(1, "in png_handle_sRGB\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sRGB"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sRGB after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sRGB chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { + png_warning(png_ptr, "Duplicate sRGB chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 1) + { + png_warning(png_ptr, "Incorrect sRGB chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 1); + if (png_crc_finish(png_ptr, 0)) + return; + + intent = buf[0]; + /* check for bad intent */ + if (intent >= PNG_sRGB_INTENT_LAST) + { + png_warning(png_ptr, "Unknown sRGB intent"); + return; + } + +#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) + { + png_fixed_point igamma; +#ifdef PNG_FIXED_POINT_SUPPORTED + igamma=info_ptr->int_gamma; +#else +# ifdef PNG_FLOATING_POINT_SUPPORTED + igamma=(png_fixed_point)(info_ptr->gamma * 100000.); +# endif +#endif + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + { + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); +#ifndef PNG_NO_CONSOLE_IO +# ifdef PNG_FIXED_POINT_SUPPORTED + fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma); +# else +# ifdef PNG_FLOATING_POINT_SUPPORTED + fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma); +# endif +# endif +#endif + } + } +#endif /* PNG_READ_gAMA_SUPPORTED */ + +#ifdef PNG_READ_cHRM_SUPPORTED +#ifdef PNG_FIXED_POINT_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) + if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + } +#endif /* PNG_FIXED_POINT_SUPPORTED */ +#endif /* PNG_READ_cHRM_SUPPORTED */ + + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); +} +#endif /* PNG_READ_sRGB_SUPPORTED */ + +#if defined(PNG_READ_iCCP_SUPPORTED) +void /* PRIVATE */ +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_charp chunkdata; + png_byte compression_type; + png_bytep pC; + png_charp profile; + png_uint_32 skip = 0; + png_uint_32 profile_size, profile_length; + png_size_t slength, prefix_length, data_length; + + png_debug(1, "in png_handle_iCCP\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iCCP"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid iCCP after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place iCCP chunk"); + + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) + { + png_warning(png_ptr, "Duplicate iCCP chunk"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "iCCP chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (profile = chunkdata; *profile; profile++) + /* empty loop to find end of name */ ; + + ++profile; + + /* there should be at least one zero (the compression type byte) + following the separator, and we should be on it */ + if ( profile >= chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Malformed iCCP chunk"); + return; + } + + /* compression_type should always be zero */ + compression_type = *profile++; + if (compression_type) + { + png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); + compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 + wrote nonzero) */ + } + + prefix_length = profile - chunkdata; + chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, + slength, prefix_length, &data_length); + + profile_length = data_length - prefix_length; + + if ( prefix_length > data_length || profile_length < 4) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Profile size field missing from iCCP chunk"); + return; + } + + /* Check the profile_size recorded in the first 32 bits of the ICC profile */ + pC = (png_bytep)(chunkdata+prefix_length); + profile_size = ((*(pC ))<<24) | + ((*(pC+1))<<16) | + ((*(pC+2))<< 8) | + ((*(pC+3)) ); + + if(profile_size < profile_length) + profile_length = profile_size; + + if(profile_size > profile_length) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "Ignoring truncated iCCP profile."); + return; + } + + png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, + chunkdata + prefix_length, profile_length); + png_free(png_ptr, chunkdata); +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_sPLT_SUPPORTED) +void /* PRIVATE */ +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep chunkdata; + png_bytep entry_start; + png_sPLT_t new_palette; +#ifdef PNG_NO_POINTER_INDEXING + png_sPLT_entryp pp; +#endif + int data_length, entry_size, i; + png_uint_32 skip = 0; + png_size_t slength; + + png_debug(1, "in png_handle_sPLT\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sPLT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sPLT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "sPLT chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (entry_start = chunkdata; *entry_start; entry_start++) + /* empty loop to find end of name */ ; + ++entry_start; + + /* a sample depth should follow the separator, and we should be on it */ + if (entry_start > chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "malformed sPLT chunk"); + return; + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + data_length = (slength - (entry_start - chunkdata)); + + /* integrity-check the data length */ + if (data_length % entry_size) + { + png_free(png_ptr, chunkdata); + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + new_palette.nentries = (png_int_32) ( data_length / entry_size); + if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX / + png_sizeof(png_sPLT_entry))) + { + png_warning(png_ptr, "sPLT chunk too long"); + return; + } + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( + png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); + if (new_palette.entries == NULL) + { + png_warning(png_ptr, "sPLT chunk requires too much memory"); + return; + } + +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0; i < new_palette.nentries; i++) + { + png_sPLT_entryp pp = new_palette.entries + i; + + if (new_palette.depth == 8) + { + pp->red = *entry_start++; + pp->green = *entry_start++; + pp->blue = *entry_start++; + pp->alpha = *entry_start++; + } + else + { + pp->red = png_get_uint_16(entry_start); entry_start += 2; + pp->green = png_get_uint_16(entry_start); entry_start += 2; + pp->blue = png_get_uint_16(entry_start); entry_start += 2; + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; + } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#else + pp = new_palette.entries; + for (i = 0; i < new_palette.nentries; i++) + { + + if (new_palette.depth == 8) + { + pp[i].red = *entry_start++; + pp[i].green = *entry_start++; + pp[i].blue = *entry_start++; + pp[i].alpha = *entry_start++; + } + else + { + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; + } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } +#endif + + /* discard all chunk data except the name and stash that */ + new_palette.name = (png_charp)chunkdata; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, chunkdata); + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_tRNS_SUPPORTED) +void /* PRIVATE */ +png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_tRNS\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tRNS"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid tRNS after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + { + png_warning(png_ptr, "Duplicate tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + png_byte buf[2]; + + if (length != 2) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 2); + png_ptr->num_trans = 1; + png_ptr->trans_values.gray = png_get_uint_16(buf); + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_byte buf[6]; + + if (length != 6) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + png_crc_read(png_ptr, buf, (png_size_t)length); + png_ptr->num_trans = 1; + png_ptr->trans_values.red = png_get_uint_16(buf); + png_ptr->trans_values.green = png_get_uint_16(buf + 2); + png_ptr->trans_values.blue = png_get_uint_16(buf + 4); + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + /* Should be an error, but we can cope with it. */ + png_warning(png_ptr, "Missing PLTE before tRNS"); + } + if (length > (png_uint_32)png_ptr->num_palette || + length > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); + return; + } + if (length == 0) + { + png_warning(png_ptr, "Zero length tRNS chunk"); + png_crc_finish(png_ptr, length); + return; + } + png_crc_read(png_ptr, readbuf, (png_size_t)length); + png_ptr->num_trans = (png_uint_16)length; + } + else + { + png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_crc_finish(png_ptr, 0)) + { + png_ptr->num_trans = 0; + return; + } + + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_values)); +} +#endif + +#if defined(PNG_READ_bKGD_SUPPORTED) +void /* PRIVATE */ +png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_size_t truelen; + png_byte buf[6]; + + png_debug(1, "in png_handle_bKGD\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before bKGD"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid bKGD after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before bKGD"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) + { + png_warning(png_ptr, "Duplicate bKGD chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + truelen = 1; + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + truelen = 6; + else + truelen = 2; + + if (length != truelen) + { + png_warning(png_ptr, "Incorrect bKGD chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) + return; + + /* We convert the index value into RGB components so that we can allow + * arbitrary RGB values for background when we have transparency, and + * so it is easy to determine the RGB values of the background color + * from the info_ptr struct. */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_ptr->background.index = buf[0]; + if(info_ptr->num_palette) + { + if(buf[0] > info_ptr->num_palette) + { + png_warning(png_ptr, "Incorrect bKGD chunk index value"); + return; + } + png_ptr->background.red = + (png_uint_16)png_ptr->palette[buf[0]].red; + png_ptr->background.green = + (png_uint_16)png_ptr->palette[buf[0]].green; + png_ptr->background.blue = + (png_uint_16)png_ptr->palette[buf[0]].blue; + } + } + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ + { + png_ptr->background.red = + png_ptr->background.green = + png_ptr->background.blue = + png_ptr->background.gray = png_get_uint_16(buf); + } + else + { + png_ptr->background.red = png_get_uint_16(buf); + png_ptr->background.green = png_get_uint_16(buf + 2); + png_ptr->background.blue = png_get_uint_16(buf + 4); + } + + png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); +} +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +void /* PRIVATE */ +png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + unsigned int num, i; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_hIST\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before hIST"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid hIST after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (!(png_ptr->mode & PNG_HAVE_PLTE)) + { + png_warning(png_ptr, "Missing PLTE before hIST"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) + { + png_warning(png_ptr, "Duplicate hIST chunk"); + png_crc_finish(png_ptr, length); + return; + } + + num = length / 2 ; + if (num != (unsigned int) png_ptr->num_palette || num > + (unsigned int) PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, "Incorrect hIST chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + for (i = 0; i < num; i++) + { + png_byte buf[2]; + + png_crc_read(png_ptr, buf, 2); + readbuf[i] = png_get_uint_16(buf); + } + + if (png_crc_finish(png_ptr, 0)) + return; + + png_set_hIST(png_ptr, info_ptr, readbuf); +} +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +void /* PRIVATE */ +png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_uint_32 res_x, res_y; + int unit_type; + + png_debug(1, "in png_handle_pHYs\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pHYs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pHYs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_warning(png_ptr, "Duplicate pHYs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect pHYs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) + return; + + res_x = png_get_uint_32(buf); + res_y = png_get_uint_32(buf + 4); + unit_type = buf[8]; + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); +} +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +void /* PRIVATE */ +png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_int_32 offset_x, offset_y; + int unit_type; + + png_debug(1, "in png_handle_oFFs\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before oFFs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid oFFs after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + { + png_warning(png_ptr, "Duplicate oFFs chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (length != 9) + { + png_warning(png_ptr, "Incorrect oFFs chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) + return; + + offset_x = png_get_int_32(buf); + offset_y = png_get_int_32(buf + 4); + unit_type = buf[8]; + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); +} +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +/* read the pCAL chunk (described in the PNG Extensions document) */ +void /* PRIVATE */ +png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_charp purpose; + png_int_32 X0, X1; + png_byte type, nparams; + png_charp buf, units, endptr; + png_charpp params; + png_size_t slength; + int i; + + png_debug(1, "in png_handle_pCAL\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before pCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid pCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) + { + png_warning(png_ptr, "Duplicate pCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", + length + 1); + purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (purpose == NULL) + { + png_warning(png_ptr, "No memory for pCAL purpose."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)purpose, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, purpose); + return; + } + + purpose[slength] = 0x00; /* null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string\n"); + for (buf = purpose; *buf; buf++) + /* empty loop */ ; + + endptr = purpose + slength; + + /* We need to have at least 12 bytes after the purpose string + in order to get the parameter information. */ + if (endptr <= buf + 12) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, purpose); + return; + } + + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); + X0 = png_get_int_32((png_bytep)buf+1); + X1 = png_get_int_32((png_bytep)buf+5); + type = buf[9]; + nparams = buf[10]; + units = buf + 11; + + png_debug(3, "Checking pCAL equation type and number of parameters\n"); + /* Check that we have the right number of parameters for known + equation types. */ + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || + (type == PNG_EQUATION_BASE_E && nparams != 3) || + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) + { + png_warning(png_ptr, "Invalid pCAL parameters for equation type"); + png_free(png_ptr, purpose); + return; + } + else if (type >= PNG_EQUATION_LAST) + { + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + } + + for (buf = units; *buf; buf++) + /* Empty loop to move past the units string. */ ; + + png_debug(3, "Allocating pCAL parameters array\n"); + params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams + *png_sizeof(png_charp))) ; + if (params == NULL) + { + png_free(png_ptr, purpose); + png_warning(png_ptr, "No memory for pCAL params."); + return; + } + + /* Get pointers to the start of each parameter string. */ + for (i = 0; i < (int)nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d\n", i); + for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { + png_warning(png_ptr, "Invalid pCAL data"); + png_free(png_ptr, purpose); + png_free(png_ptr, params); + return; + } + } + + png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams, + units, params); + + png_free(png_ptr, purpose); + png_free(png_ptr, params); +} +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +/* read the sCAL chunk */ +void /* PRIVATE */ +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_charp buffer, ep; +#ifdef PNG_FLOATING_POINT_SUPPORTED + double width, height; + png_charp vp; +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_charp swidth, sheight; +#endif +#endif + png_size_t slength; + + png_debug(1, "in png_handle_sCAL\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) + { + png_warning(png_ptr, "Duplicate sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", + length + 1); + buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (buffer == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)buffer, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, buffer); + return; + } + + buffer[slength] = 0x00; /* null terminate the last string */ + + ep = buffer + 1; /* skip unit byte */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED + width = png_strtod(png_ptr, ep, &vp); + if (*vp) + { + png_warning(png_ptr, "malformed width string in sCAL chunk"); + return; + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); + return; + } + png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); +#endif +#endif + + for (ep = buffer; *ep; ep++) + /* empty loop */ ; + ep++; + +#ifdef PNG_FLOATING_POINT_SUPPORTED + height = png_strtod(png_ptr, ep, &vp); + if (*vp) + { + png_warning(png_ptr, "malformed height string in sCAL chunk"); + return; + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); + return; + } + png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); +#endif +#endif + + if (buffer + slength < ep +#ifdef PNG_FLOATING_POINT_SUPPORTED + || width <= 0. || height <= 0. +#endif + ) + { + png_warning(png_ptr, "Invalid sCAL data"); + png_free(png_ptr, buffer); +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, swidth); + png_free(png_ptr, sheight); +#endif + return; + } + + +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight); +#endif +#endif + + png_free(png_ptr, buffer); +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, swidth); + png_free(png_ptr, sheight); +#endif +} +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +void /* PRIVATE */ +png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_byte buf[7]; + png_time mod_time; + + png_debug(1, "in png_handle_tIME\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Out of place tIME chunk"); + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) + { + png_warning(png_ptr, "Duplicate tIME chunk"); + png_crc_finish(png_ptr, length); + return; + } + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + + if (length != 7) + { + png_warning(png_ptr, "Incorrect tIME chunk length"); + png_crc_finish(png_ptr, length); + return; + } + + png_crc_read(png_ptr, buf, 7); + if (png_crc_finish(png_ptr, 0)) + return; + + mod_time.second = buf[6]; + mod_time.minute = buf[5]; + mod_time.hour = buf[4]; + mod_time.day = buf[3]; + mod_time.month = buf[2]; + mod_time.year = png_get_uint_16(buf); + + png_set_tIME(png_ptr, info_ptr, &mod_time); +} +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp key; + png_charp text; + png_uint_32 skip = 0; + png_size_t slength; + int ret; + + png_debug(1, "in png_handle_tEXt\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before tEXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + key = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (key == NULL) + { + png_warning(png_ptr, "No memory to process text chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)key, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, key); + return; + } + + key[slength] = 0x00; + + for (text = key; *text; text++) + /* empty loop to find end of key */ ; + + if (text != key + slength) + text++; + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process text chunk."); + png_free(png_ptr, key); + return; + } + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->key = key; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; +#endif + text_ptr->text = text; + text_ptr->text_length = png_strlen(text); + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, key); + png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to process text chunk."); +} +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +/* note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp chunkdata; + png_charp text; + int comp_type; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_zTXt\n"); + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before zTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + there is no hard and fast rule to tell us where to stop. */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr,"zTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr,"Out of memory processing zTXt chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (text = chunkdata; *text; text++) + /* empty loop */ ; + + /* zTXt must have some text after the chunkdataword */ + if (text == chunkdata + slength) + { + comp_type = PNG_TEXT_COMPRESSION_NONE; + png_warning(png_ptr, "Zero length zTXt chunk"); + } + else + { + comp_type = *(++text); + if (comp_type != PNG_TEXT_COMPRESSION_zTXt) + { + png_warning(png_ptr, "Unknown compression type in zTXt chunk"); + comp_type = PNG_TEXT_COMPRESSION_zTXt; + } + text++; /* skip the compression_method byte */ + } + prefix_len = text - chunkdata; + + chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, + (png_size_t)length, prefix_len, &data_len); + + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process zTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } + text_ptr->compression = comp_type; + text_ptr->key = chunkdata; +#ifdef PNG_iTXt_SUPPORTED + text_ptr->lang = NULL; + text_ptr->lang_key = NULL; + text_ptr->itxt_length = 0; +#endif + text_ptr->text = chunkdata + prefix_len; + text_ptr->text_length = data_len; + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store zTXt chunk."); +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +/* note: this does not correctly handle chunks that are > 64K under DOS */ +void /* PRIVATE */ +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp chunkdata; + png_charp key, lang, text, lang_key; + int comp_flag; + int comp_type = 0; + int ret; + png_size_t slength, prefix_len, data_len; + + png_debug(1, "in png_handle_iTXt\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + there is no hard and fast rule to tell us where to stop. */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr,"iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process iTXt chunk."); + return; + } + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (lang = chunkdata; *lang; lang++) + /* empty loop */ ; + lang++; /* skip NUL separator */ + + /* iTXt must have a language tag (possibly empty), two compression bytes, + translated keyword (possibly empty), and possibly some text after the + keyword */ + + if (lang >= chunkdata + slength) + { + comp_flag = PNG_TEXT_COMPRESSION_NONE; + png_warning(png_ptr, "Zero length iTXt chunk"); + } + else + { + comp_flag = *lang++; + comp_type = *lang++; + } + + for (lang_key = lang; *lang_key; lang_key++) + /* empty loop */ ; + lang_key++; /* skip NUL separator */ + + for (text = lang_key; *text; text++) + /* empty loop */ ; + text++; /* skip NUL separator */ + + prefix_len = text - chunkdata; + + key=chunkdata; + if (comp_flag) + chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, + (size_t)length, prefix_len, &data_len); + else + data_len=png_strlen(chunkdata + prefix_len); + text_ptr = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)png_sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process iTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } + text_ptr->compression = (int)comp_flag + 1; + text_ptr->lang_key = chunkdata+(lang_key-key); + text_ptr->lang = chunkdata+(lang-key); + text_ptr->itxt_length = data_len; + text_ptr->text_length = 0; + text_ptr->key = chunkdata; + text_ptr->text = chunkdata + prefix_len; + + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store iTXt chunk."); +} +#endif + +/* This function is called when we haven't found a handler for a + chunk. If there isn't a problem with the chunk itself (ie bad + chunk name, CRC, or a critical chunk), the chunk is silently ignored + -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which + case it will be saved away to be written out later. */ +void /* PRIVATE */ +png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_uint_32 skip = 0; + + png_debug(1, "in png_handle_unknown\n"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ + png_ptr->mode |= PNG_AFTER_IDAT; + } + + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + + if (!(png_ptr->chunk_name[0] & 0x20)) + { +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + && png_ptr->read_user_chunk_fn == NULL +#endif + ) +#endif + png_chunk_error(png_ptr, "unknown critical chunk"); + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) || + (png_ptr->read_user_chunk_fn != NULL)) + { +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + png_strcpy((png_charp)png_ptr->unknown_chunk.name, + (png_charp)png_ptr->chunk_name); + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); + png_ptr->unknown_chunk.size = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if(png_ptr->read_user_chunk_fn != NULL) + { + /* callback to user unknown chunk handler */ + int ret; + ret = (*(png_ptr->read_user_chunk_fn)) + (png_ptr, &png_ptr->unknown_chunk); + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + if (ret == 0) + { + if (!(png_ptr->chunk_name[0] & 0x20)) + if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) + png_chunk_error(png_ptr, "unknown critical chunk"); + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } +#else + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); +#endif + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + else +#endif + skip = length; + + png_crc_finish(png_ptr, skip); + +#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) + if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ + return; +#endif +} + +/* This function is called to verify that a chunk name is valid. + This function can't have the "critical chunk check" incorporated + into it, since in the future we will need to be able to call user + functions to handle unknown critical chunks after we check that + the chunk name itself is valid. */ + +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + +void /* PRIVATE */ +png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) +{ + png_debug(1, "in png_check_chunk_name\n"); + if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || + isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) + { + png_chunk_error(png_ptr, "invalid chunk type"); + } +} + +/* Combines the row recently read in with the existing pixels in the + row. This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined, + a zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. If + you want all pixels to be combined, pass 0xff (255) in mask. */ +#ifndef PNG_HAVE_MMX_COMBINE_ROW +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ + png_debug(1,"in png_combine_row\n"); + if (mask == 0xff) + { + png_memcpy(row, png_ptr->row_buf + 1, + PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); + } + else + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_inc, s_start, s_end; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x01; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + case 2: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_start, s_end, s_inc; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + int value; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x03; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + case 4: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + int s_start, s_end, s_inc; + int m = 0x80; + int shift; + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + int value; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + default: + { + png_bytep sp = png_ptr->row_buf + 1; + png_bytep dp = row; + png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + png_uint_32 i; + png_uint_32 row_width = png_ptr->width; + png_byte m = 0x80; + + + for (i = 0; i < row_width; i++) + { + if (m & mask) + { + png_memcpy(dp, sp, pixel_bytes); + } + + sp += pixel_bytes; + dp += pixel_bytes; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + } + } +} +#endif /* !PNG_HAVE_MMX_COMBINE_ROW */ + +#ifdef PNG_READ_INTERLACING_SUPPORTED +#ifndef PNG_HAVE_MMX_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */ +/* OLD pre-1.0.9 interface: +void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations) + */ +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; + png_uint_32 transformations = png_ptr->transformations; +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_do_read_interlace (stock C version)\n"); + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_byte v; + png_uint_32 i; + int j; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 0x07); + dshift = (int)((final_width + 7) & 0x07); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 0x07); + dshift = 7 - (int)((final_width + 7) & 0x07); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = 0; i < row_info->width; i++) + { + v = (png_byte)((*sp >> sshift) & 0x01); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + case 2: + { + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); + int sshift, dshift; + int s_start, s_end, s_inc; + int jstop = png_pass_inc[pass]; + png_uint_32 i; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 3) & 0x03) << 1); + dshift = (int)(((final_width + 3) & 0x03) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); + dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x03); + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + case 4: + { + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); + png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + int jstop = png_pass_inc[pass]; + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)(((row_info->width + 1) & 0x01) << 2); + dshift = (int)(((final_width + 1) & 0x01) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); + dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v = (png_byte)((*sp >> sshift) & 0xf); + int j; + + for (j = 0; j < jstop; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + default: + { + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); + png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; + + int jstop = png_pass_inc[pass]; + png_uint_32 i; + + for (i = 0; i < row_info->width; i++) + { + png_byte v[8]; + int j; + + png_memcpy(v, sp, pixel_bytes); + for (j = 0; j < jstop; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sp -= pixel_bytes; + } + break; + } + } + row_info->width = final_width; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } +#if !defined(PNG_READ_PACKSWAP_SUPPORTED) + if (&transformations == NULL) /* silence compiler warning */ + return; +#endif +} +#endif /* !PNG_HAVE_MMX_READ_INTERLACE */ +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + +#ifndef PNG_HAVE_MMX_READ_FILTER_ROW +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, + png_bytep prev_row, int filter) +{ + png_debug(1, "in png_read_filter_row\n"); + png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter); + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + case PNG_FILTER_VALUE_SUB: + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_UP: + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_AVG: + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *lp++) / 2 ) & 0xff); + rp++; + } + break; + } + case PNG_FILTER_VALUE_PAETH: + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop=row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) /* use leftover rp,pp */ + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + 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 + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + break; + } + default: + png_warning(png_ptr, "Ignoring bad adaptive filter type"); + *row=0; + break; + } +} +#endif /* !PNG_HAVE_MMX_READ_FILTER_ROW */ + +void /* PRIVATE */ +png_read_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_debug(1, "in png_read_finish_row\n"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + do + { + png_ptr->pass++; + if (png_ptr->pass >= 7) + break; + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (!(png_ptr->num_rows)) + continue; + } + else /* if (png_ptr->transformations & PNG_INTERLACE) */ + break; + } while (png_ptr->iwidth == 0); + + if (png_ptr->pass < 7) + return; + } + + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + char extra; + int ret; + + png_ptr->zstream.next_out = (Byte *)&extra; + png_ptr->zstream.avail_out = (uInt)1; + for(;;) + { + if (!(png_ptr->zstream.avail_in)) + { + while (!png_ptr->idat_size) + { + png_byte chunk_length[4]; + + png_crc_finish(png_ptr, 0); + + png_read_data(png_ptr, chunk_length, 4); + png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, png_ptr->chunk_name, 4); + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); + + } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); + png_ptr->idat_size -= png_ptr->zstream.avail_in; + } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) + { + if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || + png_ptr->idat_size) + png_warning(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + if (ret != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : + "Decompression Error"); + + if (!(png_ptr->zstream.avail_out)) + { + png_warning(png_ptr, "Extra compressed data."); + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + break; + } + + } + png_ptr->zstream.avail_out = 0; + } + + if (png_ptr->idat_size || png_ptr->zstream.avail_in) + png_warning(png_ptr, "Extra compression data"); + + inflateReset(&png_ptr->zstream); + + png_ptr->mode |= PNG_AFTER_IDAT; +} + +void /* PRIVATE */ +png_read_start_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int max_pixel_depth; + png_uint_32 row_bytes; + + png_debug(1, "in png_read_start_row\n"); + png_ptr->zstream.avail_in = 0; + png_init_read_transformations(png_ptr); + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + else + png_ptr->num_rows = png_ptr->height; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; + + png_ptr->irowbytes = (png_size_t)row_bytes; + if((png_uint_32)png_ptr->irowbytes != row_bytes) + png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); + } + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; + png_ptr->irowbytes = png_ptr->rowbytes + 1; + } + max_pixel_depth = png_ptr->pixel_depth; + +#if defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) + max_pixel_depth = 8; +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) + if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans) + max_pixel_depth = 32; + else + max_pixel_depth = 24; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth < 8) + max_pixel_depth = 8; + if (png_ptr->num_trans) + max_pixel_depth *= 2; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (png_ptr->num_trans) + { + max_pixel_depth *= 4; + max_pixel_depth /= 3; + } + } + } +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & (PNG_FILLER)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + max_pixel_depth = 32; + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth <= 8) + max_pixel_depth = 16; + else + max_pixel_depth = 32; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; + else + max_pixel_depth = 64; + } + } +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + { + if ( +#if defined(PNG_READ_EXPAND_SUPPORTED) + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || +#endif +#if defined(PNG_READ_FILLER_SUPPORTED) + (png_ptr->transformations & (PNG_FILLER)) || +#endif + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (max_pixel_depth <= 16) + max_pixel_depth = 32; + else + max_pixel_depth = 64; + } + else + { + if (max_pixel_depth <= 8) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 32; + else + max_pixel_depth = 24; + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 64; + else + max_pixel_depth = 48; + } + } +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if(png_ptr->transformations & PNG_USER_TRANSFORM) + { + int user_pixel_depth=png_ptr->user_transform_depth* + png_ptr->user_transform_channels; + if(user_pixel_depth > max_pixel_depth) + max_pixel_depth=user_pixel_depth; + } +#endif + + /* align the width on the next larger 8 pixels. Mainly used + for interlacing */ + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); + /* calculate the maximum bytes needed, adding a byte and a pixel + for safety's sake */ + row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) + + 1 + ((max_pixel_depth + 7) >> 3); +#ifdef PNG_MAX_MALLOC_64K + if (row_bytes > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); + png_ptr->row_buf = png_ptr->big_row_buf+32; +#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) + png_ptr->row_buf_size = row_bytes; +#endif + +#ifdef PNG_MAX_MALLOC_64K + if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory."); + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( + png_ptr->rowbytes + 1)); + + png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %lu,\n", png_ptr->width); + png_debug1(3, "height = %lu,\n", png_ptr->height); + png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); + png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); + png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); + png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* PNG_READ_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngset.c b/src/dep/src/irrlicht/libpng/pngset.c new file mode 100644 index 0000000..9cf6150 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngset.c @@ -0,0 +1,1271 @@ + +/* pngset.c - storage of image information into info struct + * + * Last changed in libpng 1.2.17 May 15, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + * + * The functions here are used during reads to store data from the file + * into the info struct, and during writes to store application data + * into the info struct for writing into the file. This abstracts the + * info struct and allows us to change the structure in the future. + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#if defined(PNG_bKGD_SUPPORTED) +void PNGAPI +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) +{ + png_debug1(1, "in %s storage function\n", "bKGD"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); + info_ptr->valid |= PNG_INFO_bKGD; +} +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) +{ + png_debug1(1, "in %s storage function\n", "cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (white_x < 0.0 || white_y < 0.0 || + red_x < 0.0 || red_y < 0.0 || + green_x < 0.0 || green_y < 0.0 || + blue_x < 0.0 || blue_y < 0.0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } + if (white_x > 21474.83 || white_y > 21474.83 || + red_x > 21474.83 || red_y > 21474.83 || + green_x > 21474.83 || green_y > 21474.83 || + blue_x > 21474.83 || blue_y > 21474.83) + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } + + info_ptr->x_white = (float)white_x; + info_ptr->y_white = (float)white_y; + info_ptr->x_red = (float)red_x; + info_ptr->y_red = (float)red_y; + info_ptr->x_green = (float)green_x; + info_ptr->y_green = (float)green_y; + info_ptr->x_blue = (float)blue_x; + info_ptr->y_blue = (float)blue_y; +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); + info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); + info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); + info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); + info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); + info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); + info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); + info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); +#endif + info_ptr->valid |= PNG_INFO_cHRM; +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) +{ + png_debug1(1, "in %s storage function\n", "cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (white_x < 0 || white_y < 0 || + red_x < 0 || red_y < 0 || + green_x < 0 || green_y < 0 || + blue_x < 0 || blue_y < 0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } +#ifdef PNG_FLOATING_POINT_SUPPORTED + if (white_x > (double) PNG_UINT_31_MAX || + white_y > (double) PNG_UINT_31_MAX || + red_x > (double) PNG_UINT_31_MAX || + red_y > (double) PNG_UINT_31_MAX || + green_x > (double) PNG_UINT_31_MAX || + green_y > (double) PNG_UINT_31_MAX || + blue_x > (double) PNG_UINT_31_MAX || + blue_y > (double) PNG_UINT_31_MAX) +#else + if (white_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + white_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + red_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + red_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + green_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + green_y > (png_fixed_point) PNG_UINT_31_MAX/100000L || + blue_x > (png_fixed_point) PNG_UINT_31_MAX/100000L || + blue_y > (png_fixed_point) PNG_UINT_31_MAX/100000L) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } + info_ptr->int_x_white = white_x; + info_ptr->int_y_white = white_y; + info_ptr->int_x_red = red_x; + info_ptr->int_y_red = red_y; + info_ptr->int_x_green = green_x; + info_ptr->int_y_green = green_y; + info_ptr->int_x_blue = blue_x; + info_ptr->int_y_blue = blue_y; +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->x_white = (float)(white_x/100000.); + info_ptr->y_white = (float)(white_y/100000.); + info_ptr->x_red = (float)( red_x/100000.); + info_ptr->y_red = (float)( red_y/100000.); + info_ptr->x_green = (float)(green_x/100000.); + info_ptr->y_green = (float)(green_y/100000.); + info_ptr->x_blue = (float)( blue_x/100000.); + info_ptr->y_blue = (float)( blue_y/100000.); +#endif + info_ptr->valid |= PNG_INFO_cHRM; +} +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) +{ + double gamma; + png_debug1(1, "in %s storage function\n", "gAMA"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Check for overflow */ + if (file_gamma > 21474.83) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=21474.83; + } + else + gamma=file_gamma; + info_ptr->gamma = (float)gamma; +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = (int)(gamma*100000.+.5); +#endif + info_ptr->valid |= PNG_INFO_gAMA; + if(gamma == 0.0) + png_warning(png_ptr, "Setting gamma=0"); +} +#endif +void PNGAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + int_gamma) +{ + png_fixed_point gamma; + + png_debug1(1, "in %s storage function\n", "gAMA"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=PNG_UINT_31_MAX; + } + else + { + if (int_gamma < 0) + { + png_warning(png_ptr, "Setting negative gamma to zero"); + gamma=0; + } + else + gamma=int_gamma; + } +#ifdef PNG_FLOATING_POINT_SUPPORTED + info_ptr->gamma = (float)(gamma/100000.); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + info_ptr->int_gamma = gamma; +#endif + info_ptr->valid |= PNG_INFO_gAMA; + if(gamma == 0) + png_warning(png_ptr, "Setting gamma=0"); +} +#endif + +#if defined(PNG_hIST_SUPPORTED) +void PNGAPI +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) +{ + int i; + + png_debug1(1, "in %s storage function\n", "hIST"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if (info_ptr->num_palette <= 0 || info_ptr->num_palette + > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, + "Invalid palette size, hIST allocation skipped."); + return; + } + +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); +#endif + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version + 1.2.1 */ + png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, + (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof (png_uint_16))); + if (png_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data."); + return; + } + + for (i = 0; i < info_ptr->num_palette; i++) + png_ptr->hist[i] = hist[i]; + info_ptr->hist = png_ptr->hist; + info_ptr->valid |= PNG_INFO_hIST; + +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_HIST; +#else + png_ptr->flags |= PNG_FLAG_FREE_HIST; +#endif +} +#endif + +void PNGAPI +png_set_IHDR(png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + png_debug1(1, "in %s storage function\n", "IHDR"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* check for width and height valid values */ + if (width == 0 || height == 0) + png_error(png_ptr, "Image width or height is zero in IHDR"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max || height > png_ptr->user_height_max) + png_error(png_ptr, "image size exceeds user limits in IHDR"); +#else + if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) + png_error(png_ptr, "image size exceeds user limits in IHDR"); +#endif + if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX) + png_error(png_ptr, "Invalid image size in IHDR"); + if ( width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + png_warning(png_ptr, "Width is too large for libpng to process pixels"); + + /* check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && + bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth in IHDR"); + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + png_error(png_ptr, "Invalid color type in IHDR"); + + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || + ((color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) + png_error(png_ptr, "Invalid color type/bit depth combination in IHDR"); + + if (interlace_type >= PNG_INTERLACE_LAST) + png_error(png_ptr, "Unknown interlace method in IHDR"); + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_error(png_ptr, "Unknown compression method in IHDR"); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + /* Accept filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not read a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) + png_warning(png_ptr,"MNG features are not allowed in a PNG datastream"); + if(filter_type != PNG_FILTER_TYPE_BASE) + { + if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + png_error(png_ptr, "Unknown filter method in IHDR"); + if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) + png_warning(png_ptr, "Invalid filter method in IHDR"); + } +#else + if(filter_type != PNG_FILTER_TYPE_BASE) + png_error(png_ptr, "Unknown filter method in IHDR"); +#endif + + info_ptr->width = width; + info_ptr->height = height; + info_ptr->bit_depth = (png_byte)bit_depth; + info_ptr->color_type =(png_byte) color_type; + info_ptr->compression_type = (png_byte)compression_type; + info_ptr->filter_type = (png_byte)filter_type; + info_ptr->interlace_type = (png_byte)interlace_type; + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + else + info_ptr->channels = 1; + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); + + /* check for potential overflow */ + if ( width > (PNG_UINT_32_MAX + >> 3) /* 8-byte RGBA pixels */ + - 64 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ + info_ptr->rowbytes = (png_size_t)0; + else + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width); +} + +#if defined(PNG_oFFs_SUPPORTED) +void PNGAPI +png_set_oFFs(png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type) +{ + png_debug1(1, "in %s storage function\n", "oFFs"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_offset = offset_x; + info_ptr->y_offset = offset_y; + info_ptr->offset_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_oFFs; +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +void PNGAPI +png_set_pCAL(png_structp png_ptr, png_infop info_ptr, + png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params) +{ + png_uint_32 length; + int i; + + png_debug1(1, "in %s storage function\n", "pCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + length = png_strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)\n", length); + info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_purpose == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose."); + return; + } + png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); + + png_debug(3, "storing X0, X1, type, and nparams in info\n"); + info_ptr->pcal_X0 = X0; + info_ptr->pcal_X1 = X1; + info_ptr->pcal_type = (png_byte)type; + info_ptr->pcal_nparams = (png_byte)nparams; + + length = png_strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)\n", length); + info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units."); + return; + } + png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); + + info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, + (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params."); + return; + } + + info_ptr->pcal_params[nparams] = NULL; + + for (i = 0; i < nparams; i++) + { + length = png_strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length); + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_params[i] == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL parameter."); + return; + } + png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); + } + + info_ptr->valid |= PNG_INFO_pCAL; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_PCAL; +#endif +} +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height) +{ + png_debug1(1, "in %s storage function\n", "sCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->scal_unit = (png_byte)unit; + info_ptr->scal_pixel_width = width; + info_ptr->scal_pixel_height = height; + + info_ptr->valid |= PNG_INFO_sCAL; +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, + int unit, png_charp swidth, png_charp sheight) +{ + png_uint_32 length; + + png_debug1(1, "in %s storage function\n", "sCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->scal_unit = (png_byte)unit; + + length = png_strlen(swidth) + 1; + png_debug1(3, "allocating unit for info (%d bytes)\n", length); + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->scal_s_width == NULL) + { + png_warning(png_ptr, "Memory allocation failed while processing sCAL."); + } + png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); + + length = png_strlen(sheight) + 1; + png_debug1(3, "allocating unit for info (%d bytes)\n", length); + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->scal_s_height == NULL) + { + png_free (png_ptr, info_ptr->scal_s_width); + png_warning(png_ptr, "Memory allocation failed while processing sCAL."); + } + png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); + + info_ptr->valid |= PNG_INFO_sCAL; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_SCAL; +#endif +} +#endif +#endif +#endif + +#if defined(PNG_pHYs_SUPPORTED) +void PNGAPI +png_set_pHYs(png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type) +{ + png_debug1(1, "in %s storage function\n", "pHYs"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_pixels_per_unit = res_x; + info_ptr->y_pixels_per_unit = res_y; + info_ptr->phys_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_pHYs; +} +#endif + +void PNGAPI +png_set_PLTE(png_structp png_ptr, png_infop info_ptr, + png_colorp palette, int num_palette) +{ + + png_debug1(1, "in %s storage function\n", "PLTE"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Invalid palette length"); + else + { + png_warning(png_ptr, "Invalid palette length"); + return; + } + } + + /* + * It may not actually be necessary to set png_ptr->palette here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); +#endif + + /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead + of num_palette entries, + in case of an invalid PNG file that has too-large sample values. */ + png_ptr->palette = (png_colorp)png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH * + png_sizeof(png_color)); + png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color)); + info_ptr->palette = png_ptr->palette; + info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; + +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_PLTE; +#else + png_ptr->flags |= PNG_FLAG_FREE_PLTE; +#endif + + info_ptr->valid |= PNG_INFO_PLTE; +} + +#if defined(PNG_sBIT_SUPPORTED) +void PNGAPI +png_set_sBIT(png_structp png_ptr, png_infop info_ptr, + png_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function\n", "sBIT"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8)); + info_ptr->valid |= PNG_INFO_sBIT; +} +#endif + +#if defined(PNG_sRGB_SUPPORTED) +void PNGAPI +png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) +{ + png_debug1(1, "in %s storage function\n", "sRGB"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->srgb_intent = (png_byte)intent; + info_ptr->valid |= PNG_INFO_sRGB; +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, + int intent) +{ +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + float file_gamma; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point int_file_gamma; +#endif +#endif +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, + int_green_y, int_blue_x, int_blue_y; +#endif +#endif + png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_set_sRGB(png_ptr, info_ptr, intent); + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + file_gamma = (float).45455; + png_set_gAMA(png_ptr, info_ptr, file_gamma); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + int_file_gamma = 45455L; + png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FIXED_POINT_SUPPORTED + int_white_x = 31270L; + int_white_y = 32900L; + int_red_x = 64000L; + int_red_y = 33000L; + int_green_x = 30000L; + int_green_y = 60000L; + int_blue_x = 15000L; + int_blue_y = 6000L; + + png_set_cHRM_fixed(png_ptr, info_ptr, + int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y, + int_blue_x, int_blue_y); +#endif +#ifdef PNG_FLOATING_POINT_SUPPORTED + white_x = (float).3127; + white_y = (float).3290; + red_x = (float).64; + red_y = (float).33; + green_x = (float).30; + green_y = (float).60; + blue_x = (float).15; + blue_y = (float).06; + + png_set_cHRM(png_ptr, info_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); +#endif +#endif +} +#endif + + +#if defined(PNG_iCCP_SUPPORTED) +void PNGAPI +png_set_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen) +{ + png_charp new_iccp_name; + png_charp new_iccp_profile; + + png_debug1(1, "in %s storage function\n", "iCCP"); + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1); + if (new_iccp_name == NULL) + { + png_warning(png_ptr, "Insufficient memory to process iCCP chunk."); + return; + } + png_strcpy(new_iccp_name, name); + new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); + if (new_iccp_profile == NULL) + { + png_free (png_ptr, new_iccp_name); + png_warning(png_ptr, "Insufficient memory to process iCCP profile."); + return; + } + png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); + + info_ptr->iccp_proflen = proflen; + info_ptr->iccp_name = new_iccp_name; + info_ptr->iccp_profile = new_iccp_profile; + /* Compression is always zero but is here so the API and info structure + * does not have to change if we introduce multiple compression types */ + info_ptr->iccp_compression = (png_byte)compression_type; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_ICCP; +#endif + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) +void PNGAPI +png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, + int num_text) +{ + int ret; + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + if (ret) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, + int num_text) +{ + int i; + + png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ? + "text" : (png_const_charp)png_ptr->chunk_name)); + + if (png_ptr == NULL || info_ptr == NULL || num_text == 0) + return(0); + + /* Make sure we have enough space in the "text" array in info_struct + * to hold all of the incoming text_ptr objects. + */ + if (info_ptr->num_text + num_text > info_ptr->max_text) + { + if (info_ptr->text != NULL) + { + png_textp old_text; + int old_max; + + old_max = info_ptr->max_text; + info_ptr->max_text = info_ptr->num_text + num_text + 8; + old_text = info_ptr->text; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + if (info_ptr->text == NULL) + { + png_free(png_ptr, old_text); + return(1); + } + png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * + png_sizeof(png_text))); + png_free(png_ptr, old_text); + } + else + { + info_ptr->max_text = num_text + 8; + info_ptr->num_text = 0; + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, + (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + if (info_ptr->text == NULL) + return(1); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_TEXT; +#endif + } + png_debug1(3, "allocated %d entries for info_ptr->text\n", + info_ptr->max_text); + } + for (i = 0; i < num_text; i++) + { + png_size_t text_length,key_len; + png_size_t lang_len,lang_key_len; + png_textp textp = &(info_ptr->text[info_ptr->num_text]); + + if (text_ptr[i].key == NULL) + continue; + + key_len = png_strlen(text_ptr[i].key); + + if(text_ptr[i].compression <= 0) + { + lang_len = 0; + lang_key_len = 0; + } + else +#ifdef PNG_iTXt_SUPPORTED + { + /* set iTXt data */ + if (text_ptr[i].lang != NULL) + lang_len = png_strlen(text_ptr[i].lang); + else + lang_len = 0; + if (text_ptr[i].lang_key != NULL) + lang_key_len = png_strlen(text_ptr[i].lang_key); + else + lang_key_len = 0; + } +#else + { + png_warning(png_ptr, "iTXt chunk not supported."); + continue; + } +#endif + + if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') + { + text_length = 0; +#ifdef PNG_iTXt_SUPPORTED + if(text_ptr[i].compression > 0) + textp->compression = PNG_ITXT_COMPRESSION_NONE; + else +#endif + textp->compression = PNG_TEXT_COMPRESSION_NONE; + } + else + { + text_length = png_strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + + textp->key = (png_charp)png_malloc_warn(png_ptr, + (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4)); + if (textp->key == NULL) + return(1); + png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n", + (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4), + (int)textp->key); + + png_memcpy(textp->key, text_ptr[i].key, + (png_size_t)(key_len)); + *(textp->key+key_len) = '\0'; +#ifdef PNG_iTXt_SUPPORTED + if (text_ptr[i].compression > 0) + { + textp->lang=textp->key + key_len + 1; + png_memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang+lang_len) = '\0'; + textp->lang_key=textp->lang + lang_len + 1; + png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + *(textp->lang_key+lang_key_len) = '\0'; + textp->text=textp->lang_key + lang_key_len + 1; + } + else +#endif + { +#ifdef PNG_iTXt_SUPPORTED + textp->lang=NULL; + textp->lang_key=NULL; +#endif + textp->text=textp->key + key_len + 1; + } + if(text_length) + png_memcpy(textp->text, text_ptr[i].text, + (png_size_t)(text_length)); + *(textp->text+text_length) = '\0'; + +#ifdef PNG_iTXt_SUPPORTED + if(textp->compression > 0) + { + textp->text_length = 0; + textp->itxt_length = text_length; + } + else +#endif + { + textp->text_length = text_length; +#ifdef PNG_iTXt_SUPPORTED + textp->itxt_length = 0; +#endif + } +#if 0 /* appears to be redundant; */ + info_ptr->text[info_ptr->num_text]= *textp; +#endif + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text); + } + return(0); +} +#endif + +#if defined(PNG_tIME_SUPPORTED) +void PNGAPI +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) +{ + png_debug1(1, "in %s storage function\n", "tIME"); + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_tIME)) + return; + + png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time)); + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#if defined(PNG_tRNS_SUPPORTED) +void PNGAPI +png_set_tRNS(png_structp png_ptr, png_infop info_ptr, + png_bytep trans, int num_trans, png_color_16p trans_values) +{ + png_debug1(1, "in %s storage function\n", "tRNS"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (trans != NULL) + { + /* + * It may not actually be necessary to set png_ptr->trans here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ +#ifdef PNG_FREE_ME_SUPPORTED + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); +#endif + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, + (png_uint_32)PNG_MAX_PALETTE_LENGTH); + if (num_trans <= PNG_MAX_PALETTE_LENGTH) + png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_TRNS; +#else + png_ptr->flags |= PNG_FLAG_FREE_TRNS; +#endif + } + + if (trans_values != NULL) + { + png_memcpy(&(info_ptr->trans_values), trans_values, + png_sizeof(png_color_16)); + if (num_trans == 0) + num_trans = 1; + } + info_ptr->num_trans = (png_uint_16)num_trans; + info_ptr->valid |= PNG_INFO_tRNS; +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +void PNGAPI +png_set_sPLT(png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries) +{ + png_sPLT_tp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL) + return; + + np = (png_sPLT_tp)png_malloc_warn(png_ptr, + (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t)); + if (np == NULL) + { + png_warning(png_ptr, "No memory for sPLT palettes."); + return; + } + + png_memcpy(np, info_ptr->splt_palettes, + info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes=NULL; + + for (i = 0; i < nentries; i++) + { + png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; + png_sPLT_tp from = entries + i; + + to->name = (png_charp)png_malloc(png_ptr, + png_strlen(from->name) + 1); + /* TODO: use png_malloc_warn */ + png_strcpy(to->name, from->name); + to->entries = (png_sPLT_entryp)png_malloc(png_ptr, + from->nentries * png_sizeof(png_sPLT_entry)); + /* TODO: use png_malloc_warn */ + png_memcpy(to->entries, from->entries, + from->nentries * png_sizeof(png_sPLT_entry)); + to->nentries = from->nentries; + to->depth = from->depth; + } + + info_ptr->splt_palettes = np; + info_ptr->splt_palettes_num += nentries; + info_ptr->valid |= PNG_INFO_sPLT; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_SPLT; +#endif +} +#endif /* PNG_sPLT_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +void PNGAPI +png_set_unknown_chunks(png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) +{ + png_unknown_chunkp np; + int i; + + if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) + return; + + np = (png_unknown_chunkp)png_malloc_warn(png_ptr, + (info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk)); + if (np == NULL) + { + png_warning(png_ptr, "Out of memory while processing unknown chunk."); + return; + } + + png_memcpy(np, info_ptr->unknown_chunks, + info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks=NULL; + + for (i = 0; i < num_unknowns; i++) + { + png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; + png_unknown_chunkp from = unknowns + i; + + png_strncpy((png_charp)to->name, (png_charp)from->name, 5); + to->data = (png_bytep)png_malloc_warn(png_ptr, from->size); + if (to->data == NULL) + { + png_warning(png_ptr, "Out of memory processing unknown chunk."); + } + else + { + png_memcpy(to->data, from->data, from->size); + to->size = from->size; + + /* note our location in the read or write sequence */ + to->location = (png_byte)(png_ptr->mode & 0xff); + } + } + + info_ptr->unknown_chunks = np; + info_ptr->unknown_chunks_num += num_unknowns; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_UNKN; +#endif +} +void PNGAPI +png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, + int chunk, int location) +{ + if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < + (int)info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks[chunk].location = (png_byte)location; +} +#endif + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +void PNGAPI +png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) +{ + /* This function is deprecated in favor of png_permit_mng_features() + and will be removed from libpng-1.3.0 */ + png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n"); + if (png_ptr == NULL) + return; + png_ptr->mng_features_permitted = (png_byte) + ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) | + ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); +} +#endif +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +png_uint_32 PNGAPI +png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) +{ + png_debug(1, "in png_permit_mng_features\n"); + if (png_ptr == NULL) + return (png_uint_32)0; + png_ptr->mng_features_permitted = + (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + return (png_uint_32)png_ptr->mng_features_permitted; +} +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +void PNGAPI +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep + chunk_list, int num_chunks) +{ + png_bytep new_list, p; + int i, old_num_chunks; + if (png_ptr == NULL) + return; + if (num_chunks == 0) + { + if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) + png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + + if(keep == PNG_HANDLE_CHUNK_ALWAYS) + png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; + else + png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; + return; + } + if (chunk_list == NULL) + return; + old_num_chunks=png_ptr->num_chunk_list; + new_list=(png_bytep)png_malloc(png_ptr, + (png_uint_32)(5*(num_chunks+old_num_chunks))); + if(png_ptr->chunk_list != NULL) + { + png_memcpy(new_list, png_ptr->chunk_list, + (png_size_t)(5*old_num_chunks)); + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + } + png_memcpy(new_list+5*old_num_chunks, chunk_list, + (png_size_t)(5*num_chunks)); + for (p=new_list+5*old_num_chunks+4, i=0; inum_chunk_list=old_num_chunks+num_chunks; + png_ptr->chunk_list=new_list; +#ifdef PNG_FREE_ME_SUPPORTED + png_ptr->free_me |= PNG_FREE_LIST; +#endif +} +#endif + +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) +void PNGAPI +png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, + png_user_chunk_ptr read_user_chunk_fn) +{ + png_debug(1, "in png_set_read_user_chunk_fn\n"); + if (png_ptr == NULL) + return; + png_ptr->read_user_chunk_fn = read_user_chunk_fn; + png_ptr->user_chunk_ptr = user_chunk_ptr; +} +#endif + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) +{ + png_debug1(1, "in %s storage function\n", "rows"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + info_ptr->row_pointers = row_pointers; + if(row_pointers) + info_ptr->valid |= PNG_INFO_IDAT; +} +#endif + +#ifdef PNG_WRITE_SUPPORTED +void PNGAPI +png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size) +{ + if (png_ptr == NULL) + return; + if(png_ptr->zbuf) + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf_size = (png_size_t)size; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +} +#endif + +void PNGAPI +png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) +{ + if (png_ptr && info_ptr) + info_ptr->valid &= ~(mask); +} + + +#ifndef PNG_1_0_X +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* this function was added to libpng 1.2.0 and should always exist by default */ +void PNGAPI +png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) +{ +#ifdef PNG_MMX_CODE_SUPPORTED + png_uint_32 settable_asm_flags; + png_uint_32 settable_mmx_flags; +#endif + if (png_ptr == NULL) + return; +#ifdef PNG_MMX_CODE_SUPPORTED + + settable_mmx_flags = +#ifdef PNG_HAVE_MMX_COMBINE_ROW + PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | +#endif +#ifdef PNG_HAVE_MMX_READ_INTERLACE + PNG_ASM_FLAG_MMX_READ_INTERLACE | +#endif +#ifdef PNG_HAVE_MMX_READ_FILTER_ROW + PNG_ASM_FLAG_MMX_READ_FILTER_SUB | + PNG_ASM_FLAG_MMX_READ_FILTER_UP | + PNG_ASM_FLAG_MMX_READ_FILTER_AVG | + PNG_ASM_FLAG_MMX_READ_FILTER_PAETH | +#endif + 0; + + /* could be some non-MMX ones in the future, but not currently: */ + settable_asm_flags = settable_mmx_flags; + + if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) || + !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)) + { + /* clear all MMX flags if MMX isn't supported */ + settable_asm_flags &= ~settable_mmx_flags; + png_ptr->asm_flags &= ~settable_mmx_flags; + } + + /* we're replacing the settable bits with those passed in by the user, + * so first zero them out of the master copy, then bitwise-OR in the + * allowed subset that was requested */ + + png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ + png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ +#endif /* ?PNG_MMX_CODE_SUPPORTED */ +} + +/* this function was added to libpng 1.2.0 */ +void PNGAPI +png_set_mmx_thresholds (png_structp png_ptr, + png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold) +{ + if (png_ptr == NULL) + return; +#ifdef PNG_MMX_CODE_SUPPORTED + png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold; + png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; +#endif /* ?PNG_MMX_CODE_SUPPORTED */ +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* this function was added to libpng 1.2.6 */ +void PNGAPI +png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, + png_uint_32 user_height_max) +{ + /* Images with dimensions larger than these limits will be + * rejected by png_set_IHDR(). To accept any PNG datastream + * regardless of dimensions, set both limits to 0x7ffffffL. + */ + if(png_ptr == NULL) return; + png_ptr->user_width_max = user_width_max; + png_ptr->user_height_max = user_height_max; +} +#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ + +#endif /* ?PNG_1_0_X */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngtest.c b/src/dep/src/irrlicht/libpng/pngtest.c new file mode 100644 index 0000000..4f6d602 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngtest.c @@ -0,0 +1,1554 @@ + +/* pngtest.c - a simple test program to test libpng + * + * Last changed in libpng 1.2.6 - August 15, 2004 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2004 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 program reads in a PNG image, writes it out again, and then + * compares the two files. If the files are identical, this shows that + * the basic chunk handling, filtering, and (de)compression code is working + * properly. It does not currently test all of the transforms, although + * it probably should. + * + * The program will report "FAIL" in certain legitimate cases: + * 1) when the compression level or filter selection method is changed. + * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. + * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks + * exist in the input file. + * 4) others not listed here... + * In these cases, it is best to check with another tool such as "pngcheck" + * to see what the differences between the two files are. + * + * If a filename is given on the command-line, then this file is used + * for the input, rather than the default "pngtest.png". This allows + * testing a wide variety of files easily. You can also test a number + * of files at once by typing "pngtest -m file1.png file2.png ..." + */ + +#include "png.h" + +#if defined(_WIN32_WCE) +# if _WIN32_WCE < 211 + __error__ (f|w)printf functions are not supported on old WindowsCE.; +# endif +# include +# include +# define READFILE(file, data, length, check) \ + if (ReadFile(file, data, length, &check,NULL)) check = 0 +# define WRITEFILE(file, data, length, check)) \ + if (WriteFile(file, data, length, &check, NULL)) check = 0 +# define FCLOSE(file) CloseHandle(file) +#else +# include +# include +# define READFILE(file, data, length, check) \ + check=(png_size_t)fread(data,(png_size_t)1,length,file) +# define WRITEFILE(file, data, length, check) \ + check=(png_size_t)fwrite(data,(png_size_t)1, length, file) +# define FCLOSE(file) fclose(file) +#endif + +#if defined(PNG_NO_STDIO) +# if defined(_WIN32_WCE) + typedef HANDLE png_FILE_p; +# else + typedef FILE * png_FILE_p; +# endif +#endif + +/* Makes pngtest verbose so we can find problems (needs to be before png.h) */ +#ifndef PNG_DEBUG +# define PNG_DEBUG 0 +#endif + +#if !PNG_DEBUG +# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */ +#endif + +/* Turn on CPU timing +#define PNGTEST_TIMING +*/ + +#ifdef PNG_NO_FLOATING_POINT_SUPPORTED +#undef PNGTEST_TIMING +#endif + +#ifdef PNGTEST_TIMING +static float t_start, t_stop, t_decode, t_encode, t_misc; +#include +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +static int tIME_chunk_present=0; +static char tIME_string[30] = "no tIME chunk present in file"; +#endif + +static int verbose = 0; + +int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); + +#ifdef __TURBOC__ +#include +#endif + +/* defined so I can write to a file on gui/windowing platforms */ +/* #define STDERR stderr */ +#define STDERR stdout /* for DOS */ + +/* example of using row callbacks to make a simple progress meter */ +static int status_pass=1; +static int status_dots_requested=0; +static int status_dots=1; + +/* In case a system header (e.g., on AIX) defined jmpbuf */ +#ifdef jmpbuf +# undef jmpbuf +#endif + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) png_ptr->jmpbuf +#endif + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return; + if(status_pass != pass) + { + fprintf(stdout,"\n Pass %d: ",pass); + status_pass = pass; + status_dots = 31; + } + status_dots--; + if(status_dots == 0) + { + fprintf(stdout, "\n "); + status_dots=30; + } + fprintf(stdout, "r"); +} + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return; + fprintf(stdout, "w"); +} + + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) +/* Example of using user transform callback (we don't transform anything, + but merely examine the row filters. We set this to 256 rather than + 5 in case illegal filter values are present.) */ +static png_uint_32 filters_used[256]; +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + if(png_ptr != NULL && row_info != NULL) + ++filters_used[*(data-1)]; +} +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +/* example of using user transform callback (we don't transform anything, + but merely count the zero samples) */ + +static png_uint_32 zero_samples; + +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); +void +#ifdef PNG_1_0_X +PNGAPI +#endif +count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) +{ + png_bytep dp = data; + if(png_ptr == NULL)return; + + /* contents of row_info: + * png_uint_32 width width of row + * png_uint_32 rowbytes number of bytes in row + * png_byte color_type color type of pixels + * png_byte bit_depth bit depth of samples + * png_byte channels number of channels (1-4) + * png_byte pixel_depth bits per pixel (depth*channels) + */ + + + /* counts the number of zero samples (or zero pixels if color_type is 3 */ + + if(row_info->color_type == 0 || row_info->color_type == 3) + { + int pos=0; + png_uint_32 n, nstop; + for (n=0, nstop=row_info->width; nbit_depth == 1) + { + if(((*dp << pos++ ) & 0x80) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 2) + { + if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 4) + { + if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++; + if(pos == 8) + { + pos = 0; + dp++; + } + } + if(row_info->bit_depth == 8) + if(*dp++ == 0) zero_samples++; + if(row_info->bit_depth == 16) + { + if((*dp | *(dp+1)) == 0) zero_samples++; + dp+=2; + } + } + } + else /* other color types */ + { + png_uint_32 n, nstop; + int channel; + int color_channels = row_info->channels; + if(row_info->color_type > 3)color_channels--; + + for (n=0, nstop=row_info->width; nbit_depth == 8) + if(*dp++ == 0) zero_samples++; + if(row_info->bit_depth == 16) + { + if((*dp | *(dp+1)) == 0) zero_samples++; + dp+=2; + } + } + if(row_info->color_type > 3) + { + dp++; + if(row_info->bit_depth == 16)dp++; + } + } + } +} +#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ + +static int wrote_question = 0; + +#if defined(PNG_NO_STDIO) +/* START of code to validate stdio-free compilation */ +/* These copies of the default read/write functions come from pngrio.c and */ +/* pngwio.c. They allow "don't include stdio" testing of the library. */ +/* 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 +static void +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + /* 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. + */ + READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); + + 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 +pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + int check; + png_byte *n_data; + png_FILE_p io_ptr; + + /* 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) + { + READFILE(io_ptr, n_data, length, check); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = length; + do + { + read = MIN(NEAR_BUF_SIZE, remaining); + READFILE(io_ptr, buf, 1, err); + 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 (check != length) + { + png_error(png_ptr, "read Error"); + } +} +#endif /* USE_FAR_KEYWORD */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +static void +pngtest_flush(png_structp png_ptr) +{ +#if !defined(_WIN32_WCE) + png_FILE_p io_ptr; + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +#endif +} +#endif + +/* This is the function that does the actual writing of data. If you are + not writing to a standard C stream, you should create a replacement + write_data function and use it at run time with png_set_write_fn(), rather + than changing the library. */ +#ifndef USE_FAR_KEYWORD +static void +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + + WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); + if (check != length) + { + png_error(png_ptr, "Write 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 +pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)near_data == data) + { + WRITEFILE(io_ptr, near_data, length, check); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* copy far buffer to near buffer */ + WRITEFILE(io_ptr, buf, written, err); + if (err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + while (remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +#endif /* USE_FAR_KEYWORD */ + +/* 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 to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void +pngtest_warning(png_structp png_ptr, png_const_charp message) +{ + PNG_CONST char *name = "UNKNOWN (ERROR!)"; + if (png_ptr != NULL && png_ptr->error_ptr != NULL) + name = png_ptr->error_ptr; + fprintf(STDERR, "%s: libpng warning: %s\n", name, message); +} + +/* 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 +pngtest_error(png_structp png_ptr, png_const_charp message) +{ + pngtest_warning(png_ptr, message); + /* We can return because png_error calls the default handler, which is + * actually OK in this case. */ +} +#endif /* PNG_NO_STDIO */ +/* END of code to validate stdio-free compilation */ + +/* START of code to validate memory allocation and deallocation */ +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + +/* Allocate memory. For reasonable files, size should never exceed + 64K. However, zlib may allocate more then 64K if you don't tell + it not to. See zconf.h and png.h for more information. zlib does + need to allocate exactly 64K, so whatever you call here must + have the ability to do that. + + This piece of code can be compiled to validate max 64K allocations + by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */ +typedef struct memory_information +{ + png_uint_32 size; + png_voidp pointer; + struct memory_information FAR *next; +} memory_information; +typedef memory_information FAR *memory_infop; + +static memory_infop pinformation = NULL; +static int current_allocation = 0; +static int maximum_allocation = 0; +static int total_allocation = 0; +static int num_allocations = 0; + +png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size)); +void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); + +png_voidp +png_debug_malloc(png_structp png_ptr, png_uint_32 size) +{ + + /* png_malloc has already tested for NULL; png_create_struct calls + png_debug_malloc directly, with png_ptr == NULL which is OK */ + + if (size == 0) + return (NULL); + + /* This calls the library allocator twice, once to get the requested + buffer and once to get a new free list entry. */ + { + /* Disable malloc_fn and free_fn */ + memory_infop pinfo; + png_set_mem_fn(png_ptr, NULL, NULL, NULL); + pinfo = (memory_infop)png_malloc(png_ptr, + (png_uint_32)png_sizeof (*pinfo)); + pinfo->size = size; + current_allocation += size; + total_allocation += size; + num_allocations ++; + if (current_allocation > maximum_allocation) + maximum_allocation = current_allocation; + pinfo->pointer = (png_voidp)png_malloc(png_ptr, size); + /* Restore malloc_fn and free_fn */ + png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, + (png_free_ptr)png_debug_free); + if (size != 0 && pinfo->pointer == NULL) + { + current_allocation -= size; + total_allocation -= size; + png_error(png_ptr, + "out of memory in pngtest->png_debug_malloc."); + } + pinfo->next = pinformation; + pinformation = pinfo; + /* Make sure the caller isn't assuming zeroed memory. */ + png_memset(pinfo->pointer, 0xdd, pinfo->size); + if(verbose) + printf("png_malloc %lu bytes at %x\n",(unsigned long)size, + pinfo->pointer); + return (png_voidp)(pinfo->pointer); + } +} + +/* Free a pointer. It is removed from the list at the same time. */ +void +png_debug_free(png_structp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL) + fprintf(STDERR, "NULL pointer to png_debug_free.\n"); + if (ptr == 0) + { +#if 0 /* This happens all the time. */ + fprintf(STDERR, "WARNING: freeing NULL pointer\n"); +#endif + return; + } + + /* Unlink the element from the list. */ + { + memory_infop FAR *ppinfo = &pinformation; + for (;;) + { + memory_infop pinfo = *ppinfo; + if (pinfo->pointer == ptr) + { + *ppinfo = pinfo->next; + current_allocation -= pinfo->size; + if (current_allocation < 0) + fprintf(STDERR, "Duplicate free of memory\n"); + /* We must free the list element too, but first kill + the memory that is to be freed. */ + png_memset(ptr, 0x55, pinfo->size); + png_free_default(png_ptr, pinfo); + pinfo=NULL; + break; + } + if (pinfo->next == NULL) + { + fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); + break; + } + ppinfo = &pinfo->next; + } + } + + /* Finally free the data. */ + if(verbose) + printf("Freeing %x\n",ptr); + png_free_default(png_ptr, ptr); + ptr=NULL; +} +#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +/* END of code to test memory allocation/deallocation */ + +/* Test one file */ +int +test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) +{ + static png_FILE_p fpin; + static png_FILE_p fpout; /* "static" prevents setjmp corruption */ + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; +#ifdef PNG_WRITE_SUPPORTED + png_structp write_ptr; + png_infop write_info_ptr; + png_infop write_end_info_ptr; +#else + png_structp write_ptr = NULL; + png_infop write_info_ptr = NULL; + png_infop write_end_info_ptr = NULL; +#endif + png_bytep row_buf; + png_uint_32 y; + png_uint_32 width, height; + int num_pass, pass; + int bit_depth, color_type; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + +#if defined(_WIN32_WCE) + TCHAR path[MAX_PATH]; +#endif + char inbuf[256], outbuf[256]; + + row_buf = NULL; + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); + if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpin = fopen(inname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find input file %s\n", inname); + return (1); + } + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); + if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpout = fopen(outname, "wb")) == NULL) +#endif + { + fprintf(STDERR, "Could not open output file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + png_debug(0, "Allocating read and write structures\n"); +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, + (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); +#else + read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL); +#endif +#if defined(PNG_NO_STDIO) + png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif +#ifdef PNG_WRITE_SUPPORTED +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, + (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); +#else + write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + png_error_ptr_NULL, png_error_ptr_NULL); +#endif +#if defined(PNG_NO_STDIO) + png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, + pngtest_warning); +#endif +#endif + png_debug(0, "Allocating read_info, write_info and end_info structures\n"); + read_info_ptr = png_create_info_struct(read_ptr); + end_info_ptr = png_create_info_struct(read_ptr); +#ifdef PNG_WRITE_SUPPORTED + write_info_ptr = png_create_info_struct(write_ptr); + write_end_info_ptr = png_create_info_struct(write_ptr); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_debug(0, "Setting jmpbuf for read struct\n"); +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(read_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); + if (row_buf) + png_free(read_ptr, row_buf); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf)); +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_debug(0, "Setting jmpbuf for write struct\n"); +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(write_ptr))) +#endif + { + fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + FCLOSE(fpin); + FCLOSE(fpout); + return (1); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif +#endif + + png_debug(0, "Initializing input and output streams\n"); +#if !defined(PNG_NO_STDIO) + png_init_io(read_ptr, fpin); +# ifdef PNG_WRITE_SUPPORTED + png_init_io(write_ptr, fpout); +# endif +#else + png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); +# ifdef PNG_WRITE_SUPPORTED + png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, +# if defined(PNG_WRITE_FLUSH_SUPPORTED) + pngtest_flush); +# else + NULL); +# endif +# endif +#endif + if(status_dots_requested == 1) + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, write_row_callback); +#endif + png_set_read_status_fn(read_ptr, read_row_callback); + } + else + { +#ifdef PNG_WRITE_SUPPORTED + png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL); +#endif + png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL); + } + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + { + int i; + for(i=0; i<256; i++) + filters_used[i]=0; + png_set_read_user_transform_fn(read_ptr, count_filters); + } +#endif +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + zero_samples=0; + png_set_write_user_transform_fn(write_ptr, count_zero_samples); +#endif + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# ifndef PNG_HANDLE_CHUNK_ALWAYS +# define PNG_HANDLE_CHUNK_ALWAYS 3 +# endif + png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, + png_bytep_NULL, 0); +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) +# ifndef PNG_HANDLE_CHUNK_IF_SAFE +# define PNG_HANDLE_CHUNK_IF_SAFE 2 +# endif + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, + png_bytep_NULL, 0); +#endif + + png_debug(0, "Reading info struct\n"); + png_read_info(read_ptr, read_info_ptr); + + png_debug(0, "Transferring info struct\n"); + { + int interlace_type, compression_type, filter_type; + + if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, &compression_type, &filter_type)) + { + png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + color_type, interlace_type, compression_type, filter_type); +#else + color_type, PNG_INTERLACE_NONE, compression_type, filter_type); +#endif + } + } +#if defined(PNG_FIXED_POINT_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) + { + png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, + &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#if defined(PNG_gAMA_SUPPORTED) + { + png_fixed_point gamma; + + if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) + { + png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); + } + } +#endif +#else /* Use floating point versions */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) + { + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, + blue_y; + if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, + &red_y, &green_x, &green_y, &blue_x, &blue_y)) + { + png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); + } + } +#endif +#if defined(PNG_gAMA_SUPPORTED) + { + double gamma; + + if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) + { + png_set_gAMA(write_ptr, write_info_ptr, gamma); + } + } +#endif +#endif /* floating point */ +#endif /* fixed point */ +#if defined(PNG_iCCP_SUPPORTED) + { + png_charp name; + png_charp profile; + png_uint_32 proflen; + int compression_type; + + if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, + &profile, &proflen)) + { + png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, + profile, proflen); + } + } +#endif +#if defined(PNG_sRGB_SUPPORTED) + { + int intent; + + if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) + { + png_set_sRGB(write_ptr, write_info_ptr, intent); + } + } +#endif + { + png_colorp palette; + int num_palette; + + if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) + { + png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); + } + } +#if defined(PNG_bKGD_SUPPORTED) + { + png_color_16p background; + + if (png_get_bKGD(read_ptr, read_info_ptr, &background)) + { + png_set_bKGD(write_ptr, write_info_ptr, background); + } + } +#endif +#if defined(PNG_hIST_SUPPORTED) + { + png_uint_16p hist; + + if (png_get_hIST(read_ptr, read_info_ptr, &hist)) + { + png_set_hIST(write_ptr, write_info_ptr, hist); + } + } +#endif +#if defined(PNG_oFFs_SUPPORTED) + { + png_int_32 offset_x, offset_y; + int unit_type; + + if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type)) + { + png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); + } + } +#endif +#if defined(PNG_pCAL_SUPPORTED) + { + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + + if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, + &nparams, &units, ¶ms)) + { + png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, + nparams, units, params); + } + } +#endif +#if defined(PNG_pHYs_SUPPORTED) + { + png_uint_32 res_x, res_y; + int unit_type; + + if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) + { + png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); + } + } +#endif +#if defined(PNG_sBIT_SUPPORTED) + { + png_color_8p sig_bit; + + if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) + { + png_set_sBIT(write_ptr, write_info_ptr, sig_bit); + } + } +#endif +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED + { + int unit; + double scal_width, scal_height; + + if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } + } +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + { + int unit; + png_charp scal_width, scal_height; + + if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, + &scal_height)) + { + png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } + } +#endif +#endif +#endif +#if defined(PNG_TEXT_SUPPORTED) + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) + { + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); + } + } +#endif +#if defined(PNG_tIME_SUPPORTED) + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_info_ptr, mod_time); +#if defined(PNG_TIME_RFC1123_SUPPORTED) + /* we have to use png_strcpy instead of "=" because the string + pointed to by png_convert_to_rfc1123() gets free'ed before + we use it */ + png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#if defined(PNG_tRNS_SUPPORTED) + { + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans, + &trans_values)) + { + png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans, + trans_values); + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + { + png_unknown_chunkp unknowns; + int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr, + &unknowns); + if (num_unknowns) + { + png_size_t i; + png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, + num_unknowns); + /* copy the locations from the read_info_ptr. The automatically + generated locations in write_info_ptr are wrong because we + haven't written anything yet */ + for (i = 0; i < (png_size_t)num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, + unknowns[i].location); + } + } +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_debug(0, "\nWriting info struct\n"); + +/* If we wanted, we could write info in two steps: + png_write_info_before_PLTE(write_ptr, write_info_ptr); + */ + png_write_info(write_ptr, write_info_ptr); +#endif + +#ifdef SINGLE_ROWBUF_ALLOC + png_debug(0, "\nAllocating row buffer..."); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf); +#endif /* SINGLE_ROWBUF_ALLOC */ + png_debug(0, "Writing row data\n"); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) + num_pass = png_set_interlace_handling(read_ptr); +# ifdef PNG_WRITE_SUPPORTED + png_set_interlace_handling(write_ptr); +# endif +#else + num_pass=1; +#endif + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; +#endif + for (pass = 0; pass < num_pass; pass++) + { + png_debug1(0, "Writing row data for pass %d\n",pass); + for (y = 0; y < height; y++) + { +#ifndef SINGLE_ROWBUF_ALLOC + png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y); + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf, + png_get_rowbytes(read_ptr, read_info_ptr)); +#endif /* !SINGLE_ROWBUF_ALLOC */ + png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1); + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_decode += (t_stop - t_start); + t_start = t_stop; +#endif + png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_encode += (t_stop - t_start); + t_start = t_stop; +#endif +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef SINGLE_ROWBUF_ALLOC + png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y); + png_free(read_ptr, row_buf); +#endif /* !SINGLE_ROWBUF_ALLOC */ + } + } + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); +#endif + + png_debug(0, "Reading and writing end_info data\n"); + + png_read_end(read_ptr, end_info_ptr); +#if defined(PNG_TEXT_SUPPORTED) + { + png_textp text_ptr; + int num_text; + + if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) + { + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); + } + } +#endif +#if defined(PNG_tIME_SUPPORTED) + { + png_timep mod_time; + + if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) + { + png_set_tIME(write_ptr, write_end_info_ptr, mod_time); +#if defined(PNG_TIME_RFC1123_SUPPORTED) + /* we have to use png_strcpy instead of "=" because the string + pointed to by png_convert_to_rfc1123() gets free'ed before + we use it */ + png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + tIME_chunk_present++; +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + { + png_unknown_chunkp unknowns; + int num_unknowns; + num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr, + &unknowns); + if (num_unknowns) + { + png_size_t i; + png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, + num_unknowns); + /* copy the locations from the read_info_ptr. The automatically + generated locations in write_end_info_ptr are wrong because we + haven't written the end_info yet */ + for (i = 0; i < (png_size_t)num_unknowns; i++) + png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, + unknowns[i].location); + } + } +#endif +#ifdef PNG_WRITE_SUPPORTED + png_write_end(write_ptr, write_end_info_ptr); +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED + if(verbose) + { + png_uint_32 iwidth, iheight; + iwidth = png_get_image_width(write_ptr, write_info_ptr); + iheight = png_get_image_height(write_ptr, write_info_ptr); + fprintf(STDERR, "Image width = %lu, height = %lu\n", + (unsigned long)iwidth, (unsigned long)iheight); + } +#endif + + png_debug(0, "Destroying data structs\n"); +#ifdef SINGLE_ROWBUF_ALLOC + png_debug(1, "destroying row_buf for read_ptr\n"); + png_free(read_ptr, row_buf); + row_buf=NULL; +#endif /* SINGLE_ROWBUF_ALLOC */ + png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n"); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +#ifdef PNG_WRITE_SUPPORTED + png_debug(1, "destroying write_end_info_ptr\n"); + png_destroy_info_struct(write_ptr, &write_end_info_ptr); + png_debug(1, "destroying write_ptr, write_info_ptr\n"); + png_destroy_write_struct(&write_ptr, &write_info_ptr); +#endif + png_debug(0, "Destruction complete.\n"); + + FCLOSE(fpin); + FCLOSE(fpout); + + png_debug(0, "Opening files for comparison\n"); +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); + if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpin = fopen(inname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find file %s\n", inname); + return (1); + } + +#if defined(_WIN32_WCE) + MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); + if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) +#else + if ((fpout = fopen(outname, "rb")) == NULL) +#endif + { + fprintf(STDERR, "Could not find file %s\n", outname); + FCLOSE(fpin); + return (1); + } + + for(;;) + { + png_size_t num_in, num_out; + + READFILE(fpin, inbuf, 1, num_in); + READFILE(fpout, outbuf, 1, num_out); + + if (num_in != num_out) + { + fprintf(STDERR, "\nFiles %s and %s are of a different size\n", + inname, outname); + if(wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname,PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question=1; + } + FCLOSE(fpin); + FCLOSE(fpout); + return (0); + } + + if (!num_in) + break; + + if (png_memcmp(inbuf, outbuf, num_in)) + { + fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); + if(wrote_question == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname,PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question=1; + } + FCLOSE(fpin); + FCLOSE(fpout); + return (0); + } + } + + FCLOSE(fpin); + FCLOSE(fpout); + + return (0); +} + +/* input and output filenames */ +#ifdef RISCOS +static PNG_CONST char *inname = "pngtest/png"; +static PNG_CONST char *outname = "pngout/png"; +#else +static PNG_CONST char *inname = "pngtest.png"; +static PNG_CONST char *outname = "pngout.png"; +#endif + +int +main(int argc, char *argv[]) +{ + int multiple = 0; + int ierror = 0; + + fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); + fprintf(STDERR,"%s",png_get_copyright(NULL)); + /* Show the version of libpng used in building the library */ + fprintf(STDERR," library (%lu):%s", + (unsigned long)png_access_version_number(), + png_get_header_version(NULL)); + /* Show the version of libpng used in building the application */ + fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, + PNG_HEADER_VERSION_STRING); + fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n", + (long)png_sizeof(png_struct), (long)png_sizeof(png_info)); + + /* Do some consistency checking on the memory allocation settings, I'm + not sure this matters, but it is nice to know, the first of these + tests should be impossible because of the way the macros are set + in pngconf.h */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); +#endif + /* I think the following can happen. */ +#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) + fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); +#endif + + if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) + { + fprintf(STDERR, + "Warning: versions are different between png.h and png.c\n"); + fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); + ++ierror; + } + + if (argc > 1) + { + if (strcmp(argv[1], "-m") == 0) + { + multiple = 1; + status_dots_requested = 0; + } + else if (strcmp(argv[1], "-mv") == 0 || + strcmp(argv[1], "-vm") == 0 ) + { + multiple = 1; + verbose = 1; + status_dots_requested = 1; + } + else if (strcmp(argv[1], "-v") == 0) + { + verbose = 1; + status_dots_requested = 1; + inname = argv[2]; + } + else + { + inname = argv[1]; + status_dots_requested = 0; + } + } + + if (!multiple && argc == 3+verbose) + outname = argv[2+verbose]; + + if ((!multiple && argc > 3+verbose) || (multiple && argc < 2)) + { + fprintf(STDERR, + "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", + argv[0], argv[0]); + fprintf(STDERR, + " reads/writes one PNG file (without -m) or multiple files (-m)\n"); + fprintf(STDERR, + " with -m %s is used as a temporary file\n", outname); + exit(1); + } + + if (multiple) + { + int i; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + for (i=2; isize, + (unsigned int) pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + else + { + int i; + for (i=0; i<3; ++i) + { + int kerror; +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + int allocation_now = current_allocation; +#endif + if (i == 1) status_dots_requested = 1; + else if(verbose == 0)status_dots_requested = 0; + if (i == 0 || verbose == 1 || ierror != 0) + fprintf(STDERR, "Testing %s:",inname); + kerror = test_one_file(inname, outname); + if(kerror == 0) + { + if(verbose == 1 || i == 2) + { +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + int k; +#endif +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + fprintf(STDERR, "\n PASS (%lu zero samples)\n", + (unsigned long)zero_samples); +#else + fprintf(STDERR, " PASS\n"); +#endif +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + for (k=0; k<256; k++) + if(filters_used[k]) + fprintf(STDERR, " Filter %d was used %lu times\n", + k,(unsigned long)filters_used[k]); +#endif +#if defined(PNG_TIME_RFC1123_SUPPORTED) + if(tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n",tIME_string); +#endif /* PNG_TIME_RFC1123_SUPPORTED */ + } + } + else + { + if(verbose == 0 && i != 2) + fprintf(STDERR, "Testing %s:",inname); + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + if (allocation_now != current_allocation) + fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", + current_allocation-allocation_now); + if (current_allocation != 0) + { + memory_infop pinfo = pinformation; + + fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", + current_allocation); + while (pinfo != NULL) + { + fprintf(STDERR," %lu bytes at %x\n", + (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); + pinfo = pinfo->next; + } + } +#endif + } +#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + fprintf(STDERR, " Current memory allocation: %10d bytes\n", + current_allocation); + fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", + maximum_allocation); + fprintf(STDERR, " Total memory allocation: %10d bytes\n", + total_allocation); + fprintf(STDERR, " Number of allocations: %10d\n", + num_allocations); +#endif + } + +#ifdef PNGTEST_TIMING + t_stop = (float)clock(); + t_misc += (t_stop - t_start); + t_start = t_stop; + fprintf(STDERR," CPU time used = %.3f seconds", + (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); + fprintf(STDERR," (decoding %.3f,\n", + t_decode/(float)CLOCKS_PER_SEC); + fprintf(STDERR," encoding %.3f ,", + t_encode/(float)CLOCKS_PER_SEC); + fprintf(STDERR," other %.3f seconds)\n\n", + t_misc/(float)CLOCKS_PER_SEC); +#endif + + if (ierror == 0) + fprintf(STDERR, "libpng passes test\n"); + else + fprintf(STDERR, "libpng FAILS test\n"); + return (int)(ierror != 0); +} + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef version_1_2_18 your_png_h_is_not_version_1_2_18; diff --git a/src/dep/src/irrlicht/libpng/pngtest.png b/src/dep/src/irrlicht/libpng/pngtest.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a6df4483fc9d020c028d4e4f417767bfa72877 GIT binary patch literal 8574 zcmV-^A%WhBP) z000SeMObuHX>@F508max+yQwt001AiNklO)sr#@4<(ul(br`VbraBmuhk@3?%j97U znXm>WOoQH`mkmQV#Dgk$0iE!|kWKC(UZ$ifRdrR{?y-0LgGZ$*Gb7{uBI5Vw`}_VL z{2^pm*wxREhAV)-c=gTo8wWkR0{G-;xXP6%b;|g zqv8I@RW)^t7%eD~>nQ>F*f4b!06nYt@O07vs6LIyqkVe<@%GI=8WyVu!(s*S(Wtjd zU(82uRNY!T->v-XN2ArS$X5V=dGn1YqyG7%{PGt7XU7MtdHKc8=PzFjmdlKMM?UM^ zob$|iirnz{`J^*FIa-}hE}4{WHg{nFts1NPT7|xL{NGPcRH-}Z&ORBqPLzDn!OJ*ST}> zsq;*)JZ0ti6+7x~Kj$aL=b^rKPwfk=f2HdiZa6`2T=xibJt!J~uT>R;Q>-WuGr z>+kD`02wfMflFU=HkosFJX+0N)tk;s`c_j_0VTpgzwk;lMDRY`trmcRH5e^iTso}L zSR)vfk!8Zs)3G@}KJdl}&u6aFG!TgtM$iI<%`sXitMK~Zh0#o0vVhXw#p$H%4EJ)< zKvegiUUY;EfakNabNKY4^Rw~1)3XMnGcGROU~Q3Z$tOp{)u?Y*kA}Tf&#DuEgPuJ< zdC*_IZS#MlC?WsWU;dMp2Yq`2w{6F3yXAdFiR2%R`l~FHwVxszgShFX5T7G=b4mM=VIbo_#Z_>Y62CfQ-2%~=COJAeNI2!g&<}MtD*f6g=O-we(h1e-_b-s>1&W{gPQ&&xI z4Q{e@r0Y83e2s2by@`>FOULnOaGd^zVPV;`niwO)B41gfH?f2O1Dg+S4X&?u5LyYB zuA&MNYcxt=S~{*id9>0hqh}3u6KRNuWC+O?2{3mx*67=VySkZ0B7ugU(P#uE$?S#* zA3nP<^U`hNs1O=L-7qMUC0zeN6G4f*GI$lH`!?sJg8@$`B`(yg)nK%6bkOr3pG^n% z_bowhLx3&VU^x2Ow&-EjORV01z*P*z~kq$j`Q_qeI7o$ z=uAsL(~_}ob#?znsBz2tN5E=nXC^$K&CNm2o+B`syUmU$t1!O#y{8xR0e8r)Tx#MV9OqJICk4J;^N$F?LZW%`z)Sc6#*Ki zt{TM1>}`sBZL26De?02@1_uE zB1KZ8o?We9AN1@>tL*%;tn$JtLWryZ|`ahk7ujjJ0ZgU~?b1D{?xE?te% z89p?ePD-v^jnVMz@k4+9d#%p;PGiE)*gfJpB<0RQ*0Ko zN{BHMiCnr0=WD7E$(7#310sUf>5}&Es%|K9MPbz2HST;pgJgyZqc|vXjz{~%2F|7> zu4)LeMo8F1VKqi{iXJ0aC8LK=FFIGQ!iT`a!5+Sj_z;;of9R`*xvy~{<=4YKgVtb8 z((!u2I%@;@5C}11)O8Gf=fo$M?j*)YCP_n+vf|_CQ_f~rNG4d7OqbSzM({q;YaK;l z75&1T1N`0Tq!VMTL}0j|V{@SjaXfQX$5o+Ix_Z{ch*3ge3?O7#vSxK15fQ9X^sT{% z+fL|>4k)2O4QCTak!Qr1G?8T~4b&Ob4TKnHb!<-V7xvu8fFP}HE;nNrxf&e}_s`qN z`L*8^$e%pud)1z;*np2UR%^0$qd$B$c}EA-Bvhox16rpo5S#0}77?D`@Mez>_VHyP zrWLyto0e4=e>|R;lZQk9sw07ft~`D|doM5k#>1)g^|?-9QbaOPBFsv6`1Im>(nrH$ z5sy14})f%DGQXERs5HrYR< z+&S@+2mO^~3DKODZv5$`JE=l^s|)_K{Qn@ilKy}69KKQdMSgrVEKZb==SoIT9`s*J ze!sJ<=bPlosP9FSN1#xeA~(l{5kkUe@(|<3Z2sk2#`(_Voa=aI3YCTDkTm^D^rDv zzRjnIaL}`ez@$vIwp0aa5J{nN9h++Is?l9p{AO7{Jszz>4Ail~*O7f|n9Ln@0}lrl zA5y|KxpLKbb`8{=9UrWk049g~Kf9fQCyk~6-^DndUOHD;b1cAz_j}Y$rT)l~< zeI3W^n#G%Bvpw!V9d{l+n{*;zjpm}AaEOud+_7gBv4O!}obz;fN+f^KFHYc&?cwVbjtU@cniXSY za_Q+6nz?IQ&|i-pS-nyjl)gsDutwTo>A!2Sm)8!W7O9lZsGC&Wsq1u%eT>Y@n!;#8XmE9G4@}0D zt0=6($H=3D!TEZu7@7IH#@7L@HNK8aU8*$E=8Sd3wVE9DY(5LsvrX2#i8@9k z6ZWmas0^)=F?={E{IIaAL1E5~%KDHIV?$u8wG(66iNh zx^(qa0AsE(iR6kioNq8XqpBm5GO;Culo}MXA!YUTvG}YfrLK^UXv!Ap>$_nP0OW&WC9xZH67M=^aL8ls=N1 z4C{28xu+@UObDT&@-?~AOs}d+GRcidU$yL+=Em~2=MbY3+vC#RoMXaUXk=qyB9YA> zcWF9AswO6DVcKF}1cuh4G|bByYgFR8yrLi_8Ij22=M$p^as~JIEkrN^zG^6|gvypa zRrc3WozB>7$ELZSV@5I#H#L1{?2!o+I=SbBO7EF_zv0Q1E>IYg%FS|( zn|yL{c?i%D*)MWjh?G7UEmGB?;o{Qcd`*a{(5sYCH|g72OM4Tk6kXK~`fb)D{ZKMx z{lZWvO=udRCU7|0<%U9CS_$J@oAn3 zK195a7_FJR(3-kbHdjg|%R(Zv0oXP~y*tW_P*}~yrDI-sKAk&!XfP^E!Fo(f*)(8` z+JJ^ax)H511MuPLq@%JdX`ulvSb(_;kLRv3zD~9~HmP>6b#ld3h*TkvE5YPy1OEFM z-5V!ub4BTDOeS19PmGDKmoyt&t)?Z6F}9%jwLNvd-gw2*`LQvQ2ng0}!qW)V^I6%M zJ72AVeyh}G+vO^a)ugC`i@AFmTTJlINzYxNXOo!{5sEyy;KC?$mS}M401Bs*vSadO zZIwXXM0|+T^;pj)<)M&F)=kH8{r=pQ!9&O>(EEOCP4G!m2l3F@rX4fLZCsWfiVdpeDh=b^RJ+cq5NbXPukz!|x(*upZIZ zG16B6Q~b+DH+%^I&m1CeG@&44B z-$Cx2w9)#I7zyp}(3x<4=?-slfB@z$j9)GMe;4xFr29pF^5~#AjuD*qv+<=nd6fb6 zM<;jDcm6DYmOsn4m0Zc_LBH^ihQ;|eefE#0^76+fHdp=OzIkem>ZhzM!{&mkS_rGI zXH|&(rh&npL4*O5@~vb3S=l$F$W{O2!@=0sF}FsTI?v>?g4m!`hBzU%oR8tY=?@D< zSp~ERxsv?Va@?!(M^T>pj}|55PyYMxm%}~#KX<<;+b@3`d3N#dgzz=_Htgyh;$q1n zF4-2yvMyh~T<~JC;0GnQmzU}*p63Gjr2K&}L9290Gl9H+f&#&iOw~*&^gUn?JNln}Ich)7j<8duADCjZI&= z3LC*_jaEW*k&C$-yoztErDxT7k(<%5XIt)SBs2}B55$;I#$5CU)?EYbkw~nsq2L?$ z!qj;rOLo6}gDLq=mHlYgn+^-pS1lA)$4KQHv=&Yt49_QXH~ZNe`bAz7xmnT{st~X( zDR}Dq)4LR{L`K8HoQnvD1B>&KJ)`jZCna(6t^r8?OZpFMJ^oNBVE0H`Bu|@%cX<>)h zG#mVB-K6E~n0EO_GK6acP1*%;bv^bWoP@~i;>{KWc!RQ)NN$u2dR9N&Gir2m39U}` z03RZ;X>dMu8RRP21sCF|$n}U8Lmf}ucrtg7*5E{h>Z0u!u0nl28t#ouTiXf&3ZwHU zM??SkbYkLL6fPM?OJaWS+iO;LZUmLd2EFOqd}>tIUz>ys;r_nG`Gk&_RVs$Zw#Iy0 z!EERU06sP|=fX*har!FQ@-A{GE!XC1(6jpCU@sps$#?0r{&?BK$)J+&#lTvAvPQH zAqYnY`BS5YA%sY52{IzE zZ*%fYvu71oJ~ebac|M($K1@T5Cwz+?yWXI~J@e4y$_QD%XBBf7X3s9B$7?3WH`?s7 z3S*t6bT!lszU88x3jliHVeQS(=ayIGR%+9J1#}{)q?iabQLz8Fg`VWHE5MpW$K~jx1v`mr0rl!W` z2JgLU;_;gz7f6m(1Z$0YoI#!|&Heqvda6Ujv}wGMYH?MFe0Vx}?Nq*#gS@<|#>0I( zGD;&M;z>;-H+OZ@R&UnQv*7Dge6}W|XH(}*jBpi_(q-K%(>4rdS>$vwXSkPI;CzUf zT%mHwPmf3b*~RQ|GIzIbAk@*RO!9Rrb0RUd>lK@JNi3%CmR>iTqWk%@+}!QKzQroRg|rddmS_HKixr!mmwnA z7GDE#5y^IhEL$eWlO;0}mS3@0Ms~Ni`M_wFoetHDRG0qEiv=RE!xm;YIjn9Mwz^$j zMp(uO%O(Hzxo1hl?CuaF{J?0soh^R6U;Ommz1^K(%|HL;dTu*i)QcE@BAqT@v*d$& zhV88_UM?1duwZvPL(3Mjy@d$;^$)h`(gC`3yRcX+`I`8X<#Jh=?QEOw)~$Q*c5lAk zVhMDYYgT32tuev}c9*z_gnG&DPM3fFRrwFE>hYZzldh`I3acrs-mLO9kqhdY4O1o& z1T=L>-AGzUT&bqPhZE=sUr=yf*Xbp))5;w_(NTNSgEvZ)k=bJ?6tpc%G^SR=N<+eWlMzWUE zmBvt#0g-v>@F7q-kCBLTj@rBY>gOM=iahU!5YMbh%nU6Vmsbw&Yx4H_LpLu-=3}F* zn3zntQe^Ftt#J?~DdrZH=qqZ?;o-(5*L`-rj^s*EnI_bc!-2iUdWCm1BRkuoj(+^t zN5*8tWrr`mYM49E%a@TwTq4~q7O^45C0{L<>_~=^ZN9H}FuNHq>#uMx0$Ux}$#&4& z8QpF=*1J2xa+wHri{+9pUPiW9BHLRmA}r#P%hJz6T>g4@TZ$Kp1)*A?v#;5=_l_dV zO6dF~lME%G^)}mCG6in)V4g^1$ucfkEF$-e5M!r(_)nLeY>U#rM2XPtc5htCOmyLu z|8KAMy(O@nbul|z>?$GtHnL<{{i>{f@!rY~i}Ts?mTb}O zZn2=DS;CfN>~3%I;}3H7?`hnN8outp))xLnWLrAyYN1OPz0-wdm*o-`aarBl-r0V+ zSWt(^Ru^JirUe0hV0P}EO+FizRXw}^U(8RxS}cf5fF<{KcYd<7-R1KyU(l5;mMs%! zSA_rd+2<_j5SOj(ZLjU^E?Y~`I^&D5z-)I}(xvltq_YKE?X_IKu8S;#ttD(_*PqL_ zU>l*k)j@9yVG+r)Okd31tr-2CS?+r_qu1K(x=wK8jVWLx!)jr;XMqgg(l%UOGk3l< zHR-smaffvXnPn;2$W=MengM;24AzZiQ`WUGr zPwUv=e9hdYt8_KvnM=)|A-37KVA=?zZmy#&opHnFr@!0V1#X+D(3bRXv>?1@v){RR zpt~}NON#E+7Q1?j-JLG?)HZf^m%sgC>Ot-BJ3pLzbJ{E{z21eW+k!*64U z?QR0!x3-drpu2?Sa`D&qcDHr5Md=sGKJExF>lB@QU=&)mbXkR8#3hUIuRs6Co>hO7 zZDse&c9)lRL}gq2=!1JWzhGCxPB-K1-^#=PQ-yz6EaE@?=mYaV?(JsV%in^~CB(0> zMsrUIAuh?XF3T>sYC&8s+0D9$2-^bEg%FplH@W~_5wfhix#%Wev$eHkcU!3HCI9<# z_fK)j;=Pq^c6aXm?cm-|I^88NUo^Z}M1J#f!DnB*7|X#BvFX&#UmX{4)IG zA})XV!+ZLESJ*DU2>j6Q^3?)%w;?P#6h9D_bg7q17Rv=4z`aB3 zg`IAfZg)v|5$Sf8nC%p*>YXl&ua}fx)U%h1xG7A&v$D4{jM?7(>C2Z5-`mOfzRqwj z7j)_JGJeHZaY+>dA;P`wWV^qwcUZC{29n};y6j|K^wu_U8QI!`UA;}GlXkm}dY6$ZsUmR~RFZo!Up`RB>MKmPS^UjFmV-+t$^m{qEO@^CO+m!4c*Gbw%h zID!NM75SRm9*N<)YYuK>C~MnSlg!`r%0DiQ=Hak7S@-BgUK>t)65<}pM4`fE|8xb4ZRkjjuGE9?CFdqLTDQ5$c6-*kwCVF#8od$ zA|l(C9{cH~8$X}j{n({<#n^-rIk%hX6)tm5(7*ikq$%Fn>$olI?qbZ%)ce%I7x>X)V zJ$o|P&yQ2guZh6ENl$06CLxmty@WEBz6Js3!tBX-Hu@$E{=EvmNB!dbU|>fgf^&g+ zC23t6obK zUX_EMJsIxj$23q_!^5Xz^G!;4lPDn{7WT1D36kBn%1p~@I`{SYx1m|SSEWWW95E#e z#t38vA!W|%27#N3CQC;xWmh0km^(kdNq*goE##qn+>x{kQ`d>*8zcBSyaw#tB^Pt| z_|p0Fj}Hga5F&-m2eb0qJxd`(s`31~|MB_n$YOo3Zqm}%-nS1qiLE`m0U4yOJ(ALM zlhS38b#G1NbTT)0DLPlue>f=o8iQElFIo$x-Qm?8Ps(_cR3XkjJe_pv7%MIBW=g&b zd9R&a*U?#(SU^?@d6se2Tz8OIqmb6lRw0q)s}Px7y2HC3D*{Q;_xJ78w(SLVOhwpB zUvCPlSN_dZ@3+Z^rxWwdpZf0PJvWrz-E|AZ@PtpBxRRuHD(Ck0_lG!4M<9iI_Hxe^Z$D zpIP2Hsp(mDa{M>@r!N-~Ba(pkua^n@2X=P_mdn}aU(~-C|N1xoH7=K5{sHIxCn?{! zvqybfFDZ*Bkpc$`hkK}y6x5CzbEPVtutGhsmR1maE|;tALppG4DYJDWn~N!4`pXHsi_VCJxXDJxCx0>6mK2j| zAZfwd$NP_2dF{Jz(M(*w#`BO46r)2eP^2-halrRltp!AbZB3a4wnyFL)Wsr>NmgP> zjytKyrVqAYK^T($U$Ui{ct}F(s(GAivrKo<86K?tA8rU&BlmN~0000007*qoM6N<$ Ef`FLc{r~^~ literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/pngtrans.c b/src/dep/src/irrlicht/libpng/pngtrans.c new file mode 100644 index 0000000..f91190a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngtrans.c @@ -0,0 +1,662 @@ + +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * 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.) + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* turn on BGR-to-RGB mapping */ +void PNGAPI +png_set_bgr(png_structp png_ptr) +{ + png_debug(1, "in png_set_bgr\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_BGR; +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* turn on 16 bit byte swapping */ +void PNGAPI +png_set_swap(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap\n"); + if(png_ptr == NULL) return; + if (png_ptr->bit_depth == 16) + png_ptr->transformations |= PNG_SWAP_BYTES; +} +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* turn on pixel packing */ +void PNGAPI +png_set_packing(png_structp png_ptr) +{ + png_debug(1, "in png_set_packing\n"); + if(png_ptr == NULL) return; + if (png_ptr->bit_depth < 8) + { + png_ptr->transformations |= PNG_PACK; + png_ptr->usr_bit_depth = 8; + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* turn on packed pixel swapping */ +void PNGAPI +png_set_packswap(png_structp png_ptr) +{ + png_debug(1, "in png_set_packswap\n"); + if(png_ptr == NULL) return; + if (png_ptr->bit_depth < 8) + png_ptr->transformations |= PNG_PACKSWAP; +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +void PNGAPI +png_set_shift(png_structp png_ptr, png_color_8p true_bits) +{ + png_debug(1, "in png_set_shift\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_SHIFT; + png_ptr->shift = *true_bits; +} +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +int PNGAPI +png_set_interlace_handling(png_structp png_ptr) +{ + png_debug(1, "in png_set_interlace handling\n"); + if (png_ptr && png_ptr->interlaced) + { + png_ptr->transformations |= PNG_INTERLACE; + return (7); + } + + return (1); +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte on read, or remove a filler or alpha byte on write. + * The filler type has changed in v0.95 to allow future 2-byte fillers + * for 48-bit input data, as well as to avoid problems with some compilers + * that don't like bytes as parameters. + */ +void PNGAPI +png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_filler\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_FILLER; + png_ptr->filler = (png_byte)filler; + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; + + /* This should probably go in the "do_read_filler" routine. + * I attempted to do that in libpng-1.0.1a but that caused problems + * so I restored it in libpng-1.0.2a + */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_ptr->usr_channels = 4; + } + + /* Also I added this in libpng-1.0.2a (what happens when we expand + * a less-than-8-bit grayscale to GA? */ + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + } +} + +#if !defined(PNG_1_0_X) +/* Added to libpng-1.2.7 */ +void PNGAPI +png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_add_alpha\n"); + if(png_ptr == NULL) return; + png_set_filler(png_ptr, filler, filler_loc); + png_ptr->transformations |= PNG_ADD_ALPHA; +} +#endif + +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void PNGAPI +png_set_swap_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_swap_alpha\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_SWAP_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void PNGAPI +png_set_invert_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_alpha\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_INVERT_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +void PNGAPI +png_set_invert_mono(png_structp png_ptr) +{ + png_debug(1, "in png_set_invert_mono\n"); + if(png_ptr == NULL) return; + png_ptr->transformations |= PNG_INVERT_MONO; +} + +/* invert monochrome grayscale data */ +void /* PRIVATE */ +png_do_invert(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_invert\n"); + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row == NULL || row_info == NULL) + return; +#endif + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(~(*rp)); + rp++; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 8) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=2) + { + *rp = (png_byte)(~(*rp)); + rp+=2; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=4) + { + *rp = (png_byte)(~(*rp)); + *(rp+1) = (png_byte)(~(*(rp+1))); + rp+=4; + } + } +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* swaps byte order on 16 bit depth images */ +void /* PRIVATE */ +png_do_swap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_swap\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop= row_info->width * row_info->channels; + + for (i = 0; i < istop; i++, rp += 2) + { + png_byte t = *rp; + *rp = *(rp + 1); + *(rp + 1) = t; + } + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +const static PNG_CONST png_byte onebppswaptable[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; + +const static PNG_CONST png_byte twobppswaptable[256] = { + 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, + 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, + 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, + 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, + 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, + 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, + 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, + 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, + 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, + 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, + 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, + 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, + 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, + 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, + 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, + 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, + 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, + 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, + 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, + 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, + 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, + 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, + 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, + 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, + 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, + 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, + 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, + 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, + 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, + 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, + 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, + 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF +}; + +const static PNG_CONST png_byte fourbppswaptable[256] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, + 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, + 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, + 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, + 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, + 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, + 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, + 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, + 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, + 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, + 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, + 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, + 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, + 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, + 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, + 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, + 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF +}; + +/* swaps pixel packing order within bytes */ +void /* PRIVATE */ +png_do_packswap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_packswap\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->bit_depth < 8) + { + png_bytep rp, end, table; + + end = row + row_info->rowbytes; + + if (row_info->bit_depth == 1) + table = (png_bytep)onebppswaptable; + else if (row_info->bit_depth == 2) + table = (png_bytep)twobppswaptable; + else if (row_info->bit_depth == 4) + table = (png_bytep)fourbppswaptable; + else + return; + + for (rp = row; rp < end; rp++) + *rp = table[*rp]; + } +} +#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +/* remove filler or alpha byte(s) */ +void /* PRIVATE */ +png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) +{ + png_debug(1, "in png_do_strip_filler\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + png_bytep sp=row; + png_bytep dp=row; + png_uint_32 row_width=row_info->width; + png_uint_32 i; + + if ((row_info->color_type == PNG_COLOR_TYPE_RGB || + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && + row_info->channels == 4) + { + if (row_info->bit_depth == 8) + { + /* This converts from RGBX or RGBA to RGB */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + dp+=3; sp+=4; + for (i = 1; i < row_width; i++) + { + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + sp++; + } + } + /* This converts from XRGB or ARGB to RGB */ + else + { + for (i = 0; i < row_width; i++) + { + sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 24; + row_info->rowbytes = row_width * 3; + } + else /* if (row_info->bit_depth == 16) */ + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */ + sp += 8; dp += 6; + for (i = 1; i < row_width; i++) + { + /* This could be (although png_memcpy is probably slower): + png_memcpy(dp, sp, 6); + sp += 8; + dp += 6; + */ + + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + sp += 2; + } + } + else + { + /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ + for (i = 0; i < row_width; i++) + { + /* This could be (although png_memcpy is probably slower): + png_memcpy(dp, sp, 6); + sp += 8; + dp += 6; + */ + + sp+=2; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 48; + row_info->rowbytes = row_width * 6; + } + row_info->channels = 3; + } + else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || + (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && + row_info->channels == 2) + { + if (row_info->bit_depth == 8) + { + /* This converts from GX or GA to G */ + if (flags & PNG_FLAG_FILLER_AFTER) + { + for (i = 0; i < row_width; i++) + { + *dp++ = *sp++; + sp++; + } + } + /* This converts from XG or AG to G */ + else + { + for (i = 0; i < row_width; i++) + { + sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + else /* if (row_info->bit_depth == 16) */ + { + if (flags & PNG_FLAG_FILLER_AFTER) + { + /* This converts from GGXX or GGAA to GG */ + sp += 4; dp += 2; + for (i = 1; i < row_width; i++) + { + *dp++ = *sp++; + *dp++ = *sp++; + sp += 2; + } + } + else + { + /* This converts from XXGG or AAGG to GG */ + for (i = 0; i < row_width; i++) + { + sp += 2; + *dp++ = *sp++; + *dp++ = *sp++; + } + } + row_info->pixel_depth = 16; + row_info->rowbytes = row_width * 2; + } + row_info->channels = 1; + } + if (flags & PNG_FLAG_STRIP_ALPHA) + row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + } +} +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* swaps red and blue bytes within a pixel */ +void /* PRIVATE */ +png_do_bgr(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_bgr\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 3) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 4) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + } + else if (row_info->bit_depth == 16) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 6) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 8) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + } + } +} +#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +void PNGAPI +png_set_user_transform_info(png_structp png_ptr, png_voidp + user_transform_ptr, int user_transform_depth, int user_transform_channels) +{ + png_debug(1, "in png_set_user_transform_info\n"); + if(png_ptr == NULL) return; +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + png_ptr->user_transform_ptr = user_transform_ptr; + png_ptr->user_transform_depth = (png_byte)user_transform_depth; + png_ptr->user_transform_channels = (png_byte)user_transform_channels; +#else + if(user_transform_ptr || user_transform_depth || user_transform_channels) + png_warning(png_ptr, + "This version of libpng does not support user transform info"); +#endif +} +#endif + +/* This function returns a pointer to the user_transform_ptr associated with + * the user transform 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_user_transform_ptr(png_structp png_ptr) +{ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if (png_ptr == NULL) return (NULL); + return ((png_voidp)png_ptr->user_transform_ptr); +#else + return (NULL); +#endif +} +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngvcrd.c b/src/dep/src/irrlicht/libpng/pngvcrd.c new file mode 100644 index 0000000..7bb6280 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngvcrd.c @@ -0,0 +1,3904 @@ + +/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file + * + * For Intel x86 CPU and Microsoft Visual C++ compiler + * + * Last changed in libpng 1.2.6 - August 15, 2004 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Copyright (c) 1998, Intel Corporation + * + * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 + * Interface to libpng contributed by Gilles Vollant, 1999 + * + * + * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d, + * a sign error in the post-MMX cleanup code for each pixel_depth resulted + * in bad pixels at the beginning of some rows of some images, and also + * (due to out-of-range memory reads and writes) caused heap corruption + * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e. + * + * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916] + * + * [runtime MMX configuration, GRR 20010102] + * + */ + +#define PNG_INTERNAL +#include "png.h" + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD) + +static int mmx_supported=2; + + +int PNGAPI +png_mmx_support(void) +{ + int mmx_supported_local = 0; + _asm { + push ebx //CPUID will trash these + push ecx + push edx + + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack into eax + mov ecx, eax //Make another copy of Eflag in ecx + xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)] + push eax //Save modified Eflag back to stack + + popfd //Restored modified value back to Eflag reg + pushfd //Save Eflag to stack + pop eax //Get Eflag from stack + push ecx // save original Eflag to stack + popfd // restore original Eflag + xor eax, ecx //Compare the new Eflag with the original Eflag + jz NOT_SUPPORTED //If the same, CPUID instruction is not supported, + //skip following instructions and jump to + //NOT_SUPPORTED label + + xor eax, eax //Set eax to zero + + _asm _emit 0x0f //CPUID instruction (two bytes opcode) + _asm _emit 0xa2 + + cmp eax, 1 //make sure eax return non-zero value + jl NOT_SUPPORTED //If eax is zero, mmx not supported + + xor eax, eax //set eax to zero + inc eax //Now increment eax to 1. This instruction is + //faster than the instruction "mov eax, 1" + + _asm _emit 0x0f //CPUID instruction + _asm _emit 0xa2 + + and edx, 0x00800000 //mask out all bits but mmx bit(24) + cmp edx, 0 // 0 = mmx not supported + jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported + + mov mmx_supported_local, 1 //set return value to 1 + +NOT_SUPPORTED: + mov eax, mmx_supported_local //move return value to eax + pop edx //CPUID trashed these + pop ecx + pop ebx + } + + //mmx_supported_local=0; // test code for force don't support MMX + //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local); + + mmx_supported = mmx_supported_local; + return mmx_supported_local; +} + +/* Combines the row recently read in with the previous row. + This routine takes care of alpha and transparency if requested. + This routine also handles the two methods of progressive display + of interlaced images, depending on the mask value. + The mask value describes which pixels are to be combined with + the row. The pattern always repeats every 8 pixels, so just 8 + bits are needed. A one indicates the pixel is to be combined; a + zero indicates the pixel is to be skipped. This is in addition + to any alpha or transparency value associated with the pixel. If + you want all pixels to be combined, pass 0xff (255) in mask. */ + +/* Use this routine for x86 platform - uses faster MMX routine if machine + supports MMX */ + +void /* PRIVATE */ +png_combine_row(png_structp png_ptr, png_bytep row, int mask) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_combine_row_asm\n"); + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + + if (mask == 0xff) + { + png_memcpy(row, png_ptr->row_buf + 1, + (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->width)); + } + /* GRR: add "else if (mask == 0)" case? + * or does png_combine_row() not even get called in that case? */ + else + { + switch (png_ptr->row_info.pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + int s_inc, s_start, s_end; + int m; + int shift; + png_uint_32 i; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 7; + s_inc = 1; + } + else +#endif + { + s_start = 7; + s_end = 0; + s_inc = -1; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + int value; + + value = (*sp >> shift) & 0x1; + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 2: + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 6; + s_inc = 2; + } + else +#endif + { + s_start = 6; + s_end = 0; + s_inc = -2; + } + + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0x3; + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 4: + { + png_bytep sp; + png_bytep dp; + int s_start, s_end, s_inc; + int m; + int shift; + png_uint_32 i; + int value; + + sp = png_ptr->row_buf + 1; + dp = row; + m = 0x80; +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + { + s_start = 0; + s_end = 4; + s_inc = 4; + } + else +#endif + { + s_start = 4; + s_end = 0; + s_inc = -4; + } + shift = s_start; + + for (i = 0; i < png_ptr->width; i++) + { + if (m & mask) + { + value = (*sp >> shift) & 0xf; + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); + *dp |= (png_byte)(value << shift); + } + + if (shift == s_end) + { + shift = s_start; + sp++; + dp++; + } + else + shift += s_inc; + if (m == 1) + m = 0x80; + else + m >>= 1; + } + break; + } + + case 8: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int m; + int diff, unmask; + + __int64 mask0=0x0102040810204080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + m = 0x80; + unmask = ~mask; + len = png_ptr->width &~7; //reduce to multiple of 8 + diff = png_ptr->width & 7; //amount lost + + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + + pand mm0,mm7 //nonzero if keep byte + pcmpeqb mm0,mm6 //zeros->1s, v versa + + mov ecx,len //load length of line (pixels) + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 //lcr + je mainloop8end + +mainloop8: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + pandn mm6,[ebx] + por mm4,mm6 + movq [ebx],mm4 + + add esi,8 //inc by 8 bytes processed + add ebx,8 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop8 +mainloop8end: + + mov ecx,diff + cmp ecx,0 + jz end8 + + mov edx,mask + sal edx,24 //make low byte the high byte + +secondloop8: + sal edx,1 //move high bit to CF + jnc skip8 //if CF = 0 + mov al,[esi] + mov [ebx],al +skip8: + inc esi + inc ebx + + dec ecx + jnz secondloop8 +end8: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 8 bpp + + case 16: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + __int64 mask1=0x0101020204040808, + mask0=0x1010202040408080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + + pand mm0,mm7 + pand mm1,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 //lcr + jz mainloop16end + +mainloop16: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + add esi,16 //inc by 16 bytes processed + add ebx,16 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop16 + +mainloop16end: + mov ecx,diff + cmp ecx,0 + jz end16 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop16: + sal edx,1 //move high bit to CF + jnc skip16 //if CF = 0 + mov ax,[esi] + mov [ebx],ax +skip16: + add esi,2 + add ebx,2 + + dec ecx + jnz secondloop16 +end16: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 16 bpp + + case 24: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask2=0x0101010202020404, //24bpp + mask1=0x0408080810101020, + mask0=0x2020404040808080; + + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + cmp ecx,0 + jz mainloop24end + +mainloop24: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm4,mm2 + movq mm7,[ebx+16] + pandn mm4,mm7 + por mm6,mm4 + movq [ebx+16],mm6 + + add esi,24 //inc by 24 bytes processed + add ebx,24 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop24 + +mainloop24end: + mov ecx,diff + cmp ecx,0 + jz end24 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop24: + sal edx,1 //move high bit to CF + jnc skip24 //if CF = 0 + mov ax,[esi] + mov [ebx],ax + xor eax,eax + mov al,[esi+2] + mov [ebx+2],al +skip24: + add esi,3 + add ebx,3 + + dec ecx + jnz secondloop24 + +end24: + emms + } + } + else /* mmx not supported - use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 24 bpp + + case 32: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask3=0x0101010102020202, //32bpp + mask2=0x0404040408080808, + mask1=0x1010101020202020, + mask0=0x4040404080808080; + + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + movq mm3,mask3 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + pand mm3,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + pcmpeqb mm3,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + + cmp ecx,0 //lcr + jz mainloop32end + +mainloop32: + movq mm4,[esi] + pand mm4,mm0 + movq mm6,mm0 + movq mm7,[ebx] + pandn mm6,mm7 + por mm4,mm6 + movq [ebx],mm4 + + movq mm5,[esi+8] + pand mm5,mm1 + movq mm7,mm1 + movq mm6,[ebx+8] + pandn mm7,mm6 + por mm5,mm7 + movq [ebx+8],mm5 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm4,mm2 + movq mm7,[ebx+16] + pandn mm4,mm7 + por mm6,mm4 + movq [ebx+16],mm6 + + movq mm7,[esi+24] + pand mm7,mm3 + movq mm5,mm3 + movq mm4,[ebx+24] + pandn mm5,mm4 + por mm7,mm5 + movq [ebx+24],mm7 + + add esi,32 //inc by 32 bytes processed + add ebx,32 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop32 + +mainloop32end: + mov ecx,diff + cmp ecx,0 + jz end32 + + mov edx,mask + sal edx,24 //make low byte the high byte +secondloop32: + sal edx,1 //move high bit to CF + jnc skip32 //if CF = 0 + mov eax,[esi] + mov [ebx],eax +skip32: + add esi,4 + add ebx,4 + + dec ecx + jnz secondloop32 + +end32: + emms + } + } + else /* mmx _not supported - Use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 32 bpp + + case 48: + { + png_bytep srcptr; + png_bytep dstptr; + png_uint_32 len; + int unmask, diff; + + __int64 mask5=0x0101010101010202, + mask4=0x0202020204040404, + mask3=0x0404080808080808, + mask2=0x1010101010102020, + mask1=0x2020202040404040, + mask0=0x4040808080808080; + +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + srcptr = png_ptr->row_buf + 1; + dstptr = row; + + unmask = ~mask; + len = (png_ptr->width)&~7; + diff = (png_ptr->width)&7; + _asm + { + movd mm7, unmask //load bit pattern + psubb mm6,mm6 //zero mm6 + punpcklbw mm7,mm7 + punpcklwd mm7,mm7 + punpckldq mm7,mm7 //fill register with 8 masks + + movq mm0,mask0 + movq mm1,mask1 + movq mm2,mask2 + movq mm3,mask3 + movq mm4,mask4 + movq mm5,mask5 + + pand mm0,mm7 + pand mm1,mm7 + pand mm2,mm7 + pand mm3,mm7 + pand mm4,mm7 + pand mm5,mm7 + + pcmpeqb mm0,mm6 + pcmpeqb mm1,mm6 + pcmpeqb mm2,mm6 + pcmpeqb mm3,mm6 + pcmpeqb mm4,mm6 + pcmpeqb mm5,mm6 + + mov ecx,len //load length of line + mov esi,srcptr //load source + mov ebx,dstptr //load dest + + cmp ecx,0 + jz mainloop48end + +mainloop48: + movq mm7,[esi] + pand mm7,mm0 + movq mm6,mm0 + pandn mm6,[ebx] + por mm7,mm6 + movq [ebx],mm7 + + movq mm6,[esi+8] + pand mm6,mm1 + movq mm7,mm1 + pandn mm7,[ebx+8] + por mm6,mm7 + movq [ebx+8],mm6 + + movq mm6,[esi+16] + pand mm6,mm2 + movq mm7,mm2 + pandn mm7,[ebx+16] + por mm6,mm7 + movq [ebx+16],mm6 + + movq mm7,[esi+24] + pand mm7,mm3 + movq mm6,mm3 + pandn mm6,[ebx+24] + por mm7,mm6 + movq [ebx+24],mm7 + + movq mm6,[esi+32] + pand mm6,mm4 + movq mm7,mm4 + pandn mm7,[ebx+32] + por mm6,mm7 + movq [ebx+32],mm6 + + movq mm7,[esi+40] + pand mm7,mm5 + movq mm6,mm5 + pandn mm6,[ebx+40] + por mm7,mm6 + movq [ebx+40],mm7 + + add esi,48 //inc by 32 bytes processed + add ebx,48 + sub ecx,8 //dec by 8 pixels processed + + ja mainloop48 +mainloop48end: + + mov ecx,diff + cmp ecx,0 + jz end48 + + mov edx,mask + sal edx,24 //make low byte the high byte + +secondloop48: + sal edx,1 //move high bit to CF + jnc skip48 //if CF = 0 + mov eax,[esi] + mov [ebx],eax +skip48: + add esi,4 + add ebx,4 + + dec ecx + jnz secondloop48 + +end48: + emms + } + } + else /* mmx _not supported - Use modified C routine */ + { + register unsigned int incr1, initial_val, final_val; + png_size_t pixel_bytes; + png_uint_32 i; + register int disp = png_pass_inc[png_ptr->pass]; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dstptr, srcptr, pixel_bytes); + srcptr += incr1; + dstptr += incr1; + } + } /* end of else */ + + break; + } // end 48 bpp + + default: + { + png_bytep sptr; + png_bytep dp; + png_size_t pixel_bytes; + int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; + unsigned int i; + register int disp = png_pass_inc[png_ptr->pass]; // get the offset + register unsigned int incr1, initial_val, final_val; + + pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* + pixel_bytes; + dp = row + offset_table[png_ptr->pass]*pixel_bytes; + initial_val = offset_table[png_ptr->pass]*pixel_bytes; + final_val = png_ptr->width*pixel_bytes; + incr1 = (disp)*pixel_bytes; + for (i = initial_val; i < final_val; i += incr1) + { + png_memcpy(dp, sptr, pixel_bytes); + sptr += incr1; + dp += incr1; + } + break; + } + } /* end switch (png_ptr->row_info.pixel_depth) */ + } /* end if (non-trivial mask) */ + +} /* end png_combine_row() */ + + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + +void /* PRIVATE */ +png_do_read_interlace(png_structp png_ptr) +{ + png_row_infop row_info = &(png_ptr->row_info); + png_bytep row = png_ptr->row_buf + 1; + int pass = png_ptr->pass; + png_uint_32 transformations = png_ptr->transformations; +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1,"in png_do_read_interlace\n"); + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_byte v; + png_uint_32 i; + int j; + + sp = row + (png_size_t)((row_info->width - 1) >> 3); + dp = row + (png_size_t)((final_width - 1) >> 3); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (int)((row_info->width + 7) & 7); + dshift = (int)((final_width + 7) & 7); + s_start = 7; + s_end = 0; + s_inc = -1; + } + else +#endif + { + sshift = 7 - (int)((row_info->width + 7) & 7); + dshift = 7 - (int)((final_width + 7) & 7); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = row_info->width; i; i--) + { + v = (png_byte)((*sp >> sshift) & 0x1); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 2: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 2); + dp = row + (png_size_t)((final_width - 1) >> 2); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); + dshift = (png_size_t)(((final_width + 3) & 3) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + else +#endif + { + sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); + dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + case 4: + { + png_bytep sp, dp; + int sshift, dshift; + int s_start, s_end, s_inc; + png_uint_32 i; + + sp = row + (png_size_t)((row_info->width - 1) >> 1); + dp = row + (png_size_t)((final_width - 1) >> 1); +#if defined(PNG_READ_PACKSWAP_SUPPORTED) + if (transformations & PNG_PACKSWAP) + { + sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); + dshift = (png_size_t)(((final_width + 1) & 1) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + else +#endif + { + sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); + dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = row_info->width; i; i--) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0xf); + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); + *dp |= (png_byte)(v << dshift); + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + else + dshift += s_inc; + } + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + else + sshift += s_inc; + } + break; + } + + default: // This is the place where the routine is modified + { + __int64 const4 = 0x0000000000FFFFFF; + // __int64 const5 = 0x000000FFFFFF0000; // unused... + __int64 const6 = 0x00000000000000FF; + png_bytep sptr, dp; + png_uint_32 i; + png_size_t pixel_bytes; + int width = row_info->width; + + pixel_bytes = (row_info->pixel_depth >> 3); + + sptr = row + (width - 1) * pixel_bytes; + dp = row + (final_width - 1) * pixel_bytes; + // New code by Nirav Chhatrapati - Intel Corporation + // sign fix by GRR + // NOTE: there is NO MMX code for 48-bit and 64-bit images + + // use MMX routine if machine supports it +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && mmx_supported */ ) +#else + if (mmx_supported) +#endif + { + if (pixel_bytes == 3) + { + if (((pass == 0) || (pass == 1)) && width) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width + sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytes +loop_pass0: + movd mm0, [esi] ; X X X X X v2 v1 v0 + pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 + movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 + psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 + movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 + psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 + psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 + por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 + por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 + movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1 + psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0 + movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1 + punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2 + movq [edi+16] , mm4 + psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0 + movq [edi+8] , mm3 + punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0 + sub esi, 3 + movq [edi], mm0 + sub edi, 24 + //sub esi, 3 + dec ecx + jnz loop_pass0 + EMMS + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width + sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytes +loop_pass2: + movd mm0, [esi] ; X X X X X v2 v1 v0 + pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 + movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 + psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 + movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 + psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 + psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 + por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 + por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 + movq [edi+4], mm0 ; move to memory + psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0 + movd [edi], mm0 ; move to memory + sub esi, 3 + sub edi, 12 + dec ecx + jnz loop_pass2 + EMMS + } + } + else if (width) /* && ((pass == 4) || (pass == 5)) */ + { + int width_mmx = ((width >> 1) << 1) - 8; + if (width_mmx < 0) + width_mmx = 0; + width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 3 + sub edi, 9 +loop_pass4: + movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3 + movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3 + movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3 + psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0 + pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3 + psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0 + por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3 + movq mm5, mm6 ; 0 0 0 X X v2 v1 v0 + psllq mm6, 8 ; 0 0 X X v2 v1 v0 0 + movq [edi], mm0 ; move quad to memory + psrlq mm5, 16 ; 0 0 0 0 0 X X v2 + pand mm5, const6 ; 0 0 0 0 0 0 0 v2 + por mm6, mm5 ; 0 0 X X v2 v1 v0 v2 + movd [edi+8], mm6 ; move double to memory + sub esi, 6 + sub edi, 12 + sub ecx, 2 + jnz loop_pass4 + EMMS + } + } + + sptr -= width_mmx*3; + dp -= width_mmx*6; + for (i = width; i; i--) + { + png_byte v[8]; + int j; + + png_memcpy(v, sptr, 3); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 3); + dp -= 3; + } + sptr -= 3; + } + } + } /* end of pixel_bytes == 3 */ + + else if (pixel_bytes == 1) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 31 + sub esi, 3 +loop1_pass0: + movd mm0, [esi] ; X X X X v0 v1 v2 v3 + movq mm1, mm0 ; X X X X v0 v1 v2 v3 + punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3 + punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2 + movq [edi], mm0 ; move to memory v3 + punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 + movq [edi+8], mm3 ; move to memory v2 + movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 + punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1 + punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0 + movq [edi+16], mm2 ; move to memory v1 + movq [edi+24], mm4 ; move to memory v0 + sub esi, 4 + sub edi, 32 + sub ecx, 4 + jnz loop1_pass0 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*8; + for (i = width; i; i--) + { + int j; + + /* I simplified this part in version 1.0.4e + * here and in several other instances where + * pixel_bytes == 1 -- GR-P + * + * Original code: + * + * png_byte v[8]; + * png_memcpy(v, sptr, pixel_bytes); + * for (j = 0; j < png_pass_inc[pass]; j++) + * { + * png_memcpy(dp, v, pixel_bytes); + * dp -= pixel_bytes; + * } + * sptr -= pixel_bytes; + * + * Replacement code is in the next three lines: + */ + + for (j = 0; j < png_pass_inc[pass]; j++) + *dp-- = *sptr; + sptr--; + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 2) << 2); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 15 + sub esi, 3 +loop1_pass2: + movd mm0, [esi] ; X X X X v0 v1 v2 v3 + punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 + punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1 + movq [edi], mm0 ; move to memory v2 and v3 + sub esi, 4 + movq [edi+8], mm1 ; move to memory v1 and v0 + sub edi, 16 + sub ecx, 4 + jnz loop1_pass2 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*4; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + sptr --; + } + } + else if (width) /* && ((pass == 4) || (pass == 5))) */ + { + int width_mmx = ((width >> 3) << 3); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub edi, 15 + sub esi, 7 +loop1_pass4: + movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7 + movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7 + punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7 + //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 + punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3 + movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3 + sub esi, 8 + movq [edi], mm0 ; move to memory v4 v5 v6 and v7 + //sub esi, 4 + sub edi, 16 + sub ecx, 8 + jnz loop1_pass4 + EMMS + } + } + + sptr -= width_mmx; + dp -= width_mmx*2; + for (i = width; i; i--) + { + int j; + + for (j = 0; j < png_pass_inc[pass]; j++) + { + *dp-- = *sptr; + } + sptr --; + } + } + } /* end of pixel_bytes == 1 */ + + else if (pixel_bytes == 2) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1); + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 30 +loop2_pass0: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 + punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi + 16], mm1 + movq [edi + 24], mm1 + sub esi, 4 + sub edi, 32 + sub ecx, 2 + jnz loop2_pass0 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*16 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 14 +loop2_pass2: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 + punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 + movq [edi], mm0 + sub esi, 4 + movq [edi + 8], mm1 + //sub esi, 4 + sub edi, 16 + sub ecx, 2 + jnz loop2_pass2 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*8 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 2 + sub edi, 6 +loop2_pass4: + movd mm0, [esi] ; X X X X v1 v0 v3 v2 + punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 + sub esi, 4 + movq [edi], mm0 + sub edi, 8 + sub ecx, 2 + jnz loop2_pass4 + EMMS + } + } + + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*4 - 2); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 2; + png_memcpy(v, sptr, 2); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 2; + png_memcpy(dp, v, 2); + } + } + } + } /* end of pixel_bytes == 2 */ + + else if (pixel_bytes == 4) + { + if (((pass == 0) || (pass == 1)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 60 +loop4_pass0: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi + 16], mm0 + movq [edi + 24], mm0 + movq [edi+32], mm1 + movq [edi + 40], mm1 + movq [edi+ 48], mm1 + sub esi, 8 + movq [edi + 56], mm1 + sub edi, 64 + sub ecx, 2 + jnz loop4_pass0 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*32 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (((pass == 2) || (pass == 3)) && width) + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 28 +loop4_pass2: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + movq [edi + 8], mm0 + movq [edi+16], mm1 + movq [edi + 24], mm1 + sub esi, 8 + sub edi, 32 + sub ecx, 2 + jnz loop4_pass2 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*16 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + else if (width) // pass == 4 or 5 + { + int width_mmx = ((width >> 1) << 1) ; + width -= width_mmx; + if (width_mmx) + { + _asm + { + mov esi, sptr + mov edi, dp + mov ecx, width_mmx + sub esi, 4 + sub edi, 12 +loop4_pass4: + movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 + movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 + punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 + punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 + movq [edi], mm0 + sub esi, 8 + movq [edi + 8], mm1 + sub edi, 16 + sub ecx, 2 + jnz loop4_pass4 + EMMS + } + } + + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*8 - 4); // sign fixed + for (i = width; i; i--) + { + png_byte v[8]; + int j; + sptr -= 4; + png_memcpy(v, sptr, 4); + for (j = 0; j < png_pass_inc[pass]; j++) + { + dp -= 4; + png_memcpy(dp, v, 4); + } + } + } + + } /* end of pixel_bytes == 4 */ + + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, 6); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, 6); + dp -= 6; + } + sptr -= 6; + } + } /* end of pixel_bytes == 6 */ + + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr-= pixel_bytes; + } + } + } /* end of mmx_supported */ + + else /* MMX not supported: use modified C code - takes advantage + * of inlining of memcpy for a constant */ + { + if (pixel_bytes == 1) + { + for (i = width; i; i--) + { + int j; + for (j = 0; j < png_pass_inc[pass]; j++) + *dp-- = *sptr; + sptr--; + } + } + else if (pixel_bytes == 3) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 2) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 4) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else if (pixel_bytes == 6) + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + else + { + for (i = width; i; i--) + { + png_byte v[8]; + int j; + png_memcpy(v, sptr, pixel_bytes); + for (j = 0; j < png_pass_inc[pass]; j++) + { + png_memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + sptr -= pixel_bytes; + } + } + + } /* end of MMX not supported */ + break; + } + } /* end switch (row_info->pixel_depth) */ + + row_info->width = final_width; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + } + +} + +#endif /* PNG_READ_INTERLACING_SUPPORTED */ + + +// These variables are utilized in the functions below. They are declared +// globally here to ensure alignment on 8-byte boundaries. + +union uAll { + __int64 use; + double align; +} LBCarryMask = {0x0101010101010101}, + HBClearMask = {0x7f7f7f7f7f7f7f7f}, + ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem; + + +// Optimized code for PNG Average filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row + , png_bytep prev_row) +{ + int bpp; + png_uint_32 FullLength; + png_uint_32 MMXLength; + //png_uint_32 len; + int diff; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes; // # of bytes to filter + _asm { + // Init address pointers and offset + mov edi, row // edi ==> Avg(x) + xor ebx, ebx // ebx ==> x + mov edx, edi + mov esi, prev_row // esi ==> Prior(x) + sub edx, bpp // edx ==> Raw(x-bpp) + + xor eax, eax + // Compute the Raw value for the first bpp bytes + // Raw(x) = Avg(x) + (Prior(x)/2) +davgrlp: + mov al, [esi + ebx] // Load al with Prior(x) + inc ebx + shr al, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, bpp + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davgrlp + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, ebx // add bpp + add diff, 0xf // add 7 + 8 to incr past alignment boundary + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value ebx at alignment + jz davggo + // fix alignment + // Compute the Raw value for the bytes upto the alignment boundary + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor ecx, ecx +davglp1: + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, diff // Check if at alignment boundary + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davglp1 // Repeat until at alignment boundary +davggo: + mov eax, FullLength + mov ecx, eax + sub eax, ebx // subtract alignment fix + and eax, 0x00000007 // calc bytes over mult of 8 + sub ecx, eax // drop over bytes from original length + mov MMXLength, ecx + } // end _asm block + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000000000ffffff; + ShiftBpp.use = 24; // == 3 * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm { + // Re-init address pointers and offset + movq mm7, ActiveMask + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg3lp: + movq mm0, [edi + ebx] // Load mm0 with Avg(x) + // Add (Prev_row/2) to Average + movq mm3, mm5 + psrlq mm2, ShiftRem // Correct position Raw(x-bpp) data + movq mm1, [esi + ebx] // Load mm1 with Prior(x) + movq mm6, mm7 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 3-5 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + + // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover the last two + // bytes + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + add ebx, 8 + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Move updated Raw(x) to use as Raw(x-bpp) for next loop + cmp ebx, MMXLength + movq mm2, mm0 // mov updated Raw(x) to mm2 + jb davg3lp + } // end _asm block + } + break; + + case 6: + case 4: + case 7: + case 5: + { + ActiveMask.use = 0xffffffffffffffff; // use shift below to clear + // appropriate inactive bytes + ShiftBpp.use = bpp << 3; + ShiftRem.use = 64 - ShiftBpp.use; + _asm { + movq mm4, HBClearMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + // Load ActiveMask and clear all bytes except for 1st active group + movq mm7, ActiveMask + mov edi, row // edi ==> Avg(x) + psrlq mm7, ShiftRem + mov esi, prev_row // esi ==> Prior(x) + movq mm6, mm7 + movq mm5, LBCarryMask + psllq mm6, ShiftBpp // Create mask for 2nd active group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg4lp: + movq mm0, [edi + ebx] + psrlq mm2, ShiftRem // shift data to position correctly + movq mm1, [esi + ebx] + // Add (Prev_row/2) to Average + movq mm3, mm5 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm7 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + add ebx, 8 + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active + // byte + cmp ebx, MMXLength + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Prep Raw(x-bpp) for next loop + movq mm2, mm0 // mov updated Raws to mm2 + jb davg4lp + } // end _asm block + } + break; + case 2: + { + ActiveMask.use = 0x000000000000ffff; + ShiftBpp.use = 16; // == 2 * 8 [BUGFIX] + ShiftRem.use = 48; // == 64 - 16 [BUGFIX] + _asm { + // Load ActiveMask + movq mm7, ActiveMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (we correct position in loop below) +davg2lp: + movq mm0, [edi + ebx] + psrlq mm2, ShiftRem // shift data to position correctly [BUGFIX] + movq mm1, [esi + ebx] + // Add (Prev_row/2) to Average + movq mm3, mm5 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + movq mm6, mm7 + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 2 & 3 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 4 & 5 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry + psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 6 & 7 + movq mm2, mm0 // mov updated Raws to mm2 + psllq mm2, ShiftBpp // shift data to position correctly + // Data only needs to be shifted once here to + // get the correct x-bpp offset. + add ebx, 8 + movq mm1, mm3 // now use mm1 for getting LBCarrys + pand mm1, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 (Only valid for active group) + psrlq mm2, 1 // divide raw bytes by 2 + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte + pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg + paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte + + cmp ebx, MMXLength + // Now ready to write back to memory + movq [edi + ebx - 8], mm0 + // Prep Raw(x-bpp) for next loop + movq mm2, mm0 // mov updated Raws to mm2 + jb davg2lp + } // end _asm block + } + break; + + case 1: // bpp == 1 + { + _asm { + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + mov edi, row // edi ==> Avg(x) + cmp ebx, FullLength // Test if offset at end of array + jnb davg1end + // Do Paeth decode for remaining bytes + mov esi, prev_row // esi ==> Prior(x) + mov edx, edi + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // edx ==> Raw(x-bpp) +davg1lp: + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, FullLength // Check if at end of array + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davg1lp +davg1end: + } // end _asm block + } + return; + + case 8: // bpp == 8 + { + _asm { + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + movq mm5, LBCarryMask + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov esi, prev_row // esi ==> Prior(x) + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes + // (NO NEED to correct position in loop below) +davg8lp: + movq mm0, [edi + ebx] + movq mm3, mm5 + movq mm1, [esi + ebx] + add ebx, 8 + pand mm3, mm1 // get lsb for each prev_row byte + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm3, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 + psrlq mm2, 1 // divide raw bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm3 // add LBCarrys to Avg for each byte + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + paddb mm0, mm2 // add (Raw/2) to Avg for each byte + cmp ebx, MMXLength + movq [edi + ebx - 8], mm0 + movq mm2, mm0 // reuse as Raw(x-bpp) + jb davg8lp + } // end _asm block + } + break; + default: // bpp greater than 8 + { + _asm { + movq mm5, LBCarryMask + // Re-init address pointers and offset + mov ebx, diff // ebx ==> x = offset to alignment boundary + mov edi, row // edi ==> Avg(x) + movq mm4, HBClearMask + mov edx, edi + mov esi, prev_row // esi ==> Prior(x) + sub edx, bpp // edx ==> Raw(x-bpp) +davgAlp: + movq mm0, [edi + ebx] + movq mm3, mm5 + movq mm1, [esi + ebx] + pand mm3, mm1 // get lsb for each prev_row byte + movq mm2, [edx + ebx] + psrlq mm1, 1 // divide prev_row bytes by 2 + pand mm3, mm2 // get LBCarrys for each byte where both + // lsb's were == 1 + psrlq mm2, 1 // divide raw bytes by 2 + pand mm1, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm3 // add LBCarrys to Avg for each byte + pand mm2, mm4 // clear invalid bit 7 of each byte + paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte + add ebx, 8 + paddb mm0, mm2 // add (Raw/2) to Avg for each byte + cmp ebx, MMXLength + movq [edi + ebx - 8], mm0 + jb davgAlp + } // end _asm block + } + break; + } // end switch ( bpp ) + + _asm { + // MMX acceleration complete now do clean-up + // Check if any remaining bytes left to decode + mov ebx, MMXLength // ebx ==> x = offset bytes remaining after MMX + mov edi, row // edi ==> Avg(x) + cmp ebx, FullLength // Test if offset at end of array + jnb davgend + // Do Paeth decode for remaining bytes + mov esi, prev_row // esi ==> Prior(x) + mov edx, edi + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // edx ==> Raw(x-bpp) +davglp2: + // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) + xor eax, eax + mov cl, [esi + ebx] // load cl with Prior(x) + mov al, [edx + ebx] // load al with Raw(x-bpp) + add ax, cx + inc ebx + shr ax, 1 // divide by 2 + add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx + cmp ebx, FullLength // Check if at end of array + mov [edi+ebx-1], al // Write back Raw(x); + // mov does not affect flags; -1 to offset inc ebx + jb davglp2 +davgend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Paeth filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 FullLength; + png_uint_32 MMXLength; + //png_uint_32 len; + int bpp; + int diff; + //int ptemp; + int patemp, pbtemp, pctemp; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes; // # of bytes to filter + _asm + { + xor ebx, ebx // ebx ==> x offset + mov edi, row + xor edx, edx // edx ==> x-bpp offset + mov esi, prev_row + xor eax, eax + + // Compute the Raw value for the first bpp bytes + // Note: the formula works out to be always + // Paeth(x) = Raw(x) + Prior(x) where x < bpp +dpthrlp: + mov al, [edi + ebx] + add al, [esi + ebx] + inc ebx + cmp ebx, bpp + mov [edi + ebx - 1], al + jb dpthrlp + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, ebx // add bpp + xor ecx, ecx + add diff, 0xf // add 7 + 8 to incr past alignment boundary + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value ebx at alignment + jz dpthgo + // fix alignment +dpthlp1: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthpca + neg eax // reverse sign of neg values +dpthpca: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthpba + neg ecx // reverse sign of neg values +dpthpba: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthpaa + neg eax // reverse sign of neg values +dpthpaa: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthabb + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthbbc + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth +dpthbbc: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthpaeth +dpthabb: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthabc + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth +dpthabc: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthpaeth: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, diff + jb dpthlp1 +dpthgo: + mov ecx, FullLength + mov eax, ecx + sub eax, ebx // subtract alignment fix + and eax, 0x00000007 // calc bytes over mult of 8 + sub ecx, eax // drop over bytes from original length + mov MMXLength, ecx + } // end _asm block + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000000000ffffff; + ActiveMaskEnd.use = 0xffff000000000000; + ShiftBpp.use = 24; // == bpp(3) * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm + { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dpth3lp: + psrlq mm1, ShiftRem // shift last 3 bytes to 1st 3 bytes + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm1, mm0 // Unpack High bytes of a + movq mm3, [esi+ebx-8] // Prep c=Prior(x-bpp) bytes + punpcklbw mm2, mm0 // Unpack High bytes of b + psrlq mm3, ShiftRem // shift last 3 bytes to 1st 3 bytes + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx] // load c=Prior(x-bpp) + pand mm7, ActiveMask + movq mm2, mm3 // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpcklbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) + // Now do Paeth for 2nd set of bytes (3-5) + psrlq mm2, ShiftBpp // load b=Prior(x) step 2 + punpcklbw mm1, mm0 // Unpack High bytes of a + pxor mm7, mm7 + punpcklbw mm2, mm0 // Unpack High bytes of b + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + psubw mm5, mm3 + psubw mm4, mm3 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = + // pav + pbv = pbv + pav + movq mm6, mm5 + paddw mm6, mm4 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm5 // Create mask pbv bytes < 0 + pcmpgtw mm7, mm4 // Create mask pav bytes < 0 + pand mm0, mm5 // Only pbv bytes < 0 in mm0 + pand mm7, mm4 // Only pav bytes < 0 in mm7 + psubw mm5, mm0 + psubw mm4, mm7 + psubw mm5, mm0 + psubw mm4, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + movq mm2, [esi + ebx] // load b=Prior(x) + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, mm2 // load c=Prior(x-bpp) step 1 + pand mm7, ActiveMask + punpckhbw mm2, mm0 // Unpack High bytes of b + psllq mm7, ShiftBpp // Shift bytes to 2nd group of 3 bytes + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + psllq mm3, ShiftBpp // load c=Prior(x-bpp) step 2 + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 + punpckhbw mm3, mm0 // Unpack High bytes of c + psllq mm1, ShiftBpp // Shift bytes + // Now mm1 will be used as Raw(x-bpp) + // Now do Paeth for 3rd, and final, set of bytes (6-7) + pxor mm7, mm7 + punpckhbw mm1, mm0 // Unpack High bytes of a + psubw mm4, mm3 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + pxor mm0, mm0 + paddw mm6, mm5 + + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + pandn mm0, mm1 + pandn mm7, mm4 + paddw mm0, mm2 + paddw mm7, mm5 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm1, mm1 + packuswb mm1, mm7 + // Step ebx to next set of 8 bytes and repeat loop til done + add ebx, 8 + pand mm1, ActiveMaskEnd + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + + cmp ebx, MMXLength + pxor mm0, mm0 // pxor does not affect flags + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + // mm3 ready to be used as Prior(x-bpp) next loop + jb dpth3lp + } // end _asm block + } + break; + + case 6: + case 7: + case 5: + { + ActiveMask.use = 0x00000000ffffffff; + ActiveMask2.use = 0xffffffff00000000; + ShiftBpp.use = bpp << 3; // == bpp * 8 + ShiftRem.use = 64 - ShiftBpp.use; + _asm + { + mov ebx, diff + mov edi, row + mov esi, prev_row + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] + pxor mm0, mm0 +dpth6lp: + // Must shift to position Raw(x-bpp) data + psrlq mm1, ShiftRem + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpcklbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack Low bytes of b + // Must shift to position Prior(x-bpp) data + psrlq mm3, ShiftRem + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx - 8] // load c=Prior(x-bpp) + pand mm7, ActiveMask + psrlq mm3, ShiftRem + movq mm2, [esi + ebx] // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + movq mm6, mm2 + movq [edi + ebx], mm7 // write back updated value + movq mm1, [edi+ebx-8] + psllq mm6, ShiftBpp + movq mm5, mm7 + psrlq mm1, ShiftRem + por mm3, mm6 + psllq mm5, ShiftBpp + punpckhbw mm3, mm0 // Unpack High bytes of c + por mm1, mm5 + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack High bytes of b + punpckhbw mm1, mm0 // Unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth6lp + } // end _asm block + } + break; + + case 4: + { + ActiveMask.use = 0x00000000ffffffff; + _asm { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] // Only time should need to read + // a=Raw(x-bpp) bytes +dpth4lp: + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpckhbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack High bytes of b + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpckhbw mm3, mm0 // Unpack High bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi + ebx] // load c=Prior(x-bpp) + pand mm7, ActiveMask + movq mm2, mm3 // load b=Prior(x) step 1 + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpcklbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack Low bytes of b + punpcklbw mm1, mm0 // Unpack Low bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth4lp + } // end _asm block + } + break; + case 8: // bpp == 8 + { + ActiveMask.use = 0x00000000ffffffff; + _asm { + mov ebx, diff + mov edi, row + mov esi, prev_row + pxor mm0, mm0 + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] // Only time should need to read + // a=Raw(x-bpp) bytes +dpth8lp: + // Do first set of 4 bytes + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + punpcklbw mm1, mm0 // Unpack Low bytes of a + movq mm2, [esi + ebx] // load b=Prior(x) + punpcklbw mm2, mm0 // Unpack Low bytes of b + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + punpcklbw mm3, mm0 // Unpack Low bytes of c + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + paddw mm7, mm3 + pxor mm0, mm0 + packuswb mm7, mm1 + movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes + pand mm7, ActiveMask + movq mm2, [esi + ebx] // load b=Prior(x) + paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) + punpckhbw mm3, mm0 // Unpack High bytes of c + movq [edi + ebx], mm7 // write back updated value + movq mm1, [edi+ebx-8] // read a=Raw(x-bpp) bytes + + // Do second set of 4 bytes + punpckhbw mm2, mm0 // Unpack High bytes of b + punpckhbw mm1, mm0 // Unpack High bytes of a + // pav = p - a = (a + b - c) - a = b - c + movq mm4, mm2 + // pbv = p - b = (a + b - c) - b = a - c + movq mm5, mm1 + psubw mm4, mm3 + pxor mm7, mm7 + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + movq mm6, mm4 + psubw mm5, mm3 + // pa = abs(p-a) = abs(pav) + // pb = abs(p-b) = abs(pbv) + // pc = abs(p-c) = abs(pcv) + pcmpgtw mm0, mm4 // Create mask pav bytes < 0 + paddw mm6, mm5 + pand mm0, mm4 // Only pav bytes < 0 in mm7 + pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 + psubw mm4, mm0 + pand mm7, mm5 // Only pbv bytes < 0 in mm0 + psubw mm4, mm0 + psubw mm5, mm7 + pxor mm0, mm0 + pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 + pand mm0, mm6 // Only pav bytes < 0 in mm7 + psubw mm5, mm7 + psubw mm6, mm0 + // test pa <= pb + movq mm7, mm4 + psubw mm6, mm0 + pcmpgtw mm7, mm5 // pa > pb? + movq mm0, mm7 + // use mm7 mask to merge pa & pb + pand mm5, mm7 + // use mm0 mask copy to merge a & b + pand mm2, mm0 + pandn mm7, mm4 + pandn mm0, mm1 + paddw mm7, mm5 + paddw mm0, mm2 + // test ((pa <= pb)? pa:pb) <= pc + pcmpgtw mm7, mm6 // pab > pc? + pxor mm1, mm1 + pand mm3, mm7 + pandn mm7, mm0 + pxor mm1, mm1 + paddw mm7, mm3 + pxor mm0, mm0 + // Step ex to next set of 8 bytes and repeat loop til done + add ebx, 8 + packuswb mm1, mm7 + paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) + cmp ebx, MMXLength + movq [edi + ebx - 8], mm1 // write back updated value + // mm1 will be used as Raw(x-bpp) next loop + jb dpth8lp + } // end _asm block + } + break; + + case 1: // bpp = 1 + case 2: // bpp = 2 + default: // bpp > 8 + { + _asm { + mov ebx, diff + cmp ebx, FullLength + jnb dpthdend + mov edi, row + mov esi, prev_row + // Do Paeth decode for remaining bytes + mov edx, ebx + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // Set edx = ebx - bpp +dpthdlp: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthdpca + neg eax // reverse sign of neg values +dpthdpca: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthdpba + neg ecx // reverse sign of neg values +dpthdpba: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthdpaa + neg eax // reverse sign of neg values +dpthdpaa: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthdabb + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthdbbc + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthdpaeth +dpthdbbc: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthdpaeth +dpthdabb: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthdabc + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthdpaeth +dpthdabc: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthdpaeth: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, FullLength + jb dpthdlp +dpthdend: + } // end _asm block + } + return; // No need to go further with this one + } // end switch ( bpp ) + _asm + { + // MMX acceleration complete now do clean-up + // Check if any remaining bytes left to decode + mov ebx, MMXLength + cmp ebx, FullLength + jnb dpthend + mov edi, row + mov esi, prev_row + // Do Paeth decode for remaining bytes + mov edx, ebx + xor ecx, ecx // zero ecx before using cl & cx in loop below + sub edx, bpp // Set edx = ebx - bpp +dpthlp2: + xor eax, eax + // pav = p - a = (a + b - c) - a = b - c + mov al, [esi + ebx] // load Prior(x) into al + mov cl, [esi + edx] // load Prior(x-bpp) into cl + sub eax, ecx // subtract Prior(x-bpp) + mov patemp, eax // Save pav for later use + xor eax, eax + // pbv = p - b = (a + b - c) - b = a - c + mov al, [edi + edx] // load Raw(x-bpp) into al + sub eax, ecx // subtract Prior(x-bpp) + mov ecx, eax + // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv + add eax, patemp // pcv = pav + pbv + // pc = abs(pcv) + test eax, 0x80000000 + jz dpthpca2 + neg eax // reverse sign of neg values +dpthpca2: + mov pctemp, eax // save pc for later use + // pb = abs(pbv) + test ecx, 0x80000000 + jz dpthpba2 + neg ecx // reverse sign of neg values +dpthpba2: + mov pbtemp, ecx // save pb for later use + // pa = abs(pav) + mov eax, patemp + test eax, 0x80000000 + jz dpthpaa2 + neg eax // reverse sign of neg values +dpthpaa2: + mov patemp, eax // save pa for later use + // test if pa <= pb + cmp eax, ecx + jna dpthabb2 + // pa > pb; now test if pb <= pc + cmp ecx, pctemp + jna dpthbbc2 + // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth2 +dpthbbc2: + // pb <= pc; Raw(x) = Paeth(x) + Prior(x) + mov cl, [esi + ebx] // load Prior(x) into cl + jmp dpthpaeth2 +dpthabb2: + // pa <= pb; now test if pa <= pc + cmp eax, pctemp + jna dpthabc2 + // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) + mov cl, [esi + edx] // load Prior(x-bpp) into cl + jmp dpthpaeth2 +dpthabc2: + // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) + mov cl, [edi + edx] // load Raw(x-bpp) into cl +dpthpaeth2: + inc ebx + inc edx + // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 + add [edi + ebx - 1], cl + cmp ebx, FullLength + jb dpthlp2 +dpthend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Sub filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) +{ + //int test; + int bpp; + png_uint_32 FullLength; + png_uint_32 MMXLength; + int diff; + + bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel + FullLength = row_info->rowbytes - bpp; // # of bytes to filter + _asm { + mov edi, row + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + xor eax, eax + // get # of bytes to alignment + mov diff, edi // take start of row + add diff, 0xf // add 7 + 8 to incr past + // alignment boundary + xor ebx, ebx + and diff, 0xfffffff8 // mask to alignment boundary + sub diff, edi // subtract from start ==> value + // ebx at alignment + jz dsubgo + // fix alignment +dsublp1: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, diff + jb dsublp1 +dsubgo: + mov ecx, FullLength + mov edx, ecx + sub edx, ebx // subtract alignment fix + and edx, 0x00000007 // calc bytes over mult of 8 + sub ecx, edx // drop over bytes from length + mov MMXLength, ecx + } // end _asm block + + // Now do the math for the rest of the row + switch ( bpp ) + { + case 3: + { + ActiveMask.use = 0x0000ffffff000000; + ShiftBpp.use = 24; // == 3 * 8 + ShiftRem.use = 40; // == 64 - 24 + _asm { + mov edi, row + movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + movq mm6, mm7 + mov ebx, diff + psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active + // byte group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub3lp: + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive bytes + // Add 1st active group + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm7 // mask to use only 2nd active group + paddb mm0, mm1 + // Add 3rd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm6 // mask to use only 3rd active group + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // Write updated Raws back to array + // Prep for doing 1st add at top of loop + movq mm1, mm0 + jb dsub3lp + } // end _asm block + } + break; + + case 1: + { + // Placed here just in case this is a duplicate of the + // non-MMX code for the SUB filter in png_read_filter_row below + // + // png_bytep rp; + // png_bytep lp; + // png_uint_32 i; + // bpp = (row_info->pixel_depth + 7) >> 3; + // for (i = (png_uint_32)bpp, rp = row + bpp, lp = row; + // i < row_info->rowbytes; i++, rp++, lp++) + // { + // *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff); + // } + _asm { + mov ebx, diff + mov edi, row + cmp ebx, FullLength + jnb dsub1end + mov esi, edi // lp = row + xor eax, eax + add edi, bpp // rp = row + bpp +dsub1lp: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, FullLength + jb dsub1lp +dsub1end: + } // end _asm block + } + return; + + case 6: + case 7: + case 4: + case 5: + { + ShiftBpp.use = bpp << 3; + ShiftRem.use = 64 - ShiftBpp.use; + _asm { + mov edi, row + mov ebx, diff + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub4lp: + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive bytes + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + // there is no need for any mask + // since shift clears inactive bits/bytes + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 + movq mm1, mm0 // Prep for doing 1st add at top of loop + jb dsub4lp + } // end _asm block + } + break; + + case 2: + { + ActiveMask.use = 0x00000000ffff0000; + ShiftBpp.use = 16; // == 2 * 8 + ShiftRem.use = 48; // == 64 - 16 + _asm { + movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group + mov ebx, diff + movq mm6, mm7 + mov edi, row + psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active + // byte group + mov esi, edi // lp = row + movq mm5, mm6 + add edi, bpp // rp = row + bpp + psllq mm5, ShiftBpp // Move mask in mm5 to cover 4th active + // byte group + // PRIME the pump (load the first Raw(x-bpp) data set + movq mm1, [edi+ebx-8] +dsub2lp: + // Add 1st active group + psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes + // no need for mask; shift clears inactive + // bytes + movq mm0, [edi+ebx] + paddb mm0, mm1 + // Add 2nd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm7 // mask to use only 2nd active group + paddb mm0, mm1 + // Add 3rd active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm6 // mask to use only 3rd active group + paddb mm0, mm1 + // Add 4th active group + movq mm1, mm0 // mov updated Raws to mm1 + psllq mm1, ShiftBpp // shift data to position correctly + pand mm1, mm5 // mask to use only 4th active group + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // Write updated Raws back to array + movq mm1, mm0 // Prep for doing 1st add at top of loop + jb dsub2lp + } // end _asm block + } + break; + case 8: + { + _asm { + mov edi, row + mov ebx, diff + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp + mov ecx, MMXLength + movq mm7, [edi+ebx-8] // PRIME the pump (load the first + // Raw(x-bpp) data set + and ecx, 0x0000003f // calc bytes over mult of 64 +dsub8lp: + movq mm0, [edi+ebx] // Load Sub(x) for 1st 8 bytes + paddb mm0, mm7 + movq mm1, [edi+ebx+8] // Load Sub(x) for 2nd 8 bytes + movq [edi+ebx], mm0 // Write Raw(x) for 1st 8 bytes + // Now mm0 will be used as Raw(x-bpp) for + // the 2nd group of 8 bytes. This will be + // repeated for each group of 8 bytes with + // the 8th group being used as the Raw(x-bpp) + // for the 1st group of the next loop. + paddb mm1, mm0 + movq mm2, [edi+ebx+16] // Load Sub(x) for 3rd 8 bytes + movq [edi+ebx+8], mm1 // Write Raw(x) for 2nd 8 bytes + paddb mm2, mm1 + movq mm3, [edi+ebx+24] // Load Sub(x) for 4th 8 bytes + movq [edi+ebx+16], mm2 // Write Raw(x) for 3rd 8 bytes + paddb mm3, mm2 + movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes + movq [edi+ebx+24], mm3 // Write Raw(x) for 4th 8 bytes + paddb mm4, mm3 + movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes + movq [edi+ebx+32], mm4 // Write Raw(x) for 5th 8 bytes + paddb mm5, mm4 + movq mm6, [edi+ebx+48] // Load Sub(x) for 7th 8 bytes + movq [edi+ebx+40], mm5 // Write Raw(x) for 6th 8 bytes + paddb mm6, mm5 + movq mm7, [edi+ebx+56] // Load Sub(x) for 8th 8 bytes + movq [edi+ebx+48], mm6 // Write Raw(x) for 7th 8 bytes + add ebx, 64 + paddb mm7, mm6 + cmp ebx, ecx + movq [edi+ebx-8], mm7 // Write Raw(x) for 8th 8 bytes + jb dsub8lp + cmp ebx, MMXLength + jnb dsub8lt8 +dsub8lpA: + movq mm0, [edi+ebx] + add ebx, 8 + paddb mm0, mm7 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // use -8 to offset early add to ebx + movq mm7, mm0 // Move calculated Raw(x) data to mm1 to + // be the new Raw(x-bpp) for the next loop + jb dsub8lpA +dsub8lt8: + } // end _asm block + } + break; + + default: // bpp greater than 8 bytes + { + _asm { + mov ebx, diff + mov edi, row + mov esi, edi // lp = row + add edi, bpp // rp = row + bpp +dsubAlp: + movq mm0, [edi+ebx] + movq mm1, [esi+ebx] + add ebx, 8 + paddb mm0, mm1 + cmp ebx, MMXLength + movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset + // add ebx + jb dsubAlp + } // end _asm block + } + break; + + } // end switch ( bpp ) + + _asm { + mov ebx, MMXLength + mov edi, row + cmp ebx, FullLength + jnb dsubend + mov esi, edi // lp = row + xor eax, eax + add edi, bpp // rp = row + bpp +dsublp2: + mov al, [esi+ebx] + add [edi+ebx], al + inc ebx + cmp ebx, FullLength + jb dsublp2 +dsubend: + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + +// Optimized code for PNG Up filter decoder +void /* PRIVATE */ +png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, + png_bytep prev_row) +{ + png_uint_32 len; + len = row_info->rowbytes; // # of bytes to filter + _asm { + mov edi, row + // get # of bytes to alignment + mov ecx, edi + xor ebx, ebx + add ecx, 0x7 + xor eax, eax + and ecx, 0xfffffff8 + mov esi, prev_row + sub ecx, edi + jz dupgo + // fix alignment +duplp1: + mov al, [edi+ebx] + add al, [esi+ebx] + inc ebx + cmp ebx, ecx + mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx + jb duplp1 +dupgo: + mov ecx, len + mov edx, ecx + sub edx, ebx // subtract alignment fix + and edx, 0x0000003f // calc bytes over mult of 64 + sub ecx, edx // drop over bytes from length + // Unrolled loop - use all MMX registers and interleave to reduce + // number of branch instructions (loops) and reduce partial stalls +duploop: + movq mm1, [esi+ebx] + movq mm0, [edi+ebx] + movq mm3, [esi+ebx+8] + paddb mm0, mm1 + movq mm2, [edi+ebx+8] + movq [edi+ebx], mm0 + paddb mm2, mm3 + movq mm5, [esi+ebx+16] + movq [edi+ebx+8], mm2 + movq mm4, [edi+ebx+16] + movq mm7, [esi+ebx+24] + paddb mm4, mm5 + movq mm6, [edi+ebx+24] + movq [edi+ebx+16], mm4 + paddb mm6, mm7 + movq mm1, [esi+ebx+32] + movq [edi+ebx+24], mm6 + movq mm0, [edi+ebx+32] + movq mm3, [esi+ebx+40] + paddb mm0, mm1 + movq mm2, [edi+ebx+40] + movq [edi+ebx+32], mm0 + paddb mm2, mm3 + movq mm5, [esi+ebx+48] + movq [edi+ebx+40], mm2 + movq mm4, [edi+ebx+48] + movq mm7, [esi+ebx+56] + paddb mm4, mm5 + movq mm6, [edi+ebx+56] + movq [edi+ebx+48], mm4 + add ebx, 64 + paddb mm6, mm7 + cmp ebx, ecx + movq [edi+ebx-8], mm6 // (+56)movq does not affect flags; + // -8 to offset add ebx + jb duploop + + cmp edx, 0 // Test for bytes over mult of 64 + jz dupend + + + // 2 lines added by lcreeve at netins.net + // (mail 11 Jul 98 in png-implement list) + cmp edx, 8 //test for less than 8 bytes + jb duplt8 + + + add ecx, edx + and edx, 0x00000007 // calc bytes over mult of 8 + sub ecx, edx // drop over bytes from length + jz duplt8 + // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously +duplpA: + movq mm1, [esi+ebx] + movq mm0, [edi+ebx] + add ebx, 8 + paddb mm0, mm1 + cmp ebx, ecx + movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx + jb duplpA + cmp edx, 0 // Test for bytes over mult of 8 + jz dupend +duplt8: + xor eax, eax + add ecx, edx // move over byte count into counter + // Loop using x86 registers to update remaining bytes +duplp2: + mov al, [edi + ebx] + add al, [esi + ebx] + inc ebx + cmp ebx, ecx + mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx + jb duplp2 +dupend: + // Conversion of filtered row completed + emms // End MMX instructions; prep for possible FP instrs. + } // end _asm block +} + + +// Optimized png_read_filter_row routines +void /* PRIVATE */ +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep + row, png_bytep prev_row, int filter) +{ +#ifdef PNG_DEBUG + char filnm[10]; +#endif + + if (mmx_supported == 2) { +#if !defined(PNG_1_0_X) + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif + png_mmx_support(); + } + +#ifdef PNG_DEBUG + png_debug(1, "in png_read_filter_row\n"); + switch (filter) + { + case 0: sprintf(filnm, "none"); + break; +#if !defined(PNG_1_0_X) + case 1: sprintf(filnm, "sub-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86"); + break; + case 2: sprintf(filnm, "up-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86"); + break; + case 3: sprintf(filnm, "avg-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86"); + break; + case 4: sprintf(filnm, "Paeth-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); + break; +#else + case 1: sprintf(filnm, "sub"); + break; + case 2: sprintf(filnm, "up"); + break; + case 3: sprintf(filnm, "avg"); + break; + case 4: sprintf(filnm, "Paeth"); + break; +#endif + default: sprintf(filnm, "unknw"); + break; + } + png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm); + png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth, + (int)((row_info->pixel_depth + 7) >> 3)); + png_debug1(0,"len=%8d, ", row_info->rowbytes); +#endif /* PNG_DEBUG */ + + switch (filter) + { + case PNG_FILTER_VALUE_NONE: + break; + + case PNG_FILTER_VALUE_SUB: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_sub(row_info, row); + } + else + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + png_bytep lp = row; + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_UP: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_up(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + png_bytep rp = row; + png_bytep pp = prev_row; + + for (i = 0; i < istop; ++i) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_AVG: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_avg(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) >> 1)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++ + *lp++) >> 1)) & 0xff); + rp++; + } + } + break; + } + + case PNG_FILTER_VALUE_PAETH: + { +#if !defined(PNG_1_0_X) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && + (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && + (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (mmx_supported) +#endif + { + png_read_filter_row_mmx_paeth(row_info, row, prev_row); + } + else + { + png_uint_32 i; + png_bytep rp = row; + png_bytep pp = prev_row; + png_bytep lp = row; + png_bytep cp = prev_row; + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_uint_32 istop=row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + for (i = 0; i < istop; i++) // use leftover rp,pp + { + int a, b, c, pa, pb, pc, p; + + a = *lp++; + b = *pp++; + c = *cp++; + + 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 + + /* + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + */ + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *rp = (png_byte)(((int)(*rp) + p) & 0xff); + rp++; + } + } + break; + } + + default: + png_warning(png_ptr, "Ignoring bad row filter type"); + *row=0; + break; + } +} + +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGVCRD */ diff --git a/src/dep/src/irrlicht/libpng/pngwio.c b/src/dep/src/irrlicht/libpng/pngwio.c new file mode 100644 index 0000000..f40bccb --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngwio.c @@ -0,0 +1,234 @@ + +/* pngwio.c - functions for data output + * + * 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-2002 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 output. Users who need + * special handling are expected to write functions that have the same + * arguments as these and perform similar functions, but that possibly + * use different output methods. Note that you shouldn't change these + * functions, but rather write replacement functions and then change + * them at run time with png_set_write_fn(...). + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Write the data to whatever output you are using. The default routine + writes to a file pointer. Note that this routine sometimes gets called + with very small lengths, so you should implement some kind of simple + buffering if you are using unbuffered writes. This should never be asked + to write more than 64K on a 16 bit machine. */ + +void /* PRIVATE */ +png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + if (png_ptr->write_data_fn != NULL ) + (*(png_ptr->write_data_fn))(png_ptr, data, length); + else + png_error(png_ptr, "Call to NULL write function"); +} + +#if !defined(PNG_NO_STDIO) +/* This is the function that does the actual writing of data. If you are + not writing to a standard C stream, you should create a replacement + write_data function and use it at run time with png_set_write_fn(), rather + than changing the library. */ +#ifndef USE_FAR_KEYWORD +void PNGAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + + if(png_ptr == NULL) return; +#if defined(_WIN32_WCE) + if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) + check = 0; +#else + check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); +#endif + if (check != length) + png_error(png_ptr, "Write 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) + +void PNGAPI +png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_uint_32 check; + png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ + png_FILE_p io_ptr; + + if(png_ptr == NULL) return; + /* Check if data really is near. If so, use usual code. */ + near_data = (png_byte *)CVT_PTR_NOCHECK(data); + io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)near_data == data) + { +#if defined(_WIN32_WCE) + if ( !WriteFile(io_ptr, near_data, length, &check, NULL) ) + check = 0; +#else + check = fwrite(near_data, 1, length, io_ptr); +#endif + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t written, remaining, err; + check = 0; + remaining = length; + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* copy far buffer to near buffer */ +#if defined(_WIN32_WCE) + if ( !WriteFile(io_ptr, buf, written, &err, NULL) ) + err = 0; +#else + err = fwrite(buf, 1, written, io_ptr); +#endif + if (err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + while (remaining != 0); + } + if (check != length) + png_error(png_ptr, "Write Error"); +} + +#endif +#endif + +/* This function is called to output any data pending writing (normally + to disk). After png_flush is called, there should be no data pending + writing in any buffers. */ +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +void /* PRIVATE */ +png_flush(png_structp png_ptr) +{ + if (png_ptr->output_flush_fn != NULL) + (*(png_ptr->output_flush_fn))(png_ptr); +} + +#if !defined(PNG_NO_STDIO) +void PNGAPI +png_default_flush(png_structp png_ptr) +{ +#if !defined(_WIN32_WCE) + png_FILE_p io_ptr; +#endif + if(png_ptr == NULL) return; +#if !defined(_WIN32_WCE) + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +#endif +} +#endif +#endif + +/* This function allows the application to supply new output functions for + libpng if standard C streams aren't being used. + + This function takes as its arguments: + png_ptr - pointer to a png output data structure + io_ptr - pointer to user supplied structure containing info about + the output functions. May be NULL. + write_data_fn - pointer to a new output function that takes as its + arguments a pointer to a png_struct, a pointer to + data to be written, and a 32-bit unsigned int that is + the number of bytes to be written. The new write + function should call png_error(png_ptr, "Error msg") + to exit and output any fatal error messages. + flush_data_fn - pointer to a new flush function that takes as its + arguments a pointer to a png_struct. After a call to + the flush function, there should be no data in any buffers + or pending transmission. If the output method doesn't do + any buffering of ouput, a function prototype must still be + supplied although it doesn't have to do anything. If + PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile + time, output_flush_fn will be ignored, although it must be + supplied for compatibility. */ +void PNGAPI +png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) +{ + if(png_ptr == NULL) return; + png_ptr->io_ptr = io_ptr; + +#if !defined(PNG_NO_STDIO) + if (write_data_fn != NULL) + png_ptr->write_data_fn = write_data_fn; + else + png_ptr->write_data_fn = png_default_write_data; +#else + png_ptr->write_data_fn = write_data_fn; +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) + if (output_flush_fn != NULL) + png_ptr->output_flush_fn = output_flush_fn; + else + png_ptr->output_flush_fn = png_default_flush; +#else + png_ptr->output_flush_fn = output_flush_fn; +#endif +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { + png_ptr->read_data_fn = NULL; + png_warning(png_ptr, + "Attempted to set both read_data_fn and write_data_fn in"); + png_warning(png_ptr, + "the same structure. Resetting read_data_fn to NULL."); + } +} + +#if defined(USE_FAR_KEYWORD) +#if defined(_MSC_VER) +void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + FP_OFF(near_ptr) = FP_OFF(ptr); + far_ptr = (void FAR *)near_ptr; + if(check != 0) + if(FP_SEG(ptr) != FP_SEG(far_ptr)) + png_error(png_ptr,"segment lost in conversion"); + return(near_ptr); +} +# else +void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +{ + void *near_ptr; + void FAR *far_ptr; + near_ptr = (void FAR *)ptr; + far_ptr = (void FAR *)near_ptr; + if(check != 0) + if(far_ptr != ptr) + png_error(png_ptr,"segment lost in conversion"); + return(near_ptr); +} +# endif +# endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngwrite.c b/src/dep/src/irrlicht/libpng/pngwrite.c new file mode 100644 index 0000000..b4fd7df --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngwrite.c @@ -0,0 +1,1518 @@ + +/* pngwrite.c - general routines to write a PNG file + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + */ + +/* get internal access to png.h */ +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Writes all the PNG information. This is the suggested way to use the + * library. If you have a new chunk to add, make a function to write it, + * and put it in the correct location here. If you want the chunk written + * after the image data, put it in png_write_end(). I strongly encourage + * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing + * the chunk, as that will keep the code from breaking if you want to just + * write a plain PNG file. If you have long comments, I suggest writing + * them in png_write_end(), and compressing them. + */ +void PNGAPI +png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_info_before_PLTE\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + { + png_write_sig(png_ptr); /* write PNG signature */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted)) + { + png_warning(png_ptr,"MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted=0; + } +#endif + /* write IHDR information. */ + png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + info_ptr->interlace_type); +#else + 0); +#endif + /* the rest of these check to see if the valid field has the appropriate + flag set, and if it does, writes the chunk. */ +#if defined(PNG_WRITE_gAMA_SUPPORTED) + if (info_ptr->valid & PNG_INFO_gAMA) + { +# ifdef PNG_FLOATING_POINT_SUPPORTED + png_write_gAMA(png_ptr, info_ptr->gamma); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); +# endif +#endif + } +#endif +#if defined(PNG_WRITE_sRGB_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sRGB) + png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); +#endif +#if defined(PNG_WRITE_iCCP_SUPPORTED) + if (info_ptr->valid & PNG_INFO_iCCP) + png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, + info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +#endif +#if defined(PNG_WRITE_sBIT_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sBIT) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); +#endif +#if defined(PNG_WRITE_cHRM_SUPPORTED) + if (info_ptr->valid & PNG_INFO_cHRM) + { +#ifdef PNG_FLOATING_POINT_SUPPORTED + png_write_cHRM(png_ptr, + info_ptr->x_white, info_ptr->y_white, + info_ptr->x_red, info_ptr->y_red, + info_ptr->x_green, info_ptr->y_green, + info_ptr->x_blue, info_ptr->y_blue); +#else +# ifdef PNG_FIXED_POINT_SUPPORTED + png_write_cHRM_fixed(png_ptr, + info_ptr->int_x_white, info_ptr->int_y_white, + info_ptr->int_x_red, info_ptr->int_y_red, + info_ptr->int_x_green, info_ptr->int_y_green, + info_ptr->int_x_blue, info_ptr->int_y_blue); +# endif +#endif + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && !(up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void PNGAPI +png_write_info(png_structp png_ptr, png_infop info_ptr) +{ +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) + int i; +#endif + + png_debug(1, "in png_write_info\n"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_write_info_before_PLTE(png_ptr, info_ptr); + + if (info_ptr->valid & PNG_INFO_PLTE) + png_write_PLTE(png_ptr, info_ptr->palette, + (png_uint_32)info_ptr->num_palette); + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Valid palette required for paletted images"); + +#if defined(PNG_WRITE_tRNS_SUPPORTED) + if (info_ptr->valid & PNG_INFO_tRNS) + { +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel (in tRNS) */ + if ((png_ptr->transformations & PNG_INVERT_ALPHA) && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j; + for (j=0; j<(int)info_ptr->num_trans; j++) + info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); + } +#endif + png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values), + info_ptr->num_trans, info_ptr->color_type); + } +#endif +#if defined(PNG_WRITE_bKGD_SUPPORTED) + if (info_ptr->valid & PNG_INFO_bKGD) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); +#endif +#if defined(PNG_WRITE_hIST_SUPPORTED) + if (info_ptr->valid & PNG_INFO_hIST) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); +#endif +#if defined(PNG_WRITE_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) + png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, + info_ptr->offset_unit_type); +#endif +#if defined(PNG_WRITE_pCAL_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pCAL) + png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); +#endif +#if defined(PNG_WRITE_sCAL_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sCAL) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) + png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); +#else + png_warning(png_ptr, + "png_write_sCAL not supported; sCAL chunk not written."); +#endif +#endif +#endif +#if defined(PNG_WRITE_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) + png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); +#endif +#if defined(PNG_WRITE_tIME_SUPPORTED) + if (info_ptr->valid & PNG_INFO_tIME) + { + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + png_ptr->mode |= PNG_WROTE_tIME; + } +#endif +#if defined(PNG_WRITE_sPLT_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sPLT) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); +#endif +#if defined(PNG_WRITE_TEXT_SUPPORTED) + /* Check to see if we need to write text chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing header text chunk %d, type %d\n", i, + info_ptr->text[i].compression); + /* an internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#if defined(PNG_WRITE_iTXt_SUPPORTED) + /* write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + /* If we want a compressed text chunk */ + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) + { +#if defined(PNG_WRITE_zTXt_SUPPORTED) + /* write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#if defined(PNG_WRITE_tEXt_SUPPORTED) + /* write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, + 0); +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && (up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif +} + +/* Writes the end of the PNG file. If you don't want to write comments or + * time information, you can pass NULL for info. If you already wrote these + * in png_write_info(), do not write them again here. If you have long + * comments, I suggest writing them here, and compressing them. + */ +void PNGAPI +png_write_end(png_structp png_ptr, png_infop info_ptr) +{ + png_debug(1, "in png_write_end\n"); + if (png_ptr == NULL) + return; + if (!(png_ptr->mode & PNG_HAVE_IDAT)) + png_error(png_ptr, "No IDATs written into file"); + + /* see if user wants us to write information chunks */ + if (info_ptr != NULL) + { +#if defined(PNG_WRITE_TEXT_SUPPORTED) + int i; /* local index variable */ +#endif +#if defined(PNG_WRITE_tIME_SUPPORTED) + /* check to see if user has supplied a time chunk */ + if ((info_ptr->valid & PNG_INFO_tIME) && + !(png_ptr->mode & PNG_WROTE_tIME)) + png_write_tIME(png_ptr, &(info_ptr->mod_time)); +#endif +#if defined(PNG_WRITE_TEXT_SUPPORTED) + /* loop through comment chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing trailer text chunk %d, type %d\n", i, + info_ptr->text[i].compression); + /* an internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#if defined(PNG_WRITE_iTXt_SUPPORTED) + /* write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) + { +#if defined(PNG_WRITE_zTXt_SUPPORTED) + /* write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#if defined(PNG_WRITE_tEXt_SUPPORTED) + /* write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0); +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } +#endif +#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) + if (info_ptr->unknown_chunks_num) + { + png_unknown_chunk *up; + + png_debug(5, "writing extra chunks\n"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { + int keep=png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && + up->location && (up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + { + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +#endif + } + + png_ptr->mode |= PNG_AFTER_IDAT; + + /* write end of PNG file */ + png_write_IEND(png_ptr); +#if 0 +/* This flush, added in libpng-1.0.8, causes some applications to crash + because they do not set png_ptr->output_flush_fn */ + png_flush(png_ptr); +#endif +} + +#if defined(PNG_WRITE_tIME_SUPPORTED) +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) +{ + png_debug(1, "in png_convert_from_struct_tm\n"); + ptime->year = (png_uint_16)(1900 + ttime->tm_year); + ptime->month = (png_byte)(ttime->tm_mon + 1); + ptime->day = (png_byte)ttime->tm_mday; + ptime->hour = (png_byte)ttime->tm_hour; + ptime->minute = (png_byte)ttime->tm_min; + ptime->second = (png_byte)ttime->tm_sec; +} + +void PNGAPI +png_convert_from_time_t(png_timep ptime, time_t ttime) +{ + struct tm *tbuf; + + png_debug(1, "in png_convert_from_time_t\n"); + tbuf = gmtime(&ttime); + png_convert_from_struct_tm(ptime, tbuf); +} +#endif +#endif + +/* Initialize png_ptr structure, and allocate any memory needed */ +png_structp PNGAPI +png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn) +{ +#ifdef PNG_USER_MEM_SUPPORTED + return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); +} + +/* Alternate initialize png_ptr structure, and allocate any memory needed */ +png_structp PNGAPI +png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn) +{ +#endif /* PNG_USER_MEM_SUPPORTED */ + png_structp png_ptr; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + int i; + png_debug(1, "in png_create_write_struct\n"); +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +#else + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +#endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL) + return (NULL); + +#if !defined(PNG_1_0_X) +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#ifdef PNG_MMX_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif +#endif /* PNG_1_0_X */ + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_ptr->jmpbuf)) +#endif + { + png_free(png_ptr, png_ptr->zbuf); + png_ptr->zbuf=NULL; + png_destroy_struct(png_ptr); + return (NULL); + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#endif +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +#endif /* PNG_USER_MEM_SUPPORTED */ + png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); + + i=0; + do + { + if(user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || + (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[80]; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); +#endif +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "Incompatible libpng version in application and library"); + } + } + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + + png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, + png_flush_ptr_NULL); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, + 1, png_doublep_NULL, png_doublep_NULL); +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif + return (png_ptr); +} + +/* Initialize png_ptr structure, and allocate any memory needed */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Deprecated. */ +#undef png_write_init +void PNGAPI +png_write_init(png_structp png_ptr) +{ + /* We only come here via pre-1.0.7-compiled applications */ + png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0); +} + +void PNGAPI +png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size, png_size_t png_info_size) +{ + /* We only come here via pre-1.0.12-compiled applications */ + if(png_ptr == NULL) return; +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + if(png_sizeof(png_struct) > png_struct_size || + png_sizeof(png_info) > png_info_size) + { + char msg[80]; + png_ptr->warning_fn=NULL; + if (user_png_ver) + { + sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + user_png_ver); + png_warning(png_ptr, msg); + } + sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_libpng_ver); + png_warning(png_ptr, msg); + } +#endif + if(png_sizeof(png_struct) > png_struct_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The png struct allocated by the application for writing is too small."); + } + if(png_sizeof(png_info) > png_info_size) + { + png_ptr->error_fn=NULL; +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + png_ptr->flags=0; +#endif + png_error(png_ptr, + "The info struct allocated by the application for writing is too small."); + } + png_write_init_3(&png_ptr, user_png_ver, png_struct_size); +} +#endif /* PNG_1_0_X || PNG_1_2_X */ + + +void PNGAPI +png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, + png_size_t png_struct_size) +{ + png_structp png_ptr=*ptr_ptr; +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* to save current jump buffer */ +#endif + + int i = 0; + + if (png_ptr == NULL) + return; + + do + { + if (user_png_ver[i] != png_libpng_ver[i]) + { +#ifdef PNG_LEGACY_SUPPORTED + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; +#else + png_ptr->warning_fn=NULL; + png_warning(png_ptr, + "Application uses deprecated png_write_init() and should be recompiled."); + break; +#endif + } + } while (png_libpng_ver[i++]); + + png_debug(1, "in png_write_init_3\n"); + +#ifdef PNG_SETJMP_SUPPORTED + /* save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + if (png_sizeof(png_struct) > png_struct_size) + { + png_destroy_struct(png_ptr); + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); + *ptr_ptr = png_ptr; + } + + /* reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + /* added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_ptr->user_width_max=PNG_USER_WIDTH_MAX; + png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; +#endif + +#if !defined(PNG_1_0_X) +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#ifdef PNG_MMX_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif +#endif +#endif /* PNG_1_0_X */ + +#ifdef PNG_SETJMP_SUPPORTED + /* restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif + + png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, + png_flush_ptr_NULL); + + /* initialize zbuf - compression buffer */ + png_ptr->zbuf_size = PNG_ZBUF_SIZE; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, + 1, png_doublep_NULL, png_doublep_NULL); +#endif +} + +/* Write a few rows of image data. If the image is interlaced, + * either you will have to write the 7 sub images, or, if you + * have called png_set_interlace_handling(), you will have to + * "write" the image seven times. + */ +void PNGAPI +png_write_rows(png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows) +{ + png_uint_32 i; /* row counter */ + png_bytepp rp; /* row pointer */ + + png_debug(1, "in png_write_rows\n"); + + if (png_ptr == NULL) + return; + + /* loop through the rows */ + for (i = 0, rp = row; i < num_rows; i++, rp++) + { + png_write_row(png_ptr, *rp); + } +} + +/* Write the image. You only need to call this function once, even + * if you are writing an interlaced image. + */ +void PNGAPI +png_write_image(png_structp png_ptr, png_bytepp image) +{ + png_uint_32 i; /* row index */ + int pass, num_pass; /* pass variables */ + png_bytepp rp; /* points to current row */ + + if (png_ptr == NULL) + return; + + png_debug(1, "in png_write_image\n"); +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* intialize interlace handling. If image is not interlaced, + this will set pass to 1 */ + num_pass = png_set_interlace_handling(png_ptr); +#else + num_pass = 1; +#endif + /* loop through passes */ + for (pass = 0; pass < num_pass; pass++) + { + /* loop through image */ + for (i = 0, rp = image; i < png_ptr->height; i++, rp++) + { + png_write_row(png_ptr, *rp); + } + } +} + +/* called by user to write a row of image data */ +void PNGAPI +png_write_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr == NULL) + return; + png_debug2(1, "in png_write_row (row %ld, pass %d)\n", + png_ptr->row_number, png_ptr->pass); + + /* initialize transformations and other stuff if first time */ + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* make sure we wrote the header info */ + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + png_error(png_ptr, + "png_write_info was never called before png_write_row."); + + /* check for transforms that have been set but were defined out */ +#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined."); +#endif +#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined."); +#endif + + png_write_start_row(png_ptr); + } + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* if interlaced and not interested in row, return */ + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 3: + if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 4: + if ((png_ptr->row_number & 0x03) != 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 5: + if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + case 6: + if (!(png_ptr->row_number & 0x01)) + { + png_write_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + /* set up row info for transformations */ + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->usr_width; + png_ptr->row_info.channels = png_ptr->usr_channels; + png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; + png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * + png_ptr->row_info.channels); + + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, + png_ptr->row_info.width); + + png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type); + png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width); + png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels); + png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ + png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row, + png_ptr->row_info.rowbytes); + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) + /* handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && + (png_ptr->transformations & PNG_INTERLACE)) + { + png_do_write_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass); + /* this should always get caught above, but still ... */ + if (!(png_ptr->row_info.width)) + { + png_write_finish_row(png_ptr); + return; + } + } +#endif + + /* handle other transformations */ + if (png_ptr->transformations) + png_do_write_transformations(png_ptr); + +#if defined(PNG_MNG_FEATURES_SUPPORTED) + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +#endif + + /* Find a filter if necessary, filter the row and write it out. */ + png_write_find_filter(png_ptr, &(png_ptr->row_info)); + + if (png_ptr->write_row_fn != NULL) + (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set the automatic flush interval or 0 to turn flushing off */ +void PNGAPI +png_set_flush(png_structp png_ptr, int nrows) +{ + png_debug(1, "in png_set_flush\n"); + if (png_ptr == NULL) + return; + png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); +} + +/* flush the current output buffers now */ +void PNGAPI +png_write_flush(png_structp png_ptr) +{ + int wrote_IDAT; + + png_debug(1, "in png_write_flush\n"); + if (png_ptr == NULL) + return; + /* We have already written out all of the data */ + if (png_ptr->row_number >= png_ptr->num_rows) + return; + + do + { + int ret; + + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); + wrote_IDAT = 0; + + /* check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + + if (!(png_ptr->zstream.avail_out)) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + wrote_IDAT = 1; + } + } while(wrote_IDAT == 1); + + /* If there is any data left to be output, write it into a new IDAT */ + if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + png_ptr->flush_rows = 0; + png_flush(png_ptr); +} +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ + +/* free all memory used by the write */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn = NULL; + png_voidp mem_ptr = NULL; +#endif + + png_debug(1, "in png_destroy_write_struct\n"); + if (png_ptr_ptr != NULL) + { + png_ptr = *png_ptr_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif + } + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + png_ptr->num_chunk_list=0; + } +#endif + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)info_ptr); +#endif + *info_ptr_ptr = NULL; + } + + if (png_ptr != NULL) + { + png_write_destroy(png_ptr); +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, + (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif + *png_ptr_ptr = NULL; + } +} + + +/* Free any memory used in png_ptr struct (old method) */ +void /* PRIVATE */ +png_write_destroy(png_structp png_ptr) +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf tmp_jmp; /* save jump buffer */ +#endif + png_error_ptr error_fn; + png_error_ptr warning_fn; + png_voidp error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_free_ptr free_fn; +#endif + + png_debug(1, "in png_write_destroy\n"); + /* free any memory zlib uses */ + deflateEnd(&png_ptr->zstream); + + /* free our memory. png_free checks NULL for us. */ + png_free(png_ptr, png_ptr->zbuf); + png_free(png_ptr, png_ptr->row_buf); + png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->sub_row); + png_free(png_ptr, png_ptr->up_row); + png_free(png_ptr, png_ptr->avg_row); + png_free(png_ptr, png_ptr->paeth_row); + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_free(png_ptr, png_ptr->time_buffer); +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_free(png_ptr, png_ptr->prev_filters); + png_free(png_ptr, png_ptr->filter_weights); + png_free(png_ptr, png_ptr->inv_filter_weights); + png_free(png_ptr, png_ptr->filter_costs); + png_free(png_ptr, png_ptr->inv_filter_costs); +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* reset structure */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); +#endif + + error_fn = png_ptr->error_fn; + warning_fn = png_ptr->warning_fn; + error_ptr = png_ptr->error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; +#endif + + png_memset(png_ptr, 0, png_sizeof (png_struct)); + + png_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; + png_ptr->error_ptr = error_ptr; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif + +#ifdef PNG_SETJMP_SUPPORTED + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); +#endif +} + +/* Allow the application to select one or more row filters to use. */ +void PNGAPI +png_set_filter(png_structp png_ptr, int method, int filters) +{ + png_debug(1, "in png_set_filter\n"); + if (png_ptr == NULL) + return; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; +#endif + if (method == PNG_FILTER_TYPE_BASE) + { + switch (filters & (PNG_ALL_FILTERS | 0x07)) + { + case 5: + case 6: + case 7: png_warning(png_ptr, "Unknown row filter for method 0"); + case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break; + case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break; + case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break; + case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break; + case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break; + default: png_ptr->do_filter = (png_byte)filters; break; + } + + /* If we have allocated the row_buf, this means we have already started + * with the image and we should have allocated all of the filter buffers + * that have been selected. If prev_row isn't already allocated, then + * it is too late to start using the filters that need it, since we + * will be missing the data in the previous row. If an application + * wants to start and stop using particular filters during compression, + * it should start out with all of the filters, and then add and + * remove them after the start of compression. + */ + if (png_ptr->row_buf != NULL) + { + if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Up filter after starting"); + png_ptr->do_filter &= ~PNG_FILTER_UP; + } + else + { + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Average filter after starting"); + png_ptr->do_filter &= ~PNG_FILTER_AVG; + } + else + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + } + + if ((png_ptr->do_filter & PNG_FILTER_PAETH) && + png_ptr->paeth_row == NULL) + { + if (png_ptr->prev_row == NULL) + { + png_warning(png_ptr, "Can't add Paeth filter after starting"); + png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); + } + else + { + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } + + if (png_ptr->do_filter == PNG_NO_FILTERS) + png_ptr->do_filter = PNG_FILTER_NONE; + } + } + else + png_error(png_ptr, "Unknown custom filter method"); +} + +/* This allows us to influence the way in which libpng chooses the "best" + * filter for the current scanline. While the "minimum-sum-of-absolute- + * differences metric is relatively fast and effective, there is some + * question as to whether it can be improved upon by trying to keep the + * filtered data going to zlib more consistent, hopefully resulting in + * better compression. + */ +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */ +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_doublep filter_weights, + png_doublep filter_costs) +{ + int i; + + png_debug(1, "in png_set_filter_heuristics\n"); + if (png_ptr == NULL) + return; + if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return; + } + + if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) + { + heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + } + + if (num_weights < 0 || filter_weights == NULL || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) + { + num_weights = 0; + } + + png_ptr->num_prev_filters = (png_byte)num_weights; + png_ptr->heuristic_method = (png_byte)heuristic_method; + + if (num_weights > 0) + { + if (png_ptr->prev_filters == NULL) + { + png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_byte) * num_weights)); + + /* To make sure that the weighting starts out fairly */ + for (i = 0; i < num_weights; i++) + { + png_ptr->prev_filters[i] = 255; + } + } + + if (png_ptr->filter_weights == NULL) + { + png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + for (i = 0; i < num_weights; i++) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + } + + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] < 0.0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + else + { + png_ptr->inv_filter_weights[i] = + (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); + png_ptr->filter_weights[i] = + (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); + } + } + } + + /* If, in the future, there are other filter methods, this would + * need to be based on png_ptr->filter. + */ + if (png_ptr->filter_costs == NULL) + { + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + { + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + { + if (filter_costs == NULL || filter_costs[i] < 0.0) + { + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; + } + else if (filter_costs[i] >= 1.0) + { + png_ptr->inv_filter_costs[i] = + (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); + png_ptr->filter_costs[i] = + (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); + } + } +} +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +void PNGAPI +png_set_compression_level(png_structp png_ptr, int level) +{ + png_debug(1, "in png_set_compression_level\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; + png_ptr->zlib_level = level; +} + +void PNGAPI +png_set_compression_mem_level(png_structp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_compression_mem_level\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; + png_ptr->zlib_mem_level = mem_level; +} + +void PNGAPI +png_set_compression_strategy(png_structp png_ptr, int strategy) +{ + png_debug(1, "in png_set_compression_strategy\n"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; +} + +void PNGAPI +png_set_compression_window_bits(png_structp png_ptr, int window_bits) +{ + if (png_ptr == NULL) + return; + if (window_bits > 15) + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + else if (window_bits < 8) + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); +#ifndef WBITS_8_OK + /* avoid libpng bug with 256-byte windows */ + if (window_bits == 8) + { + png_warning(png_ptr, "Compression window is being reset to 512"); + window_bits=9; + } +#endif + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; + png_ptr->zlib_window_bits = window_bits; +} + +void PNGAPI +png_set_compression_method(png_structp png_ptr, int method) +{ + png_debug(1, "in png_set_compression_method\n"); + if (png_ptr == NULL) + return; + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; + png_ptr->zlib_method = method; +} + +void PNGAPI +png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) +{ + if (png_ptr == NULL) + return; + png_ptr->write_row_fn = write_row_fn; +} + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +void PNGAPI +png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr + write_user_transform_fn) +{ + png_debug(1, "in png_set_write_user_transform_fn\n"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->write_user_transform_fn = write_user_transform_fn; +} +#endif + + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +void PNGAPI +png_write_png(png_structp png_ptr, png_infop info_ptr, + int transforms, voidp params) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + /* invert the alpha channel from opacity to transparency */ + if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); +#endif + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + +#if defined(PNG_WRITE_INVERT_SUPPORTED) + /* invert monochrome pixels */ + if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + if ((transforms & PNG_TRANSFORM_SHIFT) + && (info_ptr->valid & PNG_INFO_sBIT)) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) + /* pack pixels into bytes */ + if (transforms & PNG_TRANSFORM_PACKING) + png_set_packing(png_ptr); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) + /* swap location of alpha bytes from ARGB to RGBA */ + if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) + /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into + * RGB (4 channels -> 3 channels). The second parameter is not used. + */ + if (transforms & PNG_TRANSFORM_STRIP_FILLER) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#endif + +#if defined(PNG_WRITE_BGR_SUPPORTED) + /* flip BGR pixels to RGB */ + if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); +#endif + +#if defined(PNG_WRITE_SWAP_SUPPORTED) + /* swap bytes of 16-bit files to most significant byte first */ + if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); +#endif + +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) + /* swap bits of 1, 2, 4 bit packed pixel formats */ + if (transforms & PNG_TRANSFORM_PACKSWAP) + png_set_packswap(png_ptr); +#endif + + /* ----------------------- end of transformations ------------------- */ + + /* write the bits */ + if (info_ptr->valid & PNG_INFO_IDAT) + png_write_image(png_ptr, info_ptr->row_pointers); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + if(transforms == 0 || params == NULL) + /* quiet compiler warnings */ return; +} +#endif +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngwtran.c b/src/dep/src/irrlicht/libpng/pngwtran.c new file mode 100644 index 0000000..19b2968 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngwtran.c @@ -0,0 +1,572 @@ + +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Last changed in libpng 1.2.9 April 14, 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.) + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ +void /* PRIVATE */ +png_do_write_transformations(png_structp png_ptr) +{ + png_debug(1, "in png_do_write_transformations\n"); + + if (png_ptr == NULL) + return; + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + if (png_ptr->transformations & PNG_USER_TRANSFORM) + if(png_ptr->write_user_transform_fn != NULL) + (*(png_ptr->write_user_transform_fn)) /* user write transform function */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_uint_32 rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#endif +#if defined(PNG_WRITE_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->flags); +#endif +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) + if (png_ptr->transformations & PNG_PACKSWAP) + png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_PACK_SUPPORTED) + if (png_ptr->transformations & PNG_PACK) + png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif +#if defined(PNG_WRITE_SWAP_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) + if (png_ptr->transformations & PNG_SHIFT) + png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_SWAP_ALPHA) + png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_ALPHA) + png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_BGR_SUPPORTED) + if (png_ptr->transformations & PNG_BGR) + png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_INVERT_SUPPORTED) + if (png_ptr->transformations & PNG_INVERT_MONO) + png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +} + +#if defined(PNG_WRITE_PACK_SUPPORTED) +/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The + * row_info bit depth should be 8 (one pixel per byte). The channels + * should be 1 (this only happens on grayscale and paletted images). + */ +void /* PRIVATE */ +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) +{ + png_debug(1, "in png_do_pack\n"); + if (row_info->bit_depth == 8 && +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + row_info->channels == 1) + { + switch ((int)bit_depth) + { + case 1: + { + png_bytep sp, dp; + int mask, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + mask = 0x80; + v = 0; + + for (i = 0; i < row_width; i++) + { + if (*sp != 0) + v |= mask; + sp++; + if (mask > 1) + mask >>= 1; + else + { + mask = 0x80; + *dp = (png_byte)v; + dp++; + v = 0; + } + } + if (mask != 0x80) + *dp = (png_byte)v; + break; + } + case 2: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 6; + v = 0; + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x03); + v |= (value << shift); + if (shift == 0) + { + shift = 6; + *dp = (png_byte)v; + dp++; + v = 0; + } + else + shift -= 2; + sp++; + } + if (shift != 6) + *dp = (png_byte)v; + break; + } + case 4: + { + png_bytep sp, dp; + int shift, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 4; + v = 0; + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x0f); + v |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp = (png_byte)v; + dp++; + v = 0; + } + else + shift -= 4; + + sp++; + } + if (shift != 4) + *dp = (png_byte)v; + break; + } + } + row_info->bit_depth = (png_byte)bit_depth; + row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Shift pixel values to take advantage of whole range. Pass the + * true number of bits in bit_depth. The row should be packed + * according to row_info->bit_depth. Thus, if you had a row of + * bit depth 4, but the pixels only had values from 0 to 7, you + * would pass 3 as bit_depth, and this routine would translate the + * data to 0 to 15. + */ +void /* PRIVATE */ +png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) +{ + png_debug(1, "in png_do_shift\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && +#else + if ( +#endif + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift_start[4], shift_dec[4]; + int channels = 0; + + if (row_info->color_type & PNG_COLOR_MASK_COLOR) + { + shift_start[channels] = row_info->bit_depth - bit_depth->red; + shift_dec[channels] = bit_depth->red; + channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->green; + shift_dec[channels] = bit_depth->green; + channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->blue; + shift_dec[channels] = bit_depth->blue; + channels++; + } + else + { + shift_start[channels] = row_info->bit_depth - bit_depth->gray; + shift_dec[channels] = bit_depth->gray; + channels++; + } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + { + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; + shift_dec[channels] = bit_depth->alpha; + channels++; + } + + /* with low row depths, could only be grayscale, so one channel */ + if (row_info->bit_depth < 8) + { + png_bytep bp = row; + png_uint_32 i; + png_byte mask; + png_uint_32 row_bytes = row_info->rowbytes; + + if (bit_depth->gray == 1 && row_info->bit_depth == 2) + mask = 0x55; + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) + mask = 0x11; + else + mask = 0xff; + + for (i = 0; i < row_bytes; i++, bp++) + { + png_uint_16 v; + int j; + + v = *bp; + *bp = 0; + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + else + *bp |= (png_byte)((v >> (-j)) & mask); + } + } + } + else if (row_info->bit_depth == 8) + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (i = 0; i < istop; i++, bp++) + { + + png_uint_16 v; + int j; + int c = (int)(i%channels); + + v = *bp; + *bp = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + *bp |= (png_byte)((v << j) & 0xff); + else + *bp |= (png_byte)((v >> (-j)) & 0xff); + } + } + } + else + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (bp = row, i = 0; i < istop; i++) + { + int c = (int)(i%channels); + png_uint_16 value, v; + int j; + + v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); + value = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); + else + value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); + } + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } + } + } +} +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_swap_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from ARGB to RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + /* This converts from AARRGGBB to RRGGBBAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from AG to GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + /* This converts from AAGG to GGAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } + } + } +} +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void /* PRIVATE */ +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_invert_alpha\n"); +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL) +#endif + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This inverts the alpha channel in RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=3; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=6; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This inverts the alpha channel in GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + *(dp++) = *(sp++); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + /* This inverts the alpha channel in GGAA */ + else + { + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=2; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + } + } +} +#endif + +#if defined(PNG_MNG_FEATURES_SUPPORTED) +/* undoes intrapixel differencing */ +void /* PRIVATE */ +png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_intrapixel\n"); + if ( +#if defined(PNG_USELESS_TESTS_SUPPORTED) + row != NULL && row_info != NULL && +#endif + (row_info->color_type & PNG_COLOR_MASK_COLOR)) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((*rp - *(rp+1))&0xff); + *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); + png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); + png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); + png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp+1) = (png_byte)(red & 0xff); + *(rp+4) = (png_byte)((blue >> 8) & 0xff); + *(rp+5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/pngwutil.c b/src/dep/src/irrlicht/libpng/pngwutil.c new file mode 100644 index 0000000..4e5b75b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/pngwutil.c @@ -0,0 +1,2778 @@ + +/* pngwutil.c - utilities to write a PNG file + * + * Last changed in libpng 1.2.15 January 5, 2007 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2007 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.) + */ + +#define PNG_INTERNAL +#include "png.h" +#ifdef PNG_WRITE_SUPPORTED + +/* Place a 32-bit number into a buffer in PNG byte order. We work + * with unsigned numbers for convenience, although one supported + * ancillary chunk uses signed (two's complement) numbers. + */ +void PNGAPI +png_save_uint_32(png_bytep buf, png_uint_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} + +/* The png_save_int_32 function assumes integers are stored in two's + * complement format. If this isn't the case, then this routine needs to + * be modified to write data in two's complement format. + */ +void PNGAPI +png_save_int_32(png_bytep buf, png_int_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xff); + buf[1] = (png_byte)((i >> 16) & 0xff); + buf[2] = (png_byte)((i >> 8) & 0xff); + buf[3] = (png_byte)(i & 0xff); +} + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +void PNGAPI +png_save_uint_16(png_bytep buf, unsigned int i) +{ + buf[0] = (png_byte)((i >> 8) & 0xff); + buf[1] = (png_byte)(i & 0xff); +} + +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +void PNGAPI +png_write_chunk(png_structp png_ptr, png_bytep chunk_name, + png_bytep data, png_size_t length) +{ + if(png_ptr == NULL) return; + png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* Write the start of a PNG chunk. The type is the chunk type. + * The total_length is the sum of the lengths of all the data you will be + * passing in png_write_chunk_data(). + */ +void PNGAPI +png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, + png_uint_32 length) +{ + png_byte buf[4]; + png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length); + if(png_ptr == NULL) return; + + /* write the length */ + png_save_uint_32(buf, length); + png_write_data(png_ptr, buf, (png_size_t)4); + + /* write the chunk name */ + png_write_data(png_ptr, chunk_name, (png_size_t)4); + /* reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_name, (png_size_t)4); +} + +/* Write the data of a PNG chunk started with png_write_chunk_start(). + * Note that multiple calls to this function are allowed, and that the + * sum of the lengths from these calls *must* add up to the total_length + * given to png_write_chunk_start(). + */ +void PNGAPI +png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + /* write the data, and run the CRC over it */ + if(png_ptr == NULL) return; + if (data != NULL && length > 0) + { + png_calculate_crc(png_ptr, data, length); + png_write_data(png_ptr, data, length); + } +} + +/* Finish a chunk started with png_write_chunk_start(). */ +void PNGAPI +png_write_chunk_end(png_structp png_ptr) +{ + png_byte buf[4]; + + if(png_ptr == NULL) return; + + /* write the crc */ + png_save_uint_32(buf, png_ptr->crc); + + png_write_data(png_ptr, buf, (png_size_t)4); +} + +/* Simple function to write the signature. If we have already written + * the magic bytes of the signature, or more likely, the PNG stream is + * being embedded into another stream and doesn't need its own signature, + * we should call png_set_sig_bytes() to tell libpng how many of the + * bytes have already been written. + */ +void /* PRIVATE */ +png_write_sig(png_structp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + /* write the rest of the 8 byte signature */ + png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], + (png_size_t)8 - png_ptr->sig_bytes); + if(png_ptr->sig_bytes < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED) +/* + * This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions + * set up by the caller in order to make the whole mess thread-safe. + */ + +typedef struct +{ + char *input; /* the uncompressed input data */ + int input_len; /* its length */ + int num_output_ptr; /* number of output pointers used */ + int max_output_ptr; /* size of output_ptr */ + png_charpp output_ptr; /* array of pointers to output */ +} compression_state; + +/* compress given text into storage in the png_ptr structure */ +static int /* PRIVATE */ +png_text_compress(png_structp png_ptr, + png_charp text, png_size_t text_len, int compression, + compression_state *comp) +{ + int ret; + + comp->num_output_ptr = 0; + comp->max_output_ptr = 0; + comp->output_ptr = NULL; + comp->input = NULL; + comp->input_len = 0; + + /* we may just want to pass the text right through */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + comp->input = text; + comp->input_len = text_len; + return((int)text_len); + } + + if (compression >= PNG_TEXT_COMPRESSION_LAST) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[50]; + sprintf(msg, "Unknown compression type %d", compression); + png_warning(png_ptr, msg); +#else + png_warning(png_ptr, "Unknown compression type"); +#endif + } + + /* We can't write the chunk until we find out how much data we have, + * which means we need to run the compressor first and save the + * output. This shouldn't be a problem, as the vast majority of + * comments should be reasonable, but we will set up an array of + * malloc'd pointers to be sure. + * + * If we knew the application was well behaved, we could simplify this + * greatly by assuming we can always malloc an output buffer large + * enough to hold the compressed text ((1001 * text_len / 1000) + 12) + * and malloc this directly. The only time this would be a bad idea is + * if we can't malloc more than 64K and we have 64K of random input + * data, or if the input string is incredibly large (although this + * wouldn't cause a failure, just a slowdown due to swapping). + */ + + /* set up the compression buffers */ + png_ptr->zstream.avail_in = (uInt)text_len; + png_ptr->zstream.next_in = (Bytef *)text; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; + + /* this is the same compression loop as in png_write_row() */ + do + { + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + if (ret != Z_OK) + { + /* error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* make sure the output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, old_max + * png_sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charp))); + } + + /* save the data */ + comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + /* continue until we don't have any more to compress */ + } while (png_ptr->zstream.avail_in); + + /* finish the compression */ + do + { + /* tell zlib we are finished */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + + if (ret == Z_OK) + { + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + /* check to make sure our output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + /* This could be optimized to realloc() */ + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, + old_max * png_sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * + png_sizeof (png_charp))); + } + + /* save off the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer pointers */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + } + else if (ret != Z_STREAM_END) + { + /* we got an error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* text length is number of buffers plus last buffer */ + text_len = png_ptr->zbuf_size * comp->num_output_ptr; + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + + return((int)text_len); +} + +/* ship the compressed text out via chunk writes */ +static void /* PRIVATE */ +png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +{ + int i; + + /* handle the no-compression case */ + if (comp->input) + { + png_write_chunk_data(png_ptr, (png_bytep)comp->input, + (png_size_t)comp->input_len); + return; + } + + /* write saved output buffers, if any */ + for (i = 0; i < comp->num_output_ptr; i++) + { + png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i], + png_ptr->zbuf_size); + png_free(png_ptr, comp->output_ptr[i]); + comp->output_ptr[i]=NULL; + } + if (comp->max_output_ptr != 0) + png_free(png_ptr, comp->output_ptr); + comp->output_ptr=NULL; + /* write anything left in zbuf */ + if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) + png_write_chunk_data(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + + /* reset zlib for another zTXt/iTXt or image data */ + deflateReset(&png_ptr->zstream); + png_ptr->zstream.data_type = Z_BINARY; +} +#endif + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. Note that the rest of this code depends upon this + * information being correct. + */ +void /* PRIVATE */ +png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; +#endif + png_byte buf[13]; /* buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR\n"); + /* Check that we have valid input data from the application info */ + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: + case 16: png_ptr->channels = 1; break; + default: png_error(png_ptr,"Invalid bit depth for grayscale image"); + } + break; + case PNG_COLOR_TYPE_RGB: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for RGB image"); + png_ptr->channels = 3; + break; + case PNG_COLOR_TYPE_PALETTE: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: png_ptr->channels = 1; break; + default: png_error(png_ptr, "Invalid bit depth for paletted image"); + } + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); + png_ptr->channels = 2; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + if (bit_depth != 8 && bit_depth != 16) + png_error(png_ptr, "Invalid bit depth for RGBA image"); + png_ptr->channels = 4; + break; + default: + png_error(png_ptr, "Invalid image color type specified"); + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Invalid compression type specified"); + compression_type = PNG_COMPRESSION_TYPE_BASE; + } + + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && +#endif + filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Invalid filter type specified"); + filter_type = PNG_FILTER_TYPE_BASE; + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + if (interlace_type != PNG_INTERLACE_NONE && + interlace_type != PNG_INTERLACE_ADAM7) + { + png_warning(png_ptr, "Invalid interlace type specified"); + interlace_type = PNG_INTERLACE_ADAM7; + } +#else + interlace_type=PNG_INTERLACE_NONE; +#endif + + /* save off the relevent information */ + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->color_type = (png_byte)color_type; + png_ptr->interlaced = (png_byte)interlace_type; +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + png_ptr->width = width; + png_ptr->height = height; + + png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); + /* set the usr info, so any transformations can modify it */ + png_ptr->usr_width = png_ptr->width; + png_ptr->usr_bit_depth = png_ptr->bit_depth; + png_ptr->usr_channels = png_ptr->channels; + + /* pack the header information into the buffer */ + png_save_uint_32(buf, width); + png_save_uint_32(buf + 4, height); + buf[8] = (png_byte)bit_depth; + buf[9] = (png_byte)color_type; + buf[10] = (png_byte)compression_type; + buf[11] = (png_byte)filter_type; + buf[12] = (png_byte)interlace_type; + + /* write the chunk */ + png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); + + /* initialize zlib with PNG info */ + png_ptr->zstream.zalloc = png_zalloc; + png_ptr->zstream.zfree = png_zfree; + png_ptr->zstream.opaque = (voidpf)png_ptr; + if (!(png_ptr->do_filter)) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + png_ptr->bit_depth < 8) + png_ptr->do_filter = PNG_FILTER_NONE; + else + png_ptr->do_filter = PNG_ALL_FILTERS; + } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) + { + if (png_ptr->do_filter != PNG_FILTER_NONE) + png_ptr->zlib_strategy = Z_FILTERED; + else + png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; + } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) + png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) + png_ptr->zlib_mem_level = 8; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) + png_ptr->zlib_window_bits = 15; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) + png_ptr->zlib_method = 8; + if (deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, + png_ptr->zlib_method, png_ptr->zlib_window_bits, + png_ptr->zlib_mem_level, png_ptr->zlib_strategy) != Z_OK) + png_error(png_ptr, "zlib failed to initialize compressor"); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + /* libpng is not interested in zstream.data_type */ + /* set it to a predefined value, to avoid its evaluation inside zlib */ + png_ptr->zstream.data_type = Z_BINARY; + + png_ptr->mode = PNG_HAVE_IHDR; +} + +/* write the palette. We are careful not to trust png_color to be in the + * correct order for PNG, so people can redefine it to any convenient + * structure. + */ +void /* PRIVATE */ +png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_PLTE; +#endif + png_uint_32 i; + png_colorp pal_ptr; + png_byte buf[3]; + + png_debug(1, "in png_write_PLTE\n"); + if (( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && +#endif + num_pal == 0) || num_pal > 256) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_error(png_ptr, "Invalid number of colors in palette"); + } + else + { + png_warning(png_ptr, "Invalid number of colors in palette"); + return; + } + } + + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + { + png_warning(png_ptr, + "Ignoring request to write a PLTE chunk in grayscale PNG"); + return; + } + + png_ptr->num_palette = (png_uint_16)num_pal; + png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); + + png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3); +#ifndef PNG_NO_POINTER_INDEXING + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) + { + buf[0] = pal_ptr->red; + buf[1] = pal_ptr->green; + buf[2] = pal_ptr->blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } +#else + /* This is a little slower but some buggy compilers need to do this instead */ + pal_ptr=palette; + for (i = 0; i < num_pal; i++) + { + buf[0] = pal_ptr[i].red; + buf[1] = pal_ptr[i].green; + buf[2] = pal_ptr[i].blue; + png_write_chunk_data(png_ptr, buf, (png_size_t)3); + } +#endif + png_write_chunk_end(png_ptr); + png_ptr->mode |= PNG_HAVE_PLTE; +} + +/* write an IDAT chunk */ +void /* PRIVATE */ +png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + png_debug(1, "in png_write_IDAT\n"); + + /* Optimize the CMF field in the zlib stream. */ + /* This hack of the zlib stream is compliant to the stream specification. */ + if (!(png_ptr->mode & PNG_HAVE_IDAT) && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + { + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + /* Avoid memory underflows and multiplication overflows. */ + /* The conditions below are practically always satisfied; + however, they still must be checked. */ + if (length >= 2 && + png_ptr->height < 16384 && png_ptr->width < 16384) + { + png_uint_32 uncompressed_idat_size = png_ptr->height * + ((png_ptr->width * + png_ptr->channels * png_ptr->bit_depth + 15) >> 3); + unsigned int z_cinfo = z_cmf >> 4; + unsigned int half_z_window_size = 1 << (z_cinfo + 7); + while (uncompressed_idat_size <= half_z_window_size && + half_z_window_size >= 256) + { + z_cinfo--; + half_z_window_size >>= 1; + } + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + if (data[0] != (png_byte)z_cmf) + { + data[0] = (png_byte)z_cmf; + data[1] &= 0xe0; + data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); + } + } + } + else + png_error(png_ptr, + "Invalid zlib compression method or flags in IDAT"); + } + + png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); + png_ptr->mode |= PNG_HAVE_IDAT; +} + +/* write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IEND; +#endif + png_debug(1, "in png_write_IEND\n"); + png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, + (png_size_t)0); + png_ptr->mode |= PNG_HAVE_IEND; +} + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +/* write a gAMA chunk */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void /* PRIVATE */ +png_write_gAMA(png_structp png_ptr, double file_gamma) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_gAMA; +#endif + png_uint_32 igamma; + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA\n"); + /* file_gamma is saved in 1/100,000ths */ + igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); + png_save_uint_32(buf, igamma); + png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_gAMA; +#endif + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA\n"); + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); + png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); +} +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +/* write a sRGB chunk */ +void /* PRIVATE */ +png_write_sRGB(png_structp png_ptr, int srgb_intent) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sRGB; +#endif + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB\n"); + if(srgb_intent >= PNG_sRGB_INTENT_LAST) + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + buf[0]=(png_byte)srgb_intent; + png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); +} +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +/* write an iCCP chunk */ +void /* PRIVATE */ +png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, + png_charp profile, int profile_len) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iCCP; +#endif + png_size_t name_len; + png_charp new_name; + compression_state comp; + int embedded_profile_len = 0; + + png_debug(1, "in png_write_iCCP\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if (name == NULL || (name_len = png_check_keyword(png_ptr, name, + &new_name)) == 0) + { + png_warning(png_ptr, "Empty keyword in iCCP chunk"); + return; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_warning(png_ptr, "Unknown compression type in iCCP chunk"); + + if (profile == NULL) + profile_len = 0; + + if (profile_len > 3) + embedded_profile_len = + ((*( (png_bytep)profile ))<<24) | + ((*( (png_bytep)profile+1))<<16) | + ((*( (png_bytep)profile+2))<< 8) | + ((*( (png_bytep)profile+3)) ); + + if (profile_len < embedded_profile_len) + { + png_warning(png_ptr, + "Embedded profile length too large in iCCP chunk"); + return; + } + + if (profile_len > embedded_profile_len) + { + png_warning(png_ptr, + "Truncating profile to actual length in iCCP chunk"); + profile_len = embedded_profile_len; + } + + if (profile_len) + profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len, + PNG_COMPRESSION_TYPE_BASE, &comp); + + /* make sure we include the NULL after the name and the compression type */ + png_write_chunk_start(png_ptr, (png_bytep)png_iCCP, + (png_uint_32)name_len+profile_len+2); + new_name[name_len+1]=0x00; + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); + + if (profile_len) + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +/* write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sPLT; +#endif + png_size_t name_len; + png_charp new_name; + png_byte entrybuf[10]; + int entry_size = (spalette->depth == 8 ? 6 : 10); + int palette_size = entry_size * spalette->nentries; + png_sPLT_entryp ep; +#ifdef PNG_NO_POINTER_INDEXING + int i; +#endif + + png_debug(1, "in png_write_sPLT\n"); + if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, + spalette->name, &new_name))==0) + { + png_warning(png_ptr, "Empty keyword in sPLT chunk"); + return; + } + + /* make sure we include the NULL after the name */ + png_write_chunk_start(png_ptr, (png_bytep)png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1); + png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1); + + /* loop through each palette entry, writing appropriately */ +#ifndef PNG_NO_POINTER_INDEXING + for (ep = spalette->entries; epentries+spalette->nentries; ep++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + } +#else + ep=spalette->entries; + for (i=0; i>spalette->nentries; i++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep[i].red; + entrybuf[1] = (png_byte)ep[i].green; + entrybuf[2] = (png_byte)ep[i].blue; + entrybuf[3] = (png_byte)ep[i].alpha; + png_save_uint_16(entrybuf + 4, ep[i].frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep[i].red); + png_save_uint_16(entrybuf + 2, ep[i].green); + png_save_uint_16(entrybuf + 4, ep[i].blue); + png_save_uint_16(entrybuf + 6, ep[i].alpha); + png_save_uint_16(entrybuf + 8, ep[i].frequency); + } + png_write_chunk_data(png_ptr, entrybuf, entry_size); + } +#endif + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +/* write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sBIT; +#endif + png_byte buf[4]; + png_size_t size; + + png_debug(1, "in png_write_sBIT\n"); + /* make sure we don't depend upon the order of PNG_COLOR_8 */ + if (color_type & PNG_COLOR_MASK_COLOR) + { + png_byte maxbits; + + maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : + png_ptr->usr_bit_depth); + if (sbit->red == 0 || sbit->red > maxbits || + sbit->green == 0 || sbit->green > maxbits || + sbit->blue == 0 || sbit->blue > maxbits) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[0] = sbit->red; + buf[1] = sbit->green; + buf[2] = sbit->blue; + size = 3; + } + else + { + if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[0] = sbit->gray; + size = 1; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + { + if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + buf[size++] = sbit->alpha; + } + + png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); +} +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +/* write the cHRM chunk */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void /* PRIVATE */ +png_write_cHRM(png_structp png_ptr, double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_cHRM; +#endif + png_byte buf[32]; + png_uint_32 itemp; + + png_debug(1, "in png_write_cHRM\n"); + /* each value is saved in 1/100,000ths */ + if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 || + white_x + white_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM white point specified"); +#if !defined(PNG_NO_CONSOLE_IO) + fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y); +#endif + return; + } + itemp = (png_uint_32)(white_x * 100000.0 + 0.5); + png_save_uint_32(buf, itemp); + itemp = (png_uint_32)(white_y * 100000.0 + 0.5); + png_save_uint_32(buf + 4, itemp); + + if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM red point specified"); + return; + } + itemp = (png_uint_32)(red_x * 100000.0 + 0.5); + png_save_uint_32(buf + 8, itemp); + itemp = (png_uint_32)(red_y * 100000.0 + 0.5); + png_save_uint_32(buf + 12, itemp); + + if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM green point specified"); + return; + } + itemp = (png_uint_32)(green_x * 100000.0 + 0.5); + png_save_uint_32(buf + 16, itemp); + itemp = (png_uint_32)(green_y * 100000.0 + 0.5); + png_save_uint_32(buf + 20, itemp); + + if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0) + { + png_warning(png_ptr, "Invalid cHRM blue point specified"); + return; + } + itemp = (png_uint_32)(blue_x * 100000.0 + 0.5); + png_save_uint_32(buf + 24, itemp); + itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); + png_save_uint_32(buf + 28, itemp); + + png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); +} +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, + png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, + png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, + png_fixed_point blue_y) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_cHRM; +#endif + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM\n"); + /* each value is saved in 1/100,000ths */ + if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM white point specified"); +#if !defined(PNG_NO_CONSOLE_IO) + fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y); +#endif + return; + } + png_save_uint_32(buf, (png_uint_32)white_x); + png_save_uint_32(buf + 4, (png_uint_32)white_y); + + if (red_x + red_y > 100000L) + { + png_warning(png_ptr, "Invalid cHRM fixed red point specified"); + return; + } + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_y); + + if (green_x + green_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM green point specified"); + return; + } + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_y); + + if (blue_x + blue_y > 100000L) + { + png_warning(png_ptr, "Invalid fixed cHRM blue point specified"); + return; + } + png_save_uint_32(buf + 24, (png_uint_32)blue_x); + png_save_uint_32(buf + 28, (png_uint_32)blue_y); + + png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); +} +#endif +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +/* write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, + int num_trans, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tRNS; +#endif + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS\n"); + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + { + png_warning(png_ptr,"Invalid number of transparent colors specified"); + return; + } + /* write the chunk out as it is */ + png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans); + } + else if (color_type == PNG_COLOR_TYPE_GRAY) + { + /* one 16 bit value */ + if(tran->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + return; + } + png_save_uint_16(buf, tran->gray); + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); + } + else if (color_type == PNG_COLOR_TYPE_RGB) + { + /* three 16 bit values */ + png_save_uint_16(buf, tran->red); + png_save_uint_16(buf + 2, tran->green); + png_save_uint_16(buf + 4, tran->blue); + if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); + } + else + { + png_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } +} +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +/* write the background chunk */ +void /* PRIVATE */ +png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_bKGD; +#endif + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD\n"); + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if ( +#if defined(PNG_MNG_FEATURES_SUPPORTED) + (png_ptr->num_palette || + (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && +#endif + back->index > png_ptr->num_palette) + { + png_warning(png_ptr, "Invalid background palette index"); + return; + } + buf[0] = back->index; + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); + } + else if (color_type & PNG_COLOR_MASK_COLOR) + { + png_save_uint_16(buf, back->red); + png_save_uint_16(buf + 2, back->green); + png_save_uint_16(buf + 4, back->blue); + if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + return; + } + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); + } + else + { + if(back->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + return; + } + png_save_uint_16(buf, back->gray); + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); + } +} +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +/* write the histogram */ +void /* PRIVATE */ +png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_hIST; +#endif + int i; + png_byte buf[3]; + + png_debug(1, "in png_write_hIST\n"); + if (num_hist > (int)png_ptr->num_palette) + { + png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist, + png_ptr->num_palette); + png_warning(png_ptr, "Invalid number of histogram entries specified"); + return; + } + + png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2)); + for (i = 0; i < num_hist; i++) + { + png_save_uint_16(buf, hist[i]); + png_write_chunk_data(png_ptr, buf, (png_size_t)2); + } + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The new_key is allocated to hold the corrected keyword and must be freed + * by the calling routine. This avoids problems with trying to write to + * static keywords without having to have duplicate copies of the strings. + */ +png_size_t /* PRIVATE */ +png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) +{ + png_size_t key_len; + png_charp kp, dp; + int kflag; + int kwarn=0; + + png_debug(1, "in png_check_keyword\n"); + *new_key = NULL; + + if (key == NULL || (key_len = png_strlen(key)) == 0) + { + png_warning(png_ptr, "zero length keyword"); + return ((png_size_t)0); + } + + png_debug1(2, "Keyword to be checked is '%s'\n", key); + + *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); + if (*new_key == NULL) + { + png_warning(png_ptr, "Out of memory while procesing keyword"); + return ((png_size_t)0); + } + + /* Replace non-printing characters with a blank and print a warning */ + for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) + { + if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1)) + { +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) + char msg[40]; + + sprintf(msg, "invalid keyword character 0x%02X", *kp); + png_warning(png_ptr, msg); +#else + png_warning(png_ptr, "invalid character in keyword"); +#endif + *dp = ' '; + } + else + { + *dp = *kp; + } + } + *dp = '\0'; + + /* Remove any trailing white space. */ + kp = *new_key + key_len - 1; + if (*kp == ' ') + { + png_warning(png_ptr, "trailing spaces removed from keyword"); + + while (*kp == ' ') + { + *(kp--) = '\0'; + key_len--; + } + } + + /* Remove any leading white space. */ + kp = *new_key; + if (*kp == ' ') + { + png_warning(png_ptr, "leading spaces removed from keyword"); + + while (*kp == ' ') + { + kp++; + key_len--; + } + } + + png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp); + + /* Remove multiple internal spaces. */ + for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) + { + if (*kp == ' ' && kflag == 0) + { + *(dp++) = *kp; + kflag = 1; + } + else if (*kp == ' ') + { + key_len--; + kwarn=1; + } + else + { + *(dp++) = *kp; + kflag = 0; + } + } + *dp = '\0'; + if(kwarn) + png_warning(png_ptr, "extra interior spaces removed from keyword"); + + if (key_len == 0) + { + png_free(png_ptr, *new_key); + *new_key=NULL; + png_warning(png_ptr, "Zero length keyword"); + } + + if (key_len > 79) + { + png_warning(png_ptr, "keyword length must be 1 - 79 characters"); + new_key[79] = '\0'; + key_len = 79; + } + + return (key_len); +} +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +/* write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, + png_size_t text_len) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tEXt; +#endif + png_size_t key_len; + png_charp new_key; + + png_debug(1, "in png_write_tEXt\n"); + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in tEXt chunk"); + return; + } + + if (text == NULL || *text == '\0') + text_len = 0; + else + text_len = png_strlen(text); + + /* make sure we include the 0 after the key */ + png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1); + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + if (text_len) + png_write_chunk_data(png_ptr, (png_bytep)text, text_len); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); +} +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +/* write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, + png_size_t text_len, int compression) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_zTXt; +#endif + png_size_t key_len; + char buf[1]; + png_charp new_key; + compression_state comp; + + png_debug(1, "in png_write_zTXt\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in zTXt chunk"); + return; + } + + if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) + { + png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); + png_free(png_ptr, new_key); + return; + } + + text_len = png_strlen(text); + + png_free(png_ptr, new_key); + + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression, + &comp); + + /* write start of chunk */ + png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) + (key_len+text_len+2)); + /* write key */ + png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1); + buf[0] = (png_byte)compression; + /* write compression */ + png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); + /* write the compressed data */ + png_write_compressed_data_out(png_ptr, &comp); + + /* close the chunk */ + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +/* write an iTXt chunk */ +void /* PRIVATE */ +png_write_iTXt(png_structp png_ptr, int compression, png_charp key, + png_charp lang, png_charp lang_key, png_charp text) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iTXt; +#endif + png_size_t lang_len, key_len, lang_key_len, text_len; + png_charp new_lang, new_key; + png_byte cbuf[2]; + compression_state comp; + + png_debug(1, "in png_write_iTXt\n"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in iTXt chunk"); + return; + } + if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) + { + png_warning(png_ptr, "Empty language field in iTXt chunk"); + new_lang = NULL; + lang_len = 0; + } + + if (lang_key == NULL) + lang_key_len = 0; + else + lang_key_len = png_strlen(lang_key); + + if (text == NULL) + text_len = 0; + else + text_len = png_strlen(text); + + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression-2, + &comp); + + + /* make sure we include the compression flag, the compression byte, + * and the NULs after the key, lang, and lang_key parts */ + + png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, + (png_uint_32)( + 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + + key_len + + lang_len + + lang_key_len + + text_len)); + + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + + /* set the compression flag */ + if (compression == PNG_ITXT_COMPRESSION_NONE || \ + compression == PNG_TEXT_COMPRESSION_NONE) + cbuf[0] = 0; + else /* compression == PNG_ITXT_COMPRESSION_zTXt */ + cbuf[0] = 1; + /* set the compression method */ + cbuf[1] = 0; + png_write_chunk_data(png_ptr, cbuf, 2); + + cbuf[0] = 0; + png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1); + png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); + if (new_lang) + png_free(png_ptr, new_lang); +} +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +/* write the oFFs chunk */ +void /* PRIVATE */ +png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, + int unit_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_oFFs; +#endif + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs\n"); + if (unit_type >= PNG_OFFSET_LAST) + png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); + + png_save_int_32(buf, x_offset); + png_save_int_32(buf + 4, y_offset); + buf[8] = (png_byte)unit_type; + + png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); +} +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +/* write the pCAL chunk (described in the PNG extensions document) */ +void /* PRIVATE */ +png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, + png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pCAL; +#endif + png_size_t purpose_len, units_len, total_len; + png_uint_32p params_len; + png_byte buf[10]; + png_charp new_purpose; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams); + if (type >= PNG_EQUATION_LAST) + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; + png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len); + units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d\n", (int)units_len); + total_len = purpose_len + units_len + 10; + + params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams + *png_sizeof(png_uint_32))); + + /* Find the length of each parameter, making sure we don't count the + null terminator for the last parameter. */ + for (i = 0; i < nparams; i++) + { + params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]); + total_len += (png_size_t)params_len[i]; + } + + png_debug1(3, "pCAL total length = %d\n", (int)total_len); + png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len); + png_save_int_32(buf, X0); + png_save_int_32(buf + 4, X1); + buf[8] = (png_byte)type; + buf[9] = (png_byte)nparams; + png_write_chunk_data(png_ptr, buf, (png_size_t)10); + png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len); + + png_free(png_ptr, new_purpose); + + for (i = 0; i < nparams; i++) + { + png_write_chunk_data(png_ptr, (png_bytep)params[i], + (png_size_t)params_len[i]); + } + + png_free(png_ptr, params_len); + png_write_chunk_end(png_ptr); +} +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +/* write the sCAL chunk */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +void /* PRIVATE */ +png_write_sCAL(png_structp png_ptr, int unit, double width, double height) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sCAL; +#endif + char buf[64]; + png_size_t total_len; + + png_debug(1, "in png_write_sCAL\n"); + + buf[0] = (char)unit; +#if defined(_WIN32_WCE) +/* sprintf() function is not supported on WindowsCE */ + { + wchar_t wc_buf[32]; + size_t wc_len; + swprintf(wc_buf, TEXT("%12.12e"), width); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); + total_len = wc_len + 2; + swprintf(wc_buf, TEXT("%12.12e"), height); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len, + NULL, NULL); + total_len += wc_len; + } +#else + sprintf(buf + 1, "%12.12e", width); + total_len = 1 + png_strlen(buf + 1) + 1; + sprintf(buf + total_len, "%12.12e", height); + total_len += png_strlen(buf + total_len); +#endif + + png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); + png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); +} +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +void /* PRIVATE */ +png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, + png_charp height) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sCAL; +#endif + png_byte buf[64]; + png_size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s\n"); + + wlen = png_strlen(width); + hlen = png_strlen(height); + total_len = wlen + hlen + 2; + if (total_len > 64) + { + png_warning(png_ptr, "Can't write sCAL (buffer too small)"); + return; + } + + buf[0] = (png_byte)unit; + png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */ + png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */ + + png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); + png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len); +} +#endif +#endif +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +/* write the pHYs chunk */ +void /* PRIVATE */ +png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pHYs; +#endif + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs\n"); + if (unit_type >= PNG_RESOLUTION_LAST) + png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); + + png_save_uint_32(buf, x_pixels_per_unit); + png_save_uint_32(buf + 4, y_pixels_per_unit); + buf[8] = (png_byte)unit_type; + + png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); +} +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* Write the tIME chunk. Use either png_convert_from_struct_tm() + * or png_convert_from_time_t(), or fill in the structure yourself. + */ +void /* PRIVATE */ +png_write_tIME(png_structp png_ptr, png_timep mod_time) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tIME; +#endif + png_byte buf[7]; + + png_debug(1, "in png_write_tIME\n"); + if (mod_time->month > 12 || mod_time->month < 1 || + mod_time->day > 31 || mod_time->day < 1 || + mod_time->hour > 23 || mod_time->second > 60) + { + png_warning(png_ptr, "Invalid time specified for tIME chunk"); + return; + } + + png_save_uint_16(buf, mod_time->year); + buf[2] = mod_time->month; + buf[3] = mod_time->day; + buf[4] = mod_time->hour; + buf[5] = mod_time->minute; + buf[6] = mod_time->second; + + png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7); +} +#endif + +/* initializes the row writing capability of libpng */ +void /* PRIVATE */ +png_write_start_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + png_size_t buf_size; + + png_debug(1, "in png_write_start_row\n"); + buf_size = (png_size_t)(PNG_ROWBYTES( + png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1); + + /* set up row buffer */ + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + + /* set up filtering buffer, if using this filter */ + if (png_ptr->do_filter & PNG_FILTER_SUB) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + /* We only need to keep the previous row if we are using one of these. */ + if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + { + /* set up previous row buffer */ + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); + png_memset(png_ptr->prev_row, 0, buf_size); + + if (png_ptr->do_filter & PNG_FILTER_UP) + { + png_ptr->up_row = (png_bytep )png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + + if (png_ptr->do_filter & PNG_FILTER_AVG) + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + + if (png_ptr->do_filter & PNG_FILTER_PAETH) + { + png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* if interlaced, we need to set up width and height of pass */ + if (png_ptr->interlaced) + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - + png_pass_start[0]) / png_pass_inc[0]; + } + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + } + else +#endif + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; +} + +/* Internal use only. Called when finished processing a row of data. */ +void /* PRIVATE */ +png_write_finish_row(png_structp png_ptr) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + + int ret; + + png_debug(1, "in png_write_finish_row\n"); + /* next row */ + png_ptr->row_number++; + + /* see if we are done */ + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* if interlaced, go to next pass */ + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + if (png_ptr->transformations & PNG_INTERLACE) + { + png_ptr->pass++; + } + else + { + /* loop until we find a non-zero width or height pass */ + do + { + png_ptr->pass++; + if (png_ptr->pass >= 7) + break; + png_ptr->usr_width = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (png_ptr->transformations & PNG_INTERLACE) + break; + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); + + } + + /* reset the row above the image for the next pass */ + if (png_ptr->pass < 7) + { + if (png_ptr->prev_row != NULL) + png_memset(png_ptr->prev_row, 0, + (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* + png_ptr->usr_bit_depth,png_ptr->width))+1); + return; + } + } +#endif + + /* if we get here, we've just written the last row, so we need + to flush the compressor */ + do + { + /* tell the compressor we are done */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + /* check for an error */ + if (ret == Z_OK) + { + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + else if (ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + } while (ret != Z_STREAM_END); + + /* write any extra space */ + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + { + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - + png_ptr->zstream.avail_out); + } + + deflateReset(&png_ptr->zstream); + png_ptr->zstream.data_type = Z_BINARY; +} + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Pick out the correct pixels for the interlace pass. + * The basic idea here is to go through the row with a source + * pointer and a destination pointer (sp and dp), and copy the + * correct pixels for the pass. As the row gets compacted, + * sp will always be >= dp, so we should never overwrite anything. + * See the default: case for the easiest code to understand. + */ +void /* PRIVATE */ +png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + + png_debug(1, "in png_do_write_interlace\n"); + /* we don't have to do anything on the last pass (6) */ +#if defined(PNG_USELESS_TESTS_SUPPORTED) + if (row != NULL && row_info != NULL && pass < 6) +#else + if (pass < 6) +#endif + { + /* each pixel depth is handled separately */ + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + d = 0; + shift = 7; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 3); + value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; + d |= (value << shift); + + if (shift == 0) + { + shift = 7; + *dp++ = (png_byte)d; + d = 0; + } + else + shift--; + + } + if (shift != 7) + *dp = (png_byte)d; + break; + } + case 2: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 6; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 2); + value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; + d |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp++ = (png_byte)d; + d = 0; + } + else + shift -= 2; + } + if (shift != 6) + *dp = (png_byte)d; + break; + } + case 4: + { + png_bytep sp; + png_bytep dp; + int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 4; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (png_size_t)(i >> 1); + value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; + d |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp++ = (png_byte)d; + d = 0; + } + else + shift -= 4; + } + if (shift != 4) + *dp = (png_byte)d; + break; + } + default: + { + png_bytep sp; + png_bytep dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + png_size_t pixel_bytes; + + /* start at the beginning */ + dp = row; + /* find out how many bytes each pixel takes up */ + pixel_bytes = (row_info->pixel_depth >> 3); + /* loop through the row, only looking at the pixels that + matter */ + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + /* find out where the original pixel is */ + sp = row + (png_size_t)i * pixel_bytes; + /* move the pixel */ + if (dp != sp) + png_memcpy(dp, sp, pixel_bytes); + /* next pixel */ + dp += pixel_bytes; + } + break; + } + } + /* set new row width */ + row_info->width = (row_info->width + + png_pass_inc[pass] - 1 - + png_pass_start[pass]) / + png_pass_inc[pass]; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +/* This filters the row, chooses which filter to use, if it has not already + * been specified by the application, and then writes the row out with the + * chosen filter. + */ +#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) +#define PNG_HISHIFT 10 +#define PNG_LOMASK ((png_uint_32)0xffffL) +#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) +void /* PRIVATE */ +png_write_find_filter(png_structp png_ptr, png_row_infop row_info) +{ + png_bytep prev_row, best_row, row_buf; + png_uint_32 mins, bpp; + png_byte filter_to_do = png_ptr->do_filter; + png_uint_32 row_bytes = row_info->rowbytes; +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + int num_p_filters = (int)png_ptr->num_prev_filters; +#endif + + png_debug(1, "in png_write_find_filter\n"); + /* find out how many bytes offset each pixel is */ + bpp = (row_info->pixel_depth + 7) >> 3; + + prev_row = png_ptr->prev_row; + best_row = row_buf = png_ptr->row_buf; + mins = PNG_MAXSUM; + + /* The prediction method we use is to find which method provides the + * smallest value when summing the absolute values of the distances + * from zero, using anything >= 128 as negative numbers. This is known + * as the "minimum sum of absolute differences" heuristic. Other + * heuristics are the "weighted minimum sum of absolute differences" + * (experimental and can in theory improve compression), and the "zlib + * predictive" method (not implemented yet), which does test compressions + * of lines using different filter methods, and then chooses the + * (series of) filter(s) that give minimum compressed data size (VERY + * computationally expensive). + * + * GRR 980525: consider also + * (1) minimum sum of absolute differences from running average (i.e., + * keep running sum of non-absolute differences & count of bytes) + * [track dispersion, too? restart average if dispersion too large?] + * (1b) minimum sum of absolute differences from sliding average, probably + * with window size <= deflate window (usually 32K) + * (2) minimum sum of squared differences from zero or running average + * (i.e., ~ root-mean-square approach) + */ + + + /* We don't need to test the 'no filter' case if this is the only filter + * that has been chosen, as it doesn't actually do anything to the data. + */ + if ((filter_to_do & PNG_FILTER_NONE) && + filter_to_do != PNG_FILTER_NONE) + { + png_bytep rp; + png_uint_32 sum = 0; + png_uint_32 i; + int v; + + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) + { + v = *rp; + sum += (v < 128) ? v : 256 - v; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + png_uint_32 sumhi, sumlo; + int j; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ + + /* Reduce the sum if we match any of the previous rows */ + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + /* Factor in the cost of this filter (this is here for completeness, + * but it makes no sense to have a "cost" for the NONE filter, as + * it has the minimum possible computational cost - none). + */ + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + mins = sum; + } + + /* sub filter */ + if (filter_to_do == PNG_FILTER_SUB) + /* it's the only filter so no testing is needed */ + { + png_bytep rp, lp, dp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + *dp = *rp; + } + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + } + best_row = png_ptr->sub_row; + } + + else if (filter_to_do & PNG_FILTER_SUB) + { + png_bytep rp, dp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + /* We temporarily increase the "minimum sum" by the factor we + * would reduce the sum of this filter, so that we can do the + * early exit comparison without scaling the sum each time. + */ + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; + i++, rp++, dp++) + { + v = *dp = *rp; + + sum += (v < 128) ? v : 256 - v; + } + for (lp = row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) + { + sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->sub_row; + } + } + + /* up filter */ + if (filter_to_do == PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_uint_32 i; + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); + } + best_row = png_ptr->up_row; + } + + else if (filter_to_do & PNG_FILTER_UP) + { + png_bytep rp, dp, pp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, + pp = prev_row + 1; i < row_bytes; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->up_row; + } + } + + /* avg filter */ + if (filter_to_do == PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + } + for (lp = row_buf + 1; i < row_bytes; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + } + best_row = png_ptr->avg_row; + } + + else if (filter_to_do & PNG_FILTER_AVG) + { + png_bytep rp, dp, pp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + for (lp = row_buf + 1; i < row_bytes; i++) + { + v = *dp++ = + (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->avg_row; + } + } + + /* Paeth filter */ + if (filter_to_do == PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + } + best_row = png_ptr->paeth_row; + } + + else if (filter_to_do & PNG_FILTER_PAETH) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 sum = 0, lmins = mins; + png_uint_32 i; + int v; + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 lmhi, lmlo; + lmlo = lmins & PNG_LOMASK; + lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (lmhi > PNG_HIMASK) + lmins = PNG_MAXSUM; + else + lmins = (lmhi << PNG_HISHIFT) + lmlo; + } +#endif + + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, + pp = prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + + sum += (v < 128) ? v : 256 - v; + } + + for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + +#ifndef PNG_SLOW_PAETH + p = b - c; + pc = a - c; +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; +#else /* PNG_SLOW_PAETH */ + p = a + b - c; + pa = abs(p - a); + pb = abs(p - b); + pc = abs(p - c); + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; +#endif /* PNG_SLOW_PAETH */ + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + + sum += (v < 128) ? v : 256 - v; + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int j; + png_uint_32 sumhi, sumlo; + sumlo = sum & PNG_LOMASK; + sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; + + for (j = 0; j < num_p_filters; j++) + { + if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) + { + sumlo = (sumlo * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> + PNG_WEIGHT_SHIFT; + } + } + + sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> + PNG_COST_SHIFT; + + if (sumhi > PNG_HIMASK) + sum = PNG_MAXSUM; + else + sum = (sumhi << PNG_HISHIFT) + sumlo; + } +#endif + + if (sum < mins) + { + best_row = png_ptr->paeth_row; + } + } + + /* Do the actual writing of the filtered row data from the chosen filter. */ + + png_write_filtered_row(png_ptr, best_row); + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + /* Save the type of filter we picked this time for future calculations */ + if (png_ptr->num_prev_filters > 0) + { + int j; + for (j = 1; j < num_p_filters; j++) + { + png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; + } + png_ptr->prev_filters[j] = best_row[0]; + } +#endif +} + + +/* Do the actual writing of a previously filtered row. */ +void /* PRIVATE */ +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) +{ + png_debug(1, "in png_write_filtered_row\n"); + png_debug1(2, "filter = %d\n", filtered_row[0]); + /* set up the zlib input buffer */ + + png_ptr->zstream.next_in = filtered_row; + png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1; + /* repeat until we have compressed all the data */ + do + { + int ret; /* return of zlib */ + + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + /* check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + + /* see if it is time to write another IDAT */ + if (!(png_ptr->zstream.avail_out)) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + /* repeat until all data has been compressed */ + } while (png_ptr->zstream.avail_in); + + /* swap the current and previous rows */ + if (png_ptr->prev_row != NULL) + { + png_bytep tptr; + + tptr = png_ptr->prev_row; + png_ptr->prev_row = png_ptr->row_buf; + png_ptr->row_buf = tptr; + } + + /* finish row - updates counters and flushes zlib if last row */ + png_write_finish_row(png_ptr); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_ptr->flush_rows++; + + if (png_ptr->flush_dist > 0 && + png_ptr->flush_rows >= png_ptr->flush_dist) + { + png_write_flush(png_ptr); + } +#endif +} +#endif /* PNG_WRITE_SUPPORTED */ diff --git a/src/dep/src/irrlicht/libpng/projects/beos/x86-shared.proj b/src/dep/src/irrlicht/libpng/projects/beos/x86-shared.proj new file mode 100644 index 0000000000000000000000000000000000000000..6d2e3c31998f36b1fc44eb440f0c730f011d53f7 GIT binary patch literal 17031 zcmeHPUu+yl8K3QKle25bm&E^KJI#f(32kIwt3pMSqQuELPN?mid~VaCHrMsu`n-5= z_cXiylU9g*h@gtf15lyx#zP+p52!qW5JGu~0HLZceKBf?O5-|Vct zcFxIh=cv~CMxNdI^L;bl{C4Ks@4lJ!_=WTcV`sjT&hQz=j{hRVM{LHJ`Z+>|zr-nx z7|U>T0rxoKZUvY0u&(2lK-`5$;bBB2oAG9GBRZy}rX9yi<&6cya!RRLL(3c7O-&nA zxkEw}4^|luy;RyEU|^V4;8Aj1b7`j_at}N#b9$$sur|&LcuX6Pn{uzXo>5HgI7~8Y z`cz>I*!;HOo zwqtZ6JKmd^;+j5Z@Rv+uamtx9>^Ug&?=giPl8<0O+!Yo(H!?XH%c$I#aeGikFM+F_ zbY-k$7c{rX^Fz?|%gFCT+)z(d70Y!t-wshOj;Xt+=RMD{U3!}Y!tKp*qhwvl6%E%l z?1I5_QR$up-L*eW@j`*ImNsN|BPNz^4fq9J&snBDhkR{;MA)LBl}Z3!^GwH1Ee#eI z2TR=fmZ9S@R2gDxboGvFy(|lMe&~!bXjn7GlA+Ig+O&1Q7x4p@Wk}kSvt49SnZjZ0)H|dt z;Ri0R1m=r=Mx)}ld;h;i4f_nnmKwj5q2KMj!==(l-t-)vAuCSUOJp@JFE4-Iih4!C zA1(o#dPvuGm{zKa;hc4fCDSta#S$4ZF6=|b24_m9o*caR4ARZeM4*Yl&O$({iGz7- zRZWcHN7s5Kv9lm)j<$(F6M-lK(gf)t4-d-K7fX4~Gcxdj2pd9Hzgt|?$;10LRlqqS z?31OhJu7HX?kn}WF5oAGmue`q(4rz%o0hUB1G9*=!7Lin?83ZOFhV&+Q<82_(sc&r zQ_-<6Y1}sLf*{`LVUkS8B1}>8H5mg&N&ciHPl!J928sJtHnst)I2 z3Bs1stkJV)E1Gxd%*1H!#q3B9chF3xzy9=^7|m1@fhGctjDS=zeSvw$;-v0`c^9gd z@OR>|&;VSgQktez;ufNZz~w*nv7W z{X$O_io^jDa#69p$rZuFL^DzgFd4o$|X18QDU9|_wYwVY|qg6qwt0SGcmPzXqs?(8gqp{Ute z!?IRU9kd;ZA*;0P%H?8H;AkM?gac(2&$K=y{pXqLD6(p23Sb?#z3pZRDag)unT$ZF+U^hvQV92*#=OW=76M23egH zJBmuafqy9{#&zkIn$U`HUD4JVLL9qk;mMwwz&V9LD>RcCJ`*;u-pw_Q(>c{1%?Vn_ z1}BR$$n6c=RI<)I*8>ya>c>5P`sdwu=ydPzf&(k;llQvsd{k`r|Ms))J6{=i%qJR3 z6TgM~N%-H+nHHQs$^c`n;pQ*BB$$tQ;>M45kDEp6fDVT37d!7ugRbaxP73bjO~-(K5;X)eYQ_BY*fF z+;9r6F$cn}b-gOwYV(h7Xnqg!tq@-dAu&44Sd1Pkg&Hsl&)tOx&^z}LbYgJs@J0jb z#77w2jjaU=ehQpKY@`{5DbX4%-Xg%F zFcpnrL%{_7bnu4(O0~eWnSLs9e9h5NKqVRLzg7XLN2;4o!P^4-a@mD%i-yCAX2d@$ z;M7(fPMfVeZaNJ$ov`j+odirt#Hf0z5~j`89rw6qHyTj+%K(W+90jVqy7{yzQ2702 zH55=7Y1exIi9!uPZMN{-2D1yW@E(Tpg|A^fOnd5^PqgmbhMG@FLP&<_d`eUY)MhWd zg$A_8m0ayOZMNpCAoVxM=fNC7e zAmaZM?>hoZIUjsyPw86ye-{eEJ@*Rj3Q(Z7DEMfe?$s^nd$`zS2bY89YwaM=8IVZ+ z<_eu>;n%6Mm)Gj+Ca1RA^Rt5!egB76pqA)8$9 zM-IO9jDB4y9kLa5EY4lhXVq^EX-sxWACIgHzRbzTehk?omAc&UajER}2yxT2kxz-X PZ8~JH9RDDKPHFxR(DFj< literal 0 HcmV?d00001 diff --git a/src/dep/src/irrlicht/libpng/projects/beos/x86-shared.txt b/src/dep/src/irrlicht/libpng/projects/beos/x86-shared.txt new file mode 100644 index 0000000..ea62d61 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/beos/x86-shared.txt @@ -0,0 +1,22 @@ +This project builds a shared library version of libpng on x86 BeOS. + +It defines PNG_USE_PNGGCCRD, which activates the assembly code in +pnggccrd.c; this hasn't been extensively tested on BeOS. + +To install: + +1) build + + Note: As of version 1.0.10, you'll get a fair number of warnings when + you compile pnggccrd.c. As far as I know, these are harmless, + but it would be better if someone fixed them. + +2) copy and png.h, pngconf.h somewhere; /boot/home/config/include (which + you'll have to make) is a good choice + +3) copy libpng.so to /boot/home/config/lib + +4) build your libpng.so applications (remember to include libz.a as + well when you link) + +- Chris Herborth, March 27, 2001 diff --git a/src/dep/src/irrlicht/libpng/projects/beos/x86-static.proj b/src/dep/src/irrlicht/libpng/projects/beos/x86-static.proj new file mode 100644 index 0000000000000000000000000000000000000000..37c0753664a682120b138d997f0886ba4354e9b5 GIT binary patch literal 16706 zcmeHOO>7&-6`nOWHl`CW7}Rb&lkCAmy&Z_%X7y~&T#77 zA*mVWnp6Av)jQP))!j8&Ya7bJg7CARMH5JLI4xe@V&_)k|t3C9~ zSjj4AZqdmP!P2jy{t)tpe(I{(uCs+Mh;s3Qx@Ts=^K8qdr%52(zMR8L=9OHLyDqm1 z+{sl-_c-XT{bkxI6d3E+i^?A4*viR4zo6?m)3D}IZ!D1rTa>g?3BYTfVOz=NL~$um za_k>*9k-#*6j`ThR27f)i>?LVAHJV746DI`swva`_u`OhgzRdQJB@pHtmjx>&Z#TDQ!=>8v z+QmS8d21Zbt&oMD6I+qCL>8}TZVOo=jA>F3tlj3GZOtkKS?uj1i^>!S&Q7x`Z3#bc zaV0R{^gS9A@9u;D8ROP4bW2WL%Fugzf2vd(%^RNWWXOvX{t|hOtE;PDb)sKU@Q0s( zO+BjXI$SGNg*qd4v1FLsxmY4c#)W^#SYozh=<&qGCsA&vHUez~b`}ECOdQUeYi8mC zUb=2K5<3f$wzh2q+6Yu5AYG6?itwOaeXf+(Jf1-egkIpKtHItbF6k8EeVsZG91;G> z^7oz+eg@k8UA00N_Yy8ZoDfl}q0o!QnD?BdD)GQAVte5hUC^w;f>z+6oMKE#mymQl zf%{antxK9?8CF3MZ;UWWrbnxos>#=d4HzZ)3j!m($F#k&&A2T{<&4mU}Kcn!^<|Q|a$Nu`Wit)JC9x-mxf|JK^4i zrX_q&d^B_bZ!;-vSFn{AM_acx0{4o5G$=h&ZkoP+sZ-odYo74P6xsJA{6LE49fBXI zE;jgwd!OcWLatN5W`sz`y4%UNU6 zS#xX8x`BFc+Hf^|(k$YOn~cR_$S6%f!%OOi!?DLqdqy)6dUHtuK}H2i0jY8zJ4awB zYIcsB<{GLA%f{EnSp@C^>Yer*priH|T@7cLRCO|yov4mr5*`!)bw4^*rt&Ax?(^wd zow)3ywj-xI%CG&QvwRliLw`M9{^#fMa{SZdWm*taXK(cRl-*IrZg#~hA^m>zzx6?9 zc_Ym$^FiCMF%FHp>sqv&MjOc_=9xI?#~+MW{(GjQd=~9A4qa(1x)RNehvF5{4!U2w z7Y*b?`ENgsuJx_{e0TXQ#tLak4k}|fc4L3M(q|kMb!w0H#w+ygo@62#l10e<%t5~! z?XM2@3Y|q84S;sW;uXSystW2iFn{rXJ!R@6x-#m6=qqEqXP@pB?L;ehiC@yu_0!3N zes)fCuDua0tLK62ipoe&K_5d9yE|U_Gy3SH8MS{0^((Kh*Iz*Wk*7OEe~1zBQklIs z;ERlUcyH)6l<=hSLTqW=S0v8tvwolI8}AMK;eh`~%oW}n8YkqZtB@HqnOM9se!91O zQkGSyM3@{#oyH(O>ZA4^(7rv{TfPnx7ekqNsr|$8$gM9Pj@+6?dpZ{HSRoS#9;%<} zkK7`9>L)7@^5DeAEwFxF&+0Z9Rnk4Q522orm!(w`YUSEXcq zQtT)y`2>DnE{y9kEH$YW5xSyJXGl?eO$$%{58@L}q{n#D2 z5fof!4uo5udQG^s;g4(>{z23`A-)tsVswnL2;Ejn4PX?Wy9*JZXYRK!33nXZX*Hlu zeGKhZwiYPFDR2_8l~xp%L}##l8(L9^fv-q%Pj#WvffZHYUaP^Rkl~|Lz43gwJsZN+S+joxVXjZEMmA?#-NaJdtM(bNon*xRRFSDh9f~LLi z03=Ec0JYfz&uuZk02}WC7+=I18iHxF^+fy5ZK?GXCxm3GUQc87ZM@AMc#AFQk1M&x zaoTL(Ew$bQ@4!!Lz%*Xpa@uU)EjfnATWa6IKt(Uz2cTNfGdOeQJ^8k)G8jF&T;ptl6mcB!XO-^t*7{1X70-FJe + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=1 +Locale=2057 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +Comments= + +[HistoryLists\hlIncludePath] +Count=18 +Item0=..\..;..\..\..\zlib;$(BCB)\include +Item1=..\..;P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include +Item2=..\..;..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression\external;$(BCB)\include +Item3=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression\external;$(BCB)\include +Item4=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression;$(BCB)\include +Item5=..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression;$(BCB)\include +Item6=..\Source\ThirdParty\PortableNetworkGraphics;P:\Development\Source\ThirdParty\ZLibCompression;$(BCB)\include +Item7=..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\include +Item8=$(BCB)\include +Item9=..\Source;..\Source\General\Templates;..\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl +Item10=P:\Development\Source\;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl +Item11=P:\Development\Source;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl +Item12=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl +Item13=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl +Item14=P:\Development\Source\General\Templates\;$(BCB)\include;$(BCB)\include\vcl +Item15=P:\Development\Source\General\Templates;$(BCB)\include;$(BCB)\include\vcl +Item16=P:\Development\Source;$(BCB)\include;$(BCB)\include\vcl +Item17=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=10 +Item0=..\..;$(BCB)\lib\obj;$(BCB)\lib +Item1=..\..;..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib +Item2=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib +Item3=..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib +Item4=$(BCB)\lib\obj;$(BCB)\lib +Item5=..\Source\SIMUtilities;..\Source;$(BCB)\lib\obj;$(BCB)\lib +Item6=P:\Development\Source\SIMUtilities\;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib +Item7=P:\Development\Source\SIMUtilities;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib +Item8=P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib +Item9=P:\Development\Source;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=20 +Item0=ZLIB_DLL;Z_PREFIX;PNG_BUILD_DLL;PNG_NO_MODULEDEF +Item1=_DEBUG;ZLIB_DLL;Z_PREFIX;PNG_BUILD_DLL;PNG_NO_MODULEDEF +Item2=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_NO_MODULEDEF +Item3=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_NO_GLOBAL_ARRAYS +Item4=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED;PNG_DEBUG_FILE=stderr +Item5=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED +Item6=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED +Item7=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF +Item8=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5 +Item9=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG +Item10=PNG_BUILD_DLL;ZLIB_DLL +Item11=PNG_BUILD_DLL +Item12=PNG_DLL;PNG_BUILD_DLL;ZLIB_DLL +Item13=PNG_DLL;PNG_BUILD_DLL;PNG_NO_GLOBAL_ARRAYS;ZLIB_DLL +Item14=PNG_DLL;PNG_BUILD_DLL;PNG_NO_GLOBAL_ARRAYS +Item15=PNG_DLL;PNG_BUILD_DLL +Item16=PNG_DLL;PNG_BUILD_DLL;PNG_MODULEDEF +Item17=_HTML_FORM +Item18=_DEBUG;_HTML_FORM +Item19=_DEBUG + +[HistoryLists\hlIntOutputDir] +Count=2 +Item0=..\Obj +Item1=P:\Development\Obj + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication=P:\Development\Executables\LibPNGTestApp.exe +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + + \ No newline at end of file diff --git a/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.cpp b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.cpp new file mode 100644 index 0000000..97865f5 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.cpp @@ -0,0 +1,29 @@ +//--------------------------------------------------------------------------- +#include +//--------------------------------------------------------------------------- +// Important note about DLL memory management when your DLL uses the +// static version of the RunTime Library: +// +// If your DLL exports any functions that pass String objects (or structs/ +// classes containing nested Strings) as parameter or function results, +// you will need to add the library MEMMGR.LIB to both the DLL project and +// any other projects that use the DLL. You will also need to use MEMMGR.LIB +// if any other projects which use the DLL will be performing new or delete +// operations on any non-TObject-derived classes which are exported from the +// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling +// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases, +// the file BORLNDMM.DLL should be deployed along with your DLL. +// +// To avoid using BORLNDMM.DLL, pass string information using "char *" or +// ShortString parameters. +// +// If your DLL uses the dynamic version of the RTL, you do not need to +// explicitly add MEMMGR.LIB as this will be done implicitly for you +//--------------------------------------------------------------------------- + +int WINAPI DllEntryPoint(HINSTANCE, unsigned long, void*) +{ + return 1; +} +//--------------------------------------------------------------------------- + \ No newline at end of file diff --git a/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.readme.txt b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.readme.txt new file mode 100644 index 0000000..704c121 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpng.readme.txt @@ -0,0 +1,25 @@ +Project files to build libpng using Borland C++ Builder v5.0 + +In order to build and use libpng, please follow these steps: + + 1). Install zlib in a directory at the same level with libpng. + + 2). In a console window, go to the zlib directory and type: + make -f win32\Makefile.bor + After performing this step, you should have a file named + zlib.lib in the zlib directory. + + 3). Add the following conditional define to your project: + PNG_USE_DLL + + 4). Add libpng.lib or libpngstat.lib to the project. + Build the project. + + 5). If the build fails, add the paths to png.h and zlib.h to + your include path, and restart the build. + +By default, the libpng project uses zlib as a static library. If +you wish to use zlib as a DLL, please read the important notes from +the zlib DLL FAQ, found inside the zlib distribution. + +See the libpng documentation for instructions on how to use the code. diff --git a/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpf b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpf new file mode 100644 index 0000000..f736b62 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpf @@ -0,0 +1,22 @@ +USEUNIT("..\..\png.c"); +USEUNIT("..\..\pngerror.c"); +USEUNIT("..\..\pngget.c"); +USEUNIT("..\..\pngmem.c"); +USEUNIT("..\..\pngpread.c"); +USEUNIT("..\..\pngread.c"); +USEUNIT("..\..\pngrio.c"); +USEUNIT("..\..\pngrtran.c"); +USEUNIT("..\..\pngrutil.c"); +USEUNIT("..\..\pngset.c"); +USEUNIT("..\..\pngtrans.c"); +USEUNIT("..\..\pngwio.c"); +USEUNIT("..\..\pngwrite.c"); +USEUNIT("..\..\pngwtran.c"); +USEUNIT("..\..\pngwutil.c"); +USELIB("..\..\..\zlib\zlib.lib"); +//--------------------------------------------------------------------------- +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + + \ No newline at end of file diff --git a/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpr b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpr new file mode 100644 index 0000000..68abb8d --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/cbuilder5/libpngstat.bpr @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=2057 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=..\..;P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include +Item1=..\..;$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=..\..;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlTlibPageSize] +Count=1 +Item0=0x0010 + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[Language] +ActiveLang= +ProjectLang= +RootDir= + + \ No newline at end of file diff --git a/src/dep/src/irrlicht/libpng/projects/cbuilder5/zlib.readme.txt b/src/dep/src/irrlicht/libpng/projects/cbuilder5/zlib.readme.txt new file mode 100644 index 0000000..9fb4557 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/cbuilder5/zlib.readme.txt @@ -0,0 +1,14 @@ +The project that builds libpng under Borland C++ Builder does not +explicitly build zlib. By taking this decision, there is no need +to update the libpng project each time when there is a change in +the list of zlib source files. After all, this list is private to +zlib, and applications (such as libpng) should not assume anything +about it. + +If you wish to contribute a project that builds zlib under Borland +C++ Builder, please submit it to the zlib developers, not to the +libpng developers. + +By default, the libpng project uses zlib as a static library. If +you wish to use zlib as a DLL, please read the important notes from +the zlib DLL FAQ, found inside the zlib distribution. diff --git a/src/dep/src/irrlicht/libpng/projects/netware.txt b/src/dep/src/irrlicht/libpng/projects/netware.txt new file mode 100644 index 0000000..4ba5ba3 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/netware.txt @@ -0,0 +1,6 @@ +A set of project files is available for Netware. Get +libpng-1.2.5-project-netware.zip from a libpng distribution +site such as http://libpng.sourceforge.net + +Put the zip file in this directory (projects) and then run +"unzip -a libpng-1.2.5-project-netware.zip" diff --git a/src/dep/src/irrlicht/libpng/projects/visualc6/README.txt b/src/dep/src/irrlicht/libpng/projects/visualc6/README.txt new file mode 100644 index 0000000..863d39b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc6/README.txt @@ -0,0 +1,57 @@ +Microsoft Developer Studio Project File, Format Version 6.00 for libpng. + +Copyright (C) 2000-2004 Simon-Pierre Cadieux. +Copyright (C) 2004 Cosmin Truta. +For conditions of distribution and use, see copyright notice in png.h + + +Assumptions: +* The libpng source files are in ..\.. +* The zlib source files are in ..\..\..\zlib +* The zlib project files are in ..\..\..\zlib\projects\visualc6 + + +To use: + +1) On the main menu, select "File | Open Workspace". + Open "libpng.dsw". + +2) Select "Build | Set Active Configuration". + Choose the configuration you wish to build. + (Choose libpng or pngtest; zlib will be built automatically.) + +3) Select "Build | Clean". + +4) Select "Build | Build ... (F7)". Ignore warning messages about + not being able to find certain include files (e.g. alloc.h). + +5) If you built the sample program (pngtest), + select "Build | Execute ... (Ctrl+F5)". + + +This project builds the libpng binaries as follows: + +* Win32_DLL_Release\libpng13.dll DLL build +* Win32_DLL_Debug\libpng13d.dll DLL build (debug version) +* Win32_DLL_ASM_Release\libpng13.dll DLL build using ASM code +* Win32_DLL_ASM_Debug\libpng13d.dll DLL build using ASM (debug version) +* Win32_DLL_VB\libpng13vb.dll DLL build for Visual Basic, using stdcall +* Win32_LIB_Release\libpng.lib static build +* Win32_LIB_Debug\libpngd.lib static build (debug version) +* Win32_LIB_ASM_Release\libpng.lib static build using ASM code +* Win32_LIB_ASM_Debug\libpngd.lib static build using ASM (debug version) + + +Notes: + +If you change anything in the source files, or select different compiler +settings, please change the DLL name to something different than any of +the above names. Also, make sure that in your "pngusr.h" you define +PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX according to the +instructions provided in "pngconf.h". + +All DLLs built by this project use the Microsoft dynamic C runtime library +MSVCRT.DLL (MSVCRTD.DLL for debug versions). If you distribute any of the +above mentioned libraries you should also include this DLL in your package. +For a list of files that are redistributable in Visual C++ 6.0, see +Common\Redist\Redist.txt on Disc 1 of the Visual C++ 6.0 product CDs. diff --git a/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsp b/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsp new file mode 100644 index 0000000..223362a --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsp @@ -0,0 +1,507 @@ +# Microsoft Developer Studio Project File - Name="libpng" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libpng - Win32 DLL Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libpng.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libpng.mak" CFG="libpng - Win32 DLL Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libpng - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpng - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpng - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpng - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpng - Win32 DLL VB" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpng - Win32 LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libpng - Win32 LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "libpng - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libpng - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "libpng - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpng___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "libpng___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /machine:I386 +# ADD LINK32 zlib1.lib /nologo /dll /machine:I386 /out:"Win32_DLL_Release\libpng13.dll" /libpath:"..\..\..\zlib\projects\visualc6\Win32_DLL_Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libpng___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "libpng___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D PNG_DEBUG=1 /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "_DEBUG" /d PNG_DEBUG=1 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib1d.lib /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\libpng13d.dll" /libpath:"..\..\..\zlib\projects\visualc6\Win32_DLL_Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpng___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "libpng___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_USE_PNGVCRD" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /D "PNG_LIBPNG_SPECIALBUILD" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" /d PNG_LIBPNG_SPECIALBUILD=""""Use MMX instructions"""" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /machine:I386 +# ADD LINK32 zlib1.lib /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\libpng13.dll" /libpath:"..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libpng___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "libpng___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D PNG_DEBUG=1 /D "PNG_USE_PNGVCRD" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /D "PNG_LIBPNG_SPECIALBUILD" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "_DEBUG" /d PNG_DEBUG=1 /d PNG_LIBPNG_SPECIALBUILD=""""Use MMX instructions"""" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib1d.lib /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\libpng13d.dll" /libpath:"..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpng___Win32_DLL_VB" +# PROP BASE Intermediate_Dir "libpng___Win32_DLL_VB" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_VB" +# PROP Intermediate_Dir "Win32_DLL_VB" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /D PNGAPI=__stdcall /D "PNG_NO_MODULEDEF" /D "PNG_LIBPNG_SPECIALBUILD" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" /dPNG_LIBPNG_DLLFNAME_POSTFIX=""""VB"""" /dPNG_LIBPNG_SPECIALBUILD=""""__stdcall calling convention used for exported functions"""" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /machine:I386 +# ADD LINK32 zlib1.lib /nologo /dll /machine:I386 /out:"Win32_DLL_VB\libpng13vb.dll" /libpath:"..\..\..\zlib\projects\visualc6\Win32_DLL_Release" +# Begin Special Build Tool +OutDir=.\Win32_DLL_VB +TargetName=libpng13vb +SOURCE="$(InputPath)" +PostBuild_Cmds=echo Deleting $(targetname) import library and export file (Not required for VB projects) del $(outdir)\$(targetname).lib del $(outdir)\$(targetname).exp +# End Special Build Tool + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpng___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "libpng___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libpng___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "libpng___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D PNG_DEBUG=1 /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_Debug\libpngd.lib" + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "libpng___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "libpng___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "libpng___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "libpng___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "DEBUG" /D PNG_DEBUG=1 /D "PNG_USE_PNGVCRD" /D "PNG_LIBPNG_SPECIALBUILD" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\libpngd.lib" + +!ENDIF + +# Begin Target + +# Name "libpng - Win32 DLL Release" +# Name "libpng - Win32 DLL Debug" +# Name "libpng - Win32 DLL ASM Release" +# Name "libpng - Win32 DLL ASM Debug" +# Name "libpng - Win32 DLL VB" +# Name "libpng - Win32 LIB Release" +# Name "libpng - Win32 LIB Debug" +# Name "libpng - Win32 LIB ASM Release" +# Name "libpng - Win32 LIB ASM Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\png.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngerror.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngget.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngmem.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngpread.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngread.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngrio.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngrtran.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngrutil.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngset.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngtrans.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngvcrd.c + +!IF "$(CFG)" == "libpng - Win32 DLL Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\scripts\pngw32.def + +!IF "$(CFG)" == "libpng - Win32 DLL Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\pngwio.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngwrite.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngwtran.c +# End Source File +# Begin Source File + +SOURCE=..\..\pngwutil.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\png.h +# End Source File +# Begin Source File + +SOURCE=..\..\pngconf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\..\scripts\pngw32.rc + +!IF "$(CFG)" == "libpng - Win32 DLL Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Release" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM Debug" + +!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB" + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "libpng - Win32 LIB ASM Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\README.txt +# End Source File +# End Target +# End Project diff --git a/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsw b/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsw new file mode 100644 index 0000000..2a98646 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc6/libpng.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libpng"=".\libpng.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "pngtest"=".\pngtest.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libpng + End Project Dependency +}}} + +############################################################################### + +Project: "zlib"="..\..\..\zlib\projects\visualc6\zlib.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/dep/src/irrlicht/libpng/projects/visualc6/pngtest.dsp b/src/dep/src/irrlicht/libpng/projects/visualc6/pngtest.dsp new file mode 100644 index 0000000..2e5845c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc6/pngtest.dsp @@ -0,0 +1,314 @@ +# Microsoft Developer Studio Project File - Name="pngtest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pngtest - Win32 DLL Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pngtest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pngtest.mak" CFG="pngtest - Win32 DLL Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pngtest - Win32 DLL Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 DLL Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 LIB Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 LIB Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pngtest - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pngtest - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "pngtest___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "pngtest___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_DLL" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 +# ADD LINK32 Win32_DLL_Release\libpng13.lib ..\..\..\zlib\projects\visualc6\Win32_DLL_Release\zlib1.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +OutDir=.\Win32_DLL_Release +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=set path=$(outdir);..\..\..\zlib\projects\visualc6\Win32_DLL_Release; $(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "pngtest___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "pngtest___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_DLL" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Win32_DLL_Debug\libpng13d.lib ..\..\..\zlib\projects\visualc6\Win32_DLL_Debug\zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +OutDir=.\Win32_DLL_Debug +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=set path=$(outdir);..\..\..\zlib\projects\visualc6\Win32_DLL_Debug; $(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "pngtest___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "pngtest___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_DLL" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 +# ADD LINK32 Win32_DLL_ASM_Release\libpng13.lib ..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Release\zlib1.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +OutDir=.\Win32_DLL_ASM_Release +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=set path=$(outdir);..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Release; $(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "pngtest___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "pngtest___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_DLL" /D "PNG_NO_STDIO" /D "PNG_NO_GLOBAL_ARRAYS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Win32_DLL_ASM_Debug\libpng13d.lib ..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Debug\zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +OutDir=.\Win32_DLL_ASM_Debug +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=set path=$(outdir);..\..\..\zlib\projects\visualc6\Win32_DLL_ASM_Debug; $(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "pngtest___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "pngtest___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 +# ADD LINK32 Win32_LIB_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Release\zlib.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +OutDir=.\Win32_LIB_Release +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=$(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "pngtest___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "pngtest___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Win32_LIB_Debug\libpngd.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Debug\zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +OutDir=.\Win32_LIB_Debug +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=$(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "pngtest___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "pngtest___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 +# ADD LINK32 Win32_LIB_ASM_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_ASM_Release\zlib.lib /nologo /subsystem:console /machine:I386 +# Begin Special Build Tool +OutDir=.\Win32_LIB_ASM_Release +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=$(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ELSEIF "$(CFG)" == "pngtest - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "pngtest___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "pngtest___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 Win32_LIB_ASM_Debug\libpngd.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_ASM_Debug\zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +OutDir=.\Win32_LIB_ASM_Debug +SOURCE="$(InputPath)" +PostBuild_Desc=[Run Test] +PostBuild_Cmds=$(outdir)\pngtest.exe ..\..\pngtest.png +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "pngtest - Win32 DLL Release" +# Name "pngtest - Win32 DLL Debug" +# Name "pngtest - Win32 DLL ASM Release" +# Name "pngtest - Win32 DLL ASM Debug" +# Name "pngtest - Win32 LIB Release" +# Name "pngtest - Win32 LIB Debug" +# Name "pngtest - Win32 LIB ASM Release" +# Name "pngtest - Win32 LIB ASM Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\pngtest.c +# End Source File +# End Group +# End Target +# End Project diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/PRJ0041.mak b/src/dep/src/irrlicht/libpng/projects/visualc71/PRJ0041.mak new file mode 100644 index 0000000..3a597b0 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/PRJ0041.mak @@ -0,0 +1,21 @@ +# Prevent "Cannot find missing dependency..." warnings while compiling +# pngw32.rc (PRJ0041). + +all: $(IntDir)\alloc.h \ + $(IntDir)\fp.h \ + $(IntDir)\m68881.h \ + $(IntDir)\mem.h \ + $(IntDir)\pngusr.h \ + $(IntDir)\strings.h \ + $(IntDir)\unistd.h \ + $(IntDir)\unixio.h + +$(IntDir)\alloc.h \ +$(IntDir)\fp.h \ +$(IntDir)\m68881.h \ +$(IntDir)\mem.h \ +$(IntDir)\pngusr.h \ +$(IntDir)\strings.h \ +$(IntDir)\unistd.h \ +$(IntDir)\unixio.h: + @!echo.>$@ diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/README.txt b/src/dep/src/irrlicht/libpng/projects/visualc71/README.txt new file mode 100644 index 0000000..e49af14 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/README.txt @@ -0,0 +1,57 @@ +Microsoft Developer Studio Project File, Format Version 7.10 for libpng. + +Copyright (C) 2004 Simon-Pierre Cadieux. +For conditions of distribution and use, see copyright notice in png.h + +Assumptions: +* The libpng source files are in ..\.. +* The zlib source files are in ..\..\..\zlib +* The zlib project file is in . /* Warning: This is until the zlib project + files get intergrated into the next zlib release. The final zlib project + directory will then be ..\..\..\zlib\projects\visualc71. */ + +To use: + +1) On the main menu, select "File | Open Solution". + Open "libpng.sln". + +2) Display the Solution Explorer view (Ctrl+Alt+L) + +3) Set one of the project as the StartUp project. If you just want to build the + binaries set "libpng" as the startup project (Select "libpng" tree view + item + Project | Set as StartUp project). If you want to build and test the + binaries set it to "pngtest" (Select "pngtest" tree view item + + Project | Set as StartUp project) + +4) Select "Build | Configuration Manager...". + Choose the configuration you wish to build. + +5) Select "Build | Clean Solution". + +6) Select "Build | Build Solution (Ctrl-Shift-B)" + +This project builds the libpng binaries as follows: + +* Win32_DLL_Release\libpng13.dll DLL build +* Win32_DLL_Debug\libpng13d.dll DLL build (debug version) +* Win32_DLL_ASM_Release\libpng13.dll DLL build using ASM code +* Win32_DLL_ASM_Debug\libpng13d.dll DLL build using ASM (debug version) +* Win32_DLL_VB\libpng13vb.dll DLL build for Visual Basic, using stdcall +* Win32_LIB_Release\libpng.lib static build +* Win32_LIB_Debug\libpngd.lib static build (debug version) +* Win32_LIB_ASM_Release\libpng.lib static build using ASM code +* Win32_LIB_ASM_Debug\libpngd.lib static build using ASM (debug version) + +Notes: + +If you change anything in the source files, or select different compiler +settings, please change the DLL name to something different than any of +the above names. Also, make sure that in your "pngusr.h" you define +PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX according to the +instructions provided in "pngconf.h". + +All DLLs built by this project use the Microsoft dynamic C runtime library +MSVCR71.DLL (MSVCR71D.DLL for debug versions). If you distribute any of the +above mentioned libraries you may have to include this DLL in your package. +For a list of files that are redistributable in Visual Studio see +$(VCINSTALLDIR)\redist.txt. diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/README_zlib.txt b/src/dep/src/irrlicht/libpng/projects/visualc71/README_zlib.txt new file mode 100644 index 0000000..589f5f4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/README_zlib.txt @@ -0,0 +1,44 @@ +/* WARNING: This file was put in the LibPNG distribution for convenience only. + It is expected to be part of the next zlib release under + "projects\visualc71\README.txt." */ + +Microsoft Developer Studio Project File, Format Version 7.10 for zlib. + +Copyright (C) 2004 Simon-Pierre Cadieux. +Copyright (C) 2004 Cosmin Truta. +For conditions of distribution and use, see copyright notice in zlib.h. + + +To use: + +1) On the main menu, select "File | Open Solution". + Open "zlib.sln". + +2) Display the Solution Explorer view (Ctrl+Alt+L) + +3) Set one of the project as the StartUp project. If you just want to build the + binaries set "zlib" as the startup project (Select "zlib" tree view item + + Project | Set as StartUp project). If you want to build and test the + binaries set it to "example" (Select "example" tree view item + Project | + Set as StartUp project), If you want to build the minigzip utility set it to + "minigzip" (Select "minigzip" tree view item + Project | Set as StartUp + project + +4) Select "Build | Configuration Manager...". + Choose the configuration you wish to build. + +5) Select "Build | Clean Solution". + +6) Select "Build | Build Solution (Ctrl-Shift-B)" + +This project builds the zlib binaries as follows: + +* Win32_DLL_Release\zlib1.dll DLL build +* Win32_DLL_Debug\zlib1d.dll DLL build (debug version) +* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code +* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version) +* Win32_LIB_Release\zlib.lib static build +* Win32_LIB_Debug\zlibd.lib static build (debug version) +* Win32_LIB_ASM_Release\zlib.lib static build using ASM code +* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version) + diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.sln b/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.sln new file mode 100644 index 0000000..7f75b0c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.sln @@ -0,0 +1,88 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng.vcproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" + ProjectSection(ProjectDependencies) = postProject + {2D4F8105-7D21-454C-9932-B47CAB71A5C0} = {2D4F8105-7D21-454C-9932-B47CAB71A5C0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pngtest", "pngtest.vcproj", "{FD1C2F86-9EEF-47BD-95A4-530917E17FDA}" + ProjectSection(ProjectDependencies) = postProject + {0008960E-E0DD-41A6-8265-00B31DDB4C21} = {0008960E-E0DD-41A6-8265-00B31DDB4C21} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib.vcproj", "{2D4F8105-7D21-454C-9932-B47CAB71A5C0}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + DLL ASM Debug = DLL ASM Debug + DLL ASM Release = DLL ASM Release + DLL Debug = DLL Debug + DLL Release = DLL Release + DLL VB = DLL VB + LIB ASM Debug = LIB ASM Debug + LIB ASM Release = LIB ASM Release + LIB Debug = LIB Debug + LIB Release = LIB Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL ASM Debug.ActiveCfg = DLL ASM Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL ASM Debug.Build.0 = DLL ASM Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL ASM Release.ActiveCfg = DLL ASM Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL ASM Release.Build.0 = DLL ASM Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug.ActiveCfg = DLL Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Debug.Build.0 = DLL Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release.ActiveCfg = DLL Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL Release.Build.0 = DLL Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB.ActiveCfg = DLL VB|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.DLL VB.Build.0 = DLL VB|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB ASM Debug.ActiveCfg = LIB ASM Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB ASM Debug.Build.0 = LIB ASM Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB ASM Release.ActiveCfg = LIB ASM Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB ASM Release.Build.0 = LIB ASM Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug.ActiveCfg = LIB Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Debug.Build.0 = LIB Debug|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Release.ActiveCfg = LIB Release|Win32 + {0008960E-E0DD-41A6-8265-00B31DDB4C21}.LIB Release.Build.0 = LIB Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL ASM Debug.ActiveCfg = DLL ASM Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL ASM Debug.Build.0 = DLL ASM Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL ASM Release.ActiveCfg = DLL ASM Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL ASM Release.Build.0 = DLL ASM Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Debug.ActiveCfg = DLL Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Debug.Build.0 = DLL Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Release.ActiveCfg = DLL Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL Release.Build.0 = DLL Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL VB.ActiveCfg = DLL VB|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.DLL VB.Build.0 = DLL VB|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB ASM Debug.ActiveCfg = LIB ASM Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB ASM Debug.Build.0 = LIB ASM Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB ASM Release.ActiveCfg = LIB ASM Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB ASM Release.Build.0 = LIB ASM Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Debug.ActiveCfg = LIB Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Debug.Build.0 = LIB Debug|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Release.ActiveCfg = LIB Release|Win32 + {FD1C2F86-9EEF-47BD-95A4-530917E17FDA}.LIB Release.Build.0 = LIB Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL ASM Debug.ActiveCfg = DLL ASM Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL ASM Debug.Build.0 = DLL ASM Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL ASM Release.ActiveCfg = DLL ASM Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL ASM Release.Build.0 = DLL ASM Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Debug.ActiveCfg = DLL Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Debug.Build.0 = DLL Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Release.ActiveCfg = DLL Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL Release.Build.0 = DLL Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL VB.ActiveCfg = DLL Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.DLL VB.Build.0 = DLL Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB ASM Debug.ActiveCfg = LIB ASM Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB ASM Debug.Build.0 = LIB ASM Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB ASM Release.ActiveCfg = LIB ASM Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB ASM Release.Build.0 = LIB ASM Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Debug.ActiveCfg = LIB Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Debug.Build.0 = LIB Debug|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Release.ActiveCfg = LIB Release|Win32 + {2D4F8105-7D21-454C-9932-B47CAB71A5C0}.LIB Release.Build.0 = LIB Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.vcproj b/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.vcproj new file mode 100644 index 0000000..19c631f --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/libpng.vcproj @@ -0,0 +1,735 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/pngtest.vcproj b/src/dep/src/irrlicht/libpng/projects/visualc71/pngtest.vcproj new file mode 100644 index 0000000..210566c --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/pngtest.vcproj @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dep/src/irrlicht/libpng/projects/visualc71/zlib.vcproj b/src/dep/src/irrlicht/libpng/projects/visualc71/zlib.vcproj new file mode 100644 index 0000000..bc0a2bf --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/visualc71/zlib.vcproj @@ -0,0 +1,670 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dep/src/irrlicht/libpng/projects/wince.txt b/src/dep/src/irrlicht/libpng/projects/wince.txt new file mode 100644 index 0000000..4ccff38 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/projects/wince.txt @@ -0,0 +1,6 @@ +A set of project files is available for WinCE. Get +libpng-1.2.5-project-wince.zip from a libpng distribution +site such as http://libpng.sourceforge.net + +Put the zip file in this directory (projects) and then run +"unzip -a libpng-1.2.5-project-wince.zip" diff --git a/src/dep/src/irrlicht/libpng/scripts/CMakeLists.txt b/src/dep/src/irrlicht/libpng/scripts/CMakeLists.txt new file mode 100644 index 0000000..901eb81 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/CMakeLists.txt @@ -0,0 +1,213 @@ +project(PNG) + +# Copyright (C) 2007 Glenn Randers-Pehrson +# For conditions of distribution and use, see copyright notice in png.h + +set(PNGLIB_MAJOR 1) +set(PNGLIB_MINOR 2) +set(PNGLIB_RELEASE 18) +set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR}) +set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE}) + +# needed packages +find_package(ZLIB REQUIRED) +if(NOT WIN32) + find_library(M_LIBRARY + NAMES m + PATHS /usr/lib /usr/local/lib + ) + if(NOT M_LIBRARY) + message(STATUS + "math library 'libm' not found - floating point support disabled") + endif(NOT M_LIBRARY) +else(NOT WIN32) + # not needed on windows + set(M_LIBRARY "") +endif(NOT WIN32) + + +# COMMAND LINE OPTIONS +option(PNG_SHARED "Build shared lib" YES) +option(PNG_STATIC "Build static lib" YES) +option(PNG_TESTS "Build pngtest" YES) +option(PNG_NO_CONSOLE_IO "FIXME" YES) +option(PNG_NO_STDIO "FIXME" YES) +option(PNG_DEBUG "Build with debug output" YES) +option(PNGARG "FIXME" YES) +#TODO: +# PNG_CONSOLE_IO_SUPPORTED + +# maybe needs improving, but currently I don't know when we can enable what :) +set(png_asm_tmp "OFF") +if(NOT WIN32) + find_program(uname_executable NAMES uname PATHS /bin /usr/bin /usr/local/bin) + if(uname_executable) + EXEC_PROGRAM(${uname_executable} ARGS --machine OUTPUT_VARIABLE uname_output) + if("uname_output" MATCHES "^.*i[1-9]86.*$") + set(png_asm_tmp "ON") + else("uname_output" MATCHES "^.*i[1-9]86.*$") + set(png_asm_tmp "OFF") + endif("uname_output" MATCHES "^.*i[1-9]86.*$") + endif(uname_executable) +endif(NOT WIN32) + +option(PNG_MMX "Use MMX assembler code (x86 only)" ${png_asm_tmp}) + +# SET LIBNAME +# msvc does not append 'lib' - do it here to have consistent name +if(MSVC) + set(PNG_LIB_NAME lib) +endif(MSVC) +set(PNG_LIB_NAME ${PNG_LIB_NAME}png${PNGLIB_MAJOR}${PNGLIB_MINOR}) + +# to distinguish between debug and release lib +set(CMAKE_DEBUG_POSTFIX "d") + + +# OUR SOURCES +set(libpng_sources + png.h + pngconf.h + png.c + pngerror.c + pngget.c + pngmem.c + pngpread.c + pngread.c + pngrio.c + pngrtran.c + pngrutil.c + pngset.c + pngtrans.c + pngwio.c + pngwrite.c + pngwtran.c + pngwutil.c +) +set(pngtest_sources + pngtest.c +) +# SOME NEEDED DEFINITIONS +add_definitions(-DZLIB_DLL) + +if(MSVC) + add_definitions(-DPNG_USE_PNGVCRD -DPNG_NO_MODULEDEF + -D_CRT_SECURE_NO_DEPRECATE) + set(libpng_sources ${libpng_sources} + pngvcrd.c + ) +else(MSVC) + add_definitions(-DPNG_USE_PNGGCCRD) + set(libpng_sources ${libpng_sources} + pnggccrd.c + ) +endif(MSVC) + +if(NOT MSVC) + if(NOT PNG_MMX) + add_definitions(-DLIBPNG_NO_MMX) + add_definitions(-DPNG_NO_MMX_CODE) + endif(NOT PNG_MMX) +else(NOT MSVC) + if(PNG_MMX) + # maybe add this to pngconf.h ? + add_definitions(-DPNG_MMX_CODE_SUPPORTED) + endif(PNG_MMX) +endif(NOT MSVC) + + +if(PNG_CONSOLE_IO_SUPPORTED) + add_definitions(-DPNG_CONSOLE_IO_SUPPORTED) +endif(PNG_CONSOLE_IO_SUPPORTED) + +if(PNG_NO_CONSOLE_IO) + add_definitions(-DPNG_NO_CONSOLE_IO) +endif(PNG_NO_CONSOLE_IO) + +if(PNG_NO_STDIO) + add_definitions(-DPNG_NO_STDIO) +endif(PNG_NO_STDIO) + +if(PNG_DEBUG) + add_definitions(-DPNG_DEBUG) +endif(PNG_DEBUG) + +if(NOT M_LIBRARY) + add_definitions(-DPNG_NO_FLOATING_POINT_SUPPORTED) +endif(NOT M_LIBRARY) + +# NOW BUILD OUR TARGET +include_directories(${PNG_SOURCE_DIR} ${ZLIB_INCLUDE_DIR}) + +if(PNG_SHARED) + add_library(${PNG_LIB_NAME} SHARED ${libpng_sources}) + target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY}) +endif(PNG_SHARED) +if(PNG_STATIC) +# does not work without changing name + set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static) + add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources}) +endif(PNG_STATIC) + +if(PNG_SHARED AND WIN32) + set_target_properties(${PNG_LIB_NAME} PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL) +endif(PNG_SHARED AND WIN32) + +if(PNG_TESTS) +# does not work with msvc due to png_lib_ver issue + add_executable(pngtest ${pngtest_sources}) + target_link_libraries(pngtest ${PNG_LIB_NAME}) +# add_test(pngtest ${PNG_SOURCE_DIR}/pngtest.png) +endif(PNG_TESTS) + + +# CREATE PKGCONFIG FILES +# we use the same files like ./configure, so we have to set its vars +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix ${CMAKE_INSTALL_PREFIX}) +set(libdir ${CMAKE_INSTALL_PREFIX}/lib) +set(includedir ${CMAKE_INSTALL_PREFIX}/include) + +configure_file(${PNG_SOURCE_DIR}/scripts/libpng.pc.in + ${PNG_BINARY_DIR}/libpng.pc) +configure_file(${PNG_SOURCE_DIR}/scripts/libpng-config.in + ${PNG_BINARY_DIR}/libpng-config) +configure_file(${PNG_SOURCE_DIR}/scripts/libpng.pc.in + ${PNG_BINARY_DIR}/${PNGLIB_NAME}.pc) +configure_file(${PNG_SOURCE_DIR}/scripts/libpng-config.in + ${PNG_BINARY_DIR}/${PNGLIB_NAME}-config) + +# SET UP LINKS +set_target_properties(${PNG_LIB_NAME} PROPERTIES +# VERSION 0.${PNGLIB_RELEASE}.1.2.18 + VERSION 0.${PNGLIB_RELEASE}.0 + SOVERSION 0 + CLEAN_DIRECT_OUTPUT 1) +set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES + OUTPUT_NAME ${PNG_LIB_NAME} + CLEAN_DIRECT_OUTPUT 1) + +# INSTALL +install_targets(/lib ${PNG_LIB_NAME} ${PNG_LIB_NAME_STATIC}) +install(FILES png.h pngconf.h DESTINATION include) +install(FILES png.h pngconf.h DESTINATION include/${PNGLIB_NAME}) +install(FILES libpng.3 libpngpf.3 DESTINATION man/man3) +install(FILES png.5 DESTINATION man/man5) +install(FILES ${PNG_BINARY_DIR}/libpng.pc DESTINATION lib/pkgconfig) +install(FILES ${PNG_BINARY_DIR}/libpng-config DESTINATION bin) +install(FILES ${PNG_BINARY_DIR}/${PNGLIB_NAME}.pc DESTINATION lib/pkgconfig) +install(FILES ${PNG_BINARY_DIR}/${PNGLIB_NAME}-config DESTINATION bin) + +# what's with libpng.txt and all the extra files? + + +# UNINSTALL +# do we need this? + + +# DIST +# do we need this? + +# to create msvc import lib for mingw compiled shared lib +# pexports libpng.dll > libpng.def +# lib /def:libpng.def /machine:x86 diff --git a/src/dep/src/irrlicht/libpng/scripts/SCOPTIONS.ppc b/src/dep/src/irrlicht/libpng/scripts/SCOPTIONS.ppc new file mode 100644 index 0000000..7090fd4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/SCOPTIONS.ppc @@ -0,0 +1,7 @@ +OPTIMIZE +OPTPEEP +OPTTIME +OPTSCHED +AUTOREGISTER +PARMS=REGISTERS +INCLUDEDIR=hlp:ppc/include diff --git a/src/dep/src/irrlicht/libpng/scripts/descrip.mms b/src/dep/src/irrlicht/libpng/scripts/descrip.mms new file mode 100644 index 0000000..3879ee6 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/descrip.mms @@ -0,0 +1,52 @@ + +cc_defs = /inc=$(ZLIBSRC) +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + + + +OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\ + pngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\ + pngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj + + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : pngtest.exe libpng.olb + @ write sys$output " pngtest available" + +libpng.olb : libpng.olb($(OBJS)) + @ write sys$output " Libpng available" + + +pngtest.exe : pngtest.obj libpng.olb + link pngtest,libpng.olb/lib,$(ZLIBSRC)libz.olb/lib + +test : pngtest.exe + run pngtest + +clean : + delete *.obj;*,*.exe;* + + +# Other dependencies. +png.obj : png.h, pngconf.h +pngpread.obj : png.h, pngconf.h +pngset.obj : png.h, pngconf.h +pngget.obj : png.h, pngconf.h +pngread.obj : png.h, pngconf.h +pngrtran.obj : png.h, pngconf.h +pngrutil.obj : png.h, pngconf.h +pngerror.obj : png.h, pngconf.h +pngmem.obj : png.h, pngconf.h +pngrio.obj : png.h, pngconf.h +pngwio.obj : png.h, pngconf.h +pngtest.obj : png.h, pngconf.h +pngtrans.obj : png.h, pngconf.h +pngwrite.obj : png.h, pngconf.h +pngwtran.obj : png.h, pngconf.h +pngwutil.obj : png.h, pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/libpng-config-body.in b/src/dep/src/irrlicht/libpng/scripts/libpng-config-body.in new file mode 100644 index 0000000..0db8898 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/libpng-config-body.in @@ -0,0 +1,96 @@ + +usage() +{ + cat < libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo libdir=\"$(LIBPATH)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-R$(LIBPATH)\"; \ + echo ccopts=\"-xtarget=ultra\"; \ + echo ldopts=\"-xtarget=ultra\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + @case "`type ld`" in *ucb*) \ + echo; \ + echo '## WARNING:'; \ + echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \ + echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \ + echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \ + echo '## The environment variable LD_LIBRARY_PATH should not be set'; \ + echo '## at all. If it is, things are likely to break because of'; \ + echo '## the libucb dependency that is created.'; \ + echo; \ + ;; \ + esac + $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBSOMAJ) \ + -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(OLDSOMAJ) \ + -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOMAJ).$(PNGVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) $(SUN_CC_FLAGS) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtestd -L$(DL) -R$(DL) `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) $(SUN_CC_FLAGS) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.64sunu b/src/dep/src/irrlicht/libpng/scripts/makefile.64sunu new file mode 100644 index 0000000..1bd0c50 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.64sunu @@ -0,0 +1,250 @@ +# makefile for libpng on Solaris 2.x with cc +# Contributed by William L. Sebok, based on makefile.linux +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1998 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME=libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +CC=cc +AR_RC=ar rc +MKDIR_P=mkdir -p +LN_SF=ln -f -s +RANLIB=echo +RM_F=/bin/rm -f + +SUN_CC_FLAGS=-fast -xtarget=ultra -xarch=v9 +SUN_LD_FLAGS=-fast -xtarget=ultra -xarch=v9 + +# where make install puts libpng.a, libpng12.so and libpng12/png.h +prefix=/a +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +# Changing these to ../zlib poses a security risk. If you want +# to have zlib in an adjacent directory, specify the full path instead of "..". +#ZLIBLIB=../zlib +#ZLIBINC=../zlib + +ZLIBLIB=/usr/lib +ZLIBINC=/usr/include + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion +CFLAGS=-I$(ZLIBINC) $(SUN_CC_FLAGS) \ + # $(WARNMORE) -g -DPNG_DEBUG=5 +LDFLAGS=-L. -R. $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo libdir=\"$(LIBPATH)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-R$(LIBPATH)\"; \ + echo ccopts=\"-xtarget=ultra -xarch=v9\"; \ + echo ldopts=\"-xtarget=ultra -xarch=v9\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + @case "`type ld`" in *ucb*) \ + echo; \ + echo '## WARNING:'; \ + echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \ + echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \ + echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \ + echo '## The environment variable LD_LIBRARY_PATH should not be set'; \ + echo '## at all. If it is, things are likely to break because of'; \ + echo '## the libucb dependency that is created.'; \ + echo; \ + ;; \ + esac + $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBSOMAJ) \ + -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(OLDSOMAJ) \ + -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOMAJ).$(PNGVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) $(SUN_CC_FLAGS) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtestd -L$(DL) -R$(DL) `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) $(SUN_CC_FLAGS) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.acorn b/src/dep/src/irrlicht/libpng/scripts/makefile.acorn new file mode 100644 index 0000000..2cc0f32 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.acorn @@ -0,0 +1,51 @@ +# Project: libpng + + +# Toolflags: +CCflags = -c -depend !Depend -IC:,Zlib: -g -throwback -DRISCOS -fnah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + + +# Final targets: +@.libpng-lib: @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \ + @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \ + @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil + LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \ + @.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \ + @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil +@.mm-libpng-lib: @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \ + @.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \ + @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil + LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \ + @.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \ + @.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \ + @.mm.pngwtran @.mm.pngwutil + + +# User-editable dependencies: +# (C) Copyright 1997 Tom Tanner +Test: @.pngtest + .pngtest + @remove .pngtest + +#It would be nice if you could stop "make" listing from here on! +@.pngtest: @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib + Link $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib + +.SUFFIXES: .o .mm .c + +.c.mm: + MemCheck.CC cc $(ccflags) -o $@ LibPng:$< +.c.o: + cc $(ccflags) -o $@ $< + + +# Static dependencies: + + +# Dynamic dependencies: diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.aix b/src/dep/src/irrlicht/libpng/scripts/makefile.aix new file mode 100644 index 0000000..a172f59 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.aix @@ -0,0 +1,113 @@ +# makefile for libpng using gcc (generic, static library) +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 2000 Cosmin Truta +# Copyright (C) 2000 Marc O. Gloor (AIX support added, from makefile.gcc) +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# Location of the zlib library and include files +ZLIBINC = ../zlib +ZLIBLIB = ../zlib + +# Compiler, linker, lib and other tools +CC = gcc +LD = $(CC) +AR_RC = ar rcs +MKDIR_P = mkdir -p +RANLIB = ranlib +RM_F = rm -f +LN_SF = ln -f -s + +LIBNAME=libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +prefix=/usr/local +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) + +CDEBUG = -g -DPNG_DEBUG=5 +LDDEBUG = +CRELEASE = -O2 +LDRELEASE = -s +WARNMORE=-Wall +CFLAGS = -I$(ZLIBINC) $(WARNMORE) $(CRELEASE) +LDFLAGS = -L. -L$(ZLIBLIB) -lpng12 -lz -lm $(LDRELEASE) + +# File extensions +O=.o +A=.a +E= + +# Variables +OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \ + pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \ + pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) + +# Targets +all: $(LIBNAME)$(A) pngtest$(E) + +$(LIBNAME)$(A): $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +test: pngtest$(E) + ./pngtest$(E) + +pngtest$(E): pngtest$(O) $(LIBNAME)$(A) + $(LD) -o $@ pngtest$(O) $(LDFLAGS) + +install: $(LIBNAME)$(A) + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DI)/$(LIBNAME)/png.h + -@$(RM_F) $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h + -@$(RM_F) $(DI)/pngconf.h + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h \ + $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) -r $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + -@$(RM_F) $(DL)/$(LIBNAME)$(A) + -@$(RM_F) $(DL)/libpng$(A) + cp $(LIBNAME)$(A) $(DL)/$(LIBNAME)$(A) + chmod 644 $(DL)/$(LIBNAME)$(A) + (cd $(DL); $(LN_SF) $(LIBNAME)$(A) libpng$(A)) + (cd $(DI); $(LN_SF) libpng/* .;) + +clean: + $(RM_F) *.o $(LIBNAME)$(A) pngtest pngout.png + +png$(O): png.h pngconf.h +pngerror$(O): png.h pngconf.h +pngget$(O): png.h pngconf.h +pngmem$(O): png.h pngconf.h +pngpread$(O): png.h pngconf.h +pngread$(O): png.h pngconf.h +pngrio$(O): png.h pngconf.h +pngrtran$(O): png.h pngconf.h +pngrutil$(O): png.h pngconf.h +pngset$(O): png.h pngconf.h +pngtest$(O): png.h pngconf.h +pngtrans$(O): png.h pngconf.h +pngwio$(O): png.h pngconf.h +pngwrite$(O): png.h pngconf.h +pngwtran$(O): png.h pngconf.h +pngwutil$(O): png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.amiga b/src/dep/src/irrlicht/libpng/scripts/makefile.amiga new file mode 100644 index 0000000..e05b395 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.amiga @@ -0,0 +1,48 @@ +# Commodore Amiga Makefile +# makefile for libpng and SAS C V6.5x compiler +# Copyright (C) 1995-2000 Wolf Faust +# For conditions of distribution and use, see copyright notice in png.h +# +# Note: Use #define PNG_READ_BIG_ENDIAN_SUPPORTED in pngconf.h +# +# Location/path of zlib include files +ZLIB=/zlib +#compiler +CC=sc +#compiler flags +# WARNING: a bug in V6.51 causes bad code with OPTGO +# So use V6.55 or set NOOPTGO!!!!!!!!! +CFLAGS= NOSTKCHK PARMS=REG OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL\ + OPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 INCLUDEDIR=$(ZLIB) \ + DEFINE=PNG_INTERNAL +#linker flags +LDFLAGS= SD ND BATCH +#link libs +LDLIBS= libpng.lib libgz.lib LIB:scm.lib LIB:sc.lib Lib:amiga.lib +# linker +LN= slink +# file deletion command +RM= delete quiet +# library (.lib) file creation command +AR= oml +# make directory command +MKDIR= makedir + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.lib pngtest + +libpng.lib: $(OBJS) +-$(RM) libpng.lib +$(AR) libpng.lib r $(OBJS) + +pngtest: pngtest.o libpng.lib +$(LN) libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo libs=\"-lpng12 -lz \"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + cp $(LIBSO)* /boot/home/config/lib + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -nostart -Wl,-soname,$(LIBSOMAJ) -o \ + $(LIBSOVER) $(OBJSDLL) $(LDFLAGS) + +$(OLDSOVER): $(OBJSDLL) + $(CC) -nostart -Wl,-soname,$(OLDSOMAJ) -o \ + $(OLDSOVER) $(OBJSDLL) $(LDFLAGS) + +pngtest: pngtest.o $(LIBSO) + $(CC) -L$(ZLIBLIB) -L. -lz -lpng12 -o pngtest pngtest.o + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) $(CFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl,-rpath $(ZLIBLIB):$(DL) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtesti \ + $(OLDSOVER) \ + libpng.pc + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.bor b/src/dep/src/irrlicht/libpng/scripts/makefile.bor new file mode 100644 index 0000000..49d6844 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.bor @@ -0,0 +1,162 @@ +# Makefile for libpng +# 16-bit Borland C++ (Note: All modules are compiled in C mode) +# To build the library, do: +# "make -fmakefile.bor -DMODEL=c" +# or: "make -fmakefile.bor -DMODEL=l" +# +# ------------ Borland C++ ------------ + +### Absolutely necessary for this makefile to work +.AUTODEPEND + +## Where zlib.h, zconf.h and zlib_MODEL.lib are +ZLIB_DIR=..\zlib + + +## Compiler, linker and lib stuff +CC=bcc +LD=bcc +LIB=tlib + +!ifndef MODEL +MODEL=l +!endif + +MODEL_ARG=-m$(MODEL) + +#TARGET_CPU=3 +# 2 = 286, 3 = 386, etc. +!ifndef TARGET_CPU +TARGET_CPU=2 +!endif + +# Use this if you don't want Borland's fancy exception handling +# (for Borland C++ 4.0 or later) +#NOEHLIB=noeh$(MODEL).lib + +!ifdef DEBUG +CDEBUG=-v +LDEBUG=-v +!else +CDEBUG= +LDEBUG= +!endif + +# STACKOFLOW=1 +!ifdef STACKOFLOW +CDEBUG=$(CDEBUG) -N +LDEBUG=$(LDEBUG) -N +!endif + +# -X- turn on dependency generation in the object file +# -w set all warnings on +# -O2 optimize for speed +# -Z global optimization +CFLAGS=-O2 -Z -X- -w -I$(ZLIB_DIR) -$(TARGET_CPU) $(MODEL_ARG) $(CDEBUG) + +# -M generate map file +LDFLAGS=-M -L$(ZLIB_DIR) $(MODEL_ARG) $(LDEBUG) + + +## Variables +OBJS = \ + png.obj \ + pngerror.obj \ + pngget.obj \ + pngmem.obj \ + pngpread.obj \ + pngread.obj \ + pngrio.obj \ + pngrtran.obj \ + pngrutil.obj \ + pngset.obj \ + pngtrans.obj \ + pngwio.obj \ + pngwrite.obj \ + pngwtran.obj \ + pngwutil.obj + +LIBOBJS = \ + +png.obj \ + +pngerror.obj \ + +pngget.obj \ + +pngmem.obj \ + +pngpread.obj \ + +pngread.obj \ + +pngrio.obj \ + +pngrtran.obj \ + +pngrutil.obj \ + +pngset.obj \ + +pngtrans.obj \ + +pngwio.obj \ + +pngwrite.obj \ + +pngwtran.obj \ + +pngwutil.obj + +LIBNAME=libpng$(MODEL).lib + + +## Implicit rules +# Braces let make "batch" calls to the compiler, +# 2 calls instead of 12; space is important. +.c.obj: + $(CC) $(CFLAGS) -c {$*.c } + +.c.exe: + $(CC) $(CFLAGS) $(LDFLAGS) $*.c $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB) + + +## Major targets +all: libpng pngtest + +libpng: $(LIBNAME) + +pngtest: pngtest$(MODEL).exe + +test: pngtest$(MODEL).exe + pngtest$(MODEL) + + +## Minor Targets + +png.obj: png.c +pngerror.obj: pngerror.c +pngget.obj: pngget.c +pngmem.obj: pngmem.c +pngpread.obj: pngpread.c +pngread.obj: pngread.c +pngrio.obj: pngrio.c +pngrtran.obj: pngrtran.c +pngrutil.obj: pngrutil.c +pngset.obj: pngset.c +pngtrans.obj: pngtrans.c +pngwio.obj: pngwio.c +pngwrite.obj: pngwrite.c +pngwtran.obj: pngwtran.c +pngwutil.obj: pngwutil.c + + +$(LIBNAME): $(OBJS) + -del $(LIBNAME) + $(LIB) $(LIBNAME) @&&| +$(LIBOBJS), libpng$(MODEL) +| + + +pngtest$(MODEL).obj: pngtest.c + $(CC) $(CFLAGS) -opngtest$(MODEL) -c pngtest.c + +pngtest$(MODEL).exe: pngtest$(MODEL).obj + $(LD) $(LDFLAGS) pngtest$(MODEL).obj $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB) + + +# Clean up anything else you want +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.lst + -del *.map + + +# End of makefile for libpng diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.cygwin b/src/dep/src/irrlicht/libpng/scripts/makefile.cygwin new file mode 100644 index 0000000..ce2c7c2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.cygwin @@ -0,0 +1,316 @@ +# makefile for cygwin on x86 +# Builds both dll (with import lib) and static lib versions +# of the library, and builds two copies of pngtest: one +# statically linked and one dynamically linked. +# +# Copyright (C) 2002, 2006 Soren Anderson, Charles Wilson, +# and Glenn Randers-Pehrson, based on makefile for linux-elf w/mmx by: +# Copyright (C) 1998-2000 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# This makefile intends to support building outside the src directory +# if desired. When invoking it, specify an argument to SRCDIR on the +# command line that points to the top of the directory where your source +# is located. + +ifdef SRCDIR +VPATH = $(SRCDIR) +else +SRCDIR = . +endif + +# Override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. + +DESTDIR= + +# To enable assembler optimizations, add '-DPNG_USE_PNGGCCRD' to +# $CFLAGS, and include pnggccrd.o in $OBJS, below, and in the dependency +# list at the bottom of this makefile. + +CC=gcc +ifdef MINGW +MINGW_CCFLAGS=-mno-cygwin -I/usr/include/mingw +MINGW_LDFLAGS=-mno-cygwin -L/usr/lib/mingw +endif + +# Where "make install" puts libpng*.a, *png*.dll, png.h, and pngconf.h +ifndef prefix +prefix=/usr +$(warning You haven't specified a 'prefix=' location. Defaulting to "/usr") +endif +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +ZLIBLIB= /usr/lib +ZLIBINC= +#ZLIBLIB=../zlib +#ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +### if you use the asm, add pnggccrd.o to the OBJS list +### +### if you don't need thread safety, but want the asm accel +#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD \ +# $(addprefix -I,$(ZLIBINC)) -Wall -O3 $(ALIGN) -funroll-loops \ +# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 +### if you need thread safety and want (minimal) asm accel +#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_USE_PNGGCCRD $(addprefix -I,$(ZLIBINC)) \ +# -Wall -O3 $(ALIGN) -funroll-loops \ +# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 +### Normal (non-asm) compilation +CFLAGS= $(strip $(MINGW_CCFLAGS) $(addprefix -I,$(ZLIBINC)) \ + -Wall -O3 $(ALIGN) -funroll-loops \ + -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 + +LIBNAME = libpng12 +PNGMAJ = 0 +CYGDLL = 12 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +SHAREDLIB=cygpng$(CYGDLL).dll +STATLIB=libpng.a +IMPLIB=libpng.dll.a +SHAREDDEF=libpng.def +LIBS=$(SHAREDLIB) $(STATLIB) +EXE=.exe + +LDFLAGS=$(strip -L. $(MINGW_LDFLAGS) -lpng $(addprefix -L,$(ZLIBLIB)) -lz) +LDSFLAGS=$(strip -shared -L. $(MINGW_LDFLAGS) -Wl,--export-all) +LDEXTRA=-Wl,--out-implib=$(IMPLIB) $(addprefix -L,$(ZLIBLIB)) -lz + +MKDIR_P=/bin/mkdir -pv +RANLIB=ranlib +#RANLIB=echo + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib + +BINPATH=$(exec_prefix)/bin +MANPATH=$(prefix)/man +MAN3PATH=$(MANPATH)/man3 +MAN5PATH=$(MANPATH)/man5 + +# cosmetic: shortened strings: +S =$(SRCDIR) +D =$(DESTDIR) +DB =$(D)$(BINPATH) +DI =$(D)$(INCPATH) +DL =$(D)$(LIBPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o # pnggccrd.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +%.o : %.c + $(CC) -c $(CFLAGS) -o $@ $< +%.pic.o : CFLAGS += -DPNG_BUILD_DLL +%.pic.o : %.c + $(CC) -c $(CFLAGS) -o $@ $< + +all: all-static all-shared libpng.pc libpng-config libpng.pc libpng-config + +# Make this to verify that "make [...] install" will do what you want. +buildsetup-tell: + @echo VPATH is set to: \"$(VPATH)\" + @echo prefix is set to: \"$(prefix)\" + @echo -e INCPATH,LIBPATH, etc. are set to:'\n' \ + $(addprefix $(D),$(INCPATH)'\n' $(LIBPATH)'\n' $(BINPATH)'\n' \ + $(MANPATH)'\n' $(MAN3PATH)'\n' $(MAN5PATH)'\n')'\n' + +libpng.pc: scripts/libpng.pc.in + @echo -e Making pkg-config file for this libpng installation..'\n' \ + using PREFIX=\"$(prefix)\"'\n' + cat $(S)/scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \ + sed -e s/-lm// > libpng.pc + +libpng-config: scripts/libpng-config-head.in scripts/libpng-config-body.in + @echo -e Making $(LIBNAME) libpng-config file for this libpng \ + installation..'\n' using PREFIX=\"$(prefix)\"'\n' + ( cat $(S)/scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng$(CYGDLL) -lz\"; \ + cat $(S)/scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +static: all-static +shared: all-shared +all-static: $(STATLIB) pngtest-stat$(EXE) +all-shared: $(SHAREDLIB) pngtest$(EXE) + +pnggccrd.o: pnggccrd.c png.h pngconf.h + @echo "" + @echo ' You can ignore the "control reaches end of non-void function"' + @echo ' warning and " defined but not used" warnings:' + @echo "" + $(CC) -c $(CFLAGS) -o $@ $< + +pnggccrd.pic.o: pnggccrd.c png.h pngconf.h + @echo "" + @echo ' You can ignore the "control reaches end of non-void function"' + @echo ' warning and " defined but not used" warnings:' + @echo "" + $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $< + +$(STATLIB): $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +$(SHAREDDEF): scripts/pngw32.def + cat $< | sed -e '1{G;s/^\(.*\)\(\n\)/EXPORTS/;};2,/^EXPORTS/d' | \ + sed -e 's/\([^;]*\);/;/' > $@ + +$(SHAREDLIB): $(OBJSDLL) $(SHAREDDEF) + $(CC) $(LDSFLAGS) -o $@ $(OBJSDLL) -L. $(LDEXTRA) + +pngtest$(EXE): pngtest.pic.o $(SHAREDLIB) + $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@ + +pngtest-stat$(EXE): pngtest.o $(STATLIB) + $(CC) -static $(CFLAGS) $< $(LDFLAGS) -o $@ + +pngtest.pic.o: pngtest.c + $(CC) $(CFLAGS) -c $< -o $@ + +pngtest.o: pngtest.c + $(CC) $(CFLAGS) -c $< -o $@ + +test: test-static test-shared + +test-static: pngtest-stat$(EXE) + ./pngtest-stat $(S)/pngtest.png + +test-shared: pngtest$(EXE) + ./pngtest $(S)/pngtest.png + +install-static: $(STATLIB) install-headers install-man + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + install -m 644 $(STATLIB) $(DL)/$(LIBNAME).a + -@rm -f $(DL)/$(STATLIB) + (cd $(DL); ln -sf $(LIBNAME).a $(STATLIB)) + +install-shared: $(SHAREDLIB) libpng.pc libpng-config install-headers install-man + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc + -@/bin/rm -f $(DL)/pkgconfig/libpng.pc + install -m 644 $(IMPLIB) $(DL)/$(LIBNAME).dll.a + -@rm -f $(DL)/$(IMPLIB) + (cd $(DL); ln -sf $(LIBNAME).dll.a $(IMPLIB)) + install -s -m 755 $(SHAREDLIB) $(DB) + install -m 644 libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc) + +install-headers: + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + -@rm -f $(DI)/png.h + -@rm -f $(DI)/pngconf.h + install -m 644 $(S)/png.h $(S)/pngconf.h $(DI)/$(LIBNAME) + -@rm -f $(DI)/libpng + (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .) + +install-man: + -@if [ ! -d $(D)$(MAN3PATH) ]; then $(MKDIR_P) $(D)$(MAN3PATH); fi + -@if [ ! -d $(D)$(MAN5PATH) ]; then $(MKDIR_P) $(D)$(MAN5PATH); fi + install -m 644 $(S)/libpngpf.3 $(S)/libpng.3 $(D)$(MAN3PATH) + install -m 644 $(S)/png.5 $(D)$(MAN5PATH) + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@/bin/rm -f $(DB)/libpng-config + -@/bin/rm -f $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); ln -sf $(LIBNAME)-config libpng-config) + +# Run this to verify that a future `configure' run will pick up the settings +# you want. +test-config-install: SHELL=/bin/bash +test-config-install: $(DB)/libpng-config + @echo -e Testing libpng-config functions...'\n' + @ for TYRA in LDFLAGS CPPFLAGS CFLAGS LIBS VERSION; \ + do \ + printf "(%d)\t %10s =%s\n" $$(($$gytiu + 1)) $$TYRA \ + "$$($(DB)/libpng-config `echo --$$TYRA |tr '[:upper:]' '[:lower:]'`)"; \ + gytiu=$$(( $$gytiu + 1 )); \ + done + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) $(CFLAGS) \ + `$(BINPATH)/libpng12-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/libpng12-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CFLAGS) \ + `$(BINPATH)/libpng12-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti$(EXE) `$(BINPATH)/libpng12-config --ldflags` + ./pngtesti$(EXE) pngtest.png + +clean: + /bin/rm -f *.pic.o *.o $(STATLIB) $(IMPLIB) $(SHAREDLIB) \ + pngtest-stat$(EXE) pngtest$(EXE) pngout.png $(SHAREDDEF) \ + libpng-config libpng.pc pngtesti$(EXE) + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +.PHONY: buildsetup-tell libpng.pc libpng-config test-config-install clean + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h png.c +pngerror.o pngerror.pic.o: png.h pngconf.h pngerror.c +pngrio.o pngrio.pic.o: png.h pngconf.h pngrio.c +pngwio.o pngwio.pic.o: png.h pngconf.h pngwio.c +pngmem.o pngmem.pic.o: png.h pngconf.h pngmem.c +pngset.o pngset.pic.o: png.h pngconf.h pngset.c +pngget.o pngget.pic.o: png.h pngconf.h pngget.c +pngread.o pngread.pic.o: png.h pngconf.h pngread.c +pngrtran.o pngrtran.pic.o: png.h pngconf.h pngrtran.c +pngrutil.o pngrutil.pic.o: png.h pngconf.h pngrutil.c +pngtrans.o pngtrans.pic.o: png.h pngconf.h pngtrans.c +pngwrite.o pngwrite.pic.o: png.h pngconf.h pngwrite.c +pngwtran.o pngwtran.pic.o: png.h pngconf.h pngwtran.c +pngwutil.o pngwutil.pic.o: png.h pngconf.h pngwutil.c +pngpread.o pngpread.pic.o: png.h pngconf.h pngpread.c + +pngtest.o: png.h pngconf.h pngtest.c +pngtest-stat.o: png.h pngconf.h pngtest.c + + + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.darwin b/src/dep/src/irrlicht/libpng/scripts/makefile.darwin new file mode 100644 index 0000000..a5df6c4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.darwin @@ -0,0 +1,230 @@ +# makefile for libpng on Darwin / Mac OS X +# Copyright (C) 2002, 2004, 2006 Glenn Randers-Pehrson +# Copyright (C) 2001 Christoph Pfisterer +# derived from makefile.linux: +# Copyright (C) 1998, 1999 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# where "make install" puts libpng.a, libpng12.dylib, png.h and pngconf.h +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).dylib +LIBSOMAJ=$(LIBNAME).$(PNGMAJ).dylib +LIBSOVER=$(LIBNAME).$(PNGVER).dylib +OLDSO=libpng.dylib +OLDSOMAJ=libpng.3.dylib +OLDSOVER=libpng.3.$(PNGMIN).dylib + +# Utilities: +CC=cc +AR_RC=ar rc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops +LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fno-common -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \ + sed -e s/-lm// > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -dynamiclib \ + -install_name $(LIBPATH)/$(LIBSOMAJ) \ + -current_version $(PNGVER) -compatibility_version $(PNGVER) \ + -o $(LIBSOVER) \ + $(OBJSDLL) -L$(ZLIBLIB) -lz + +$(OLDSOVER): $(OBJSDLL) + $(CC) -dynamiclib \ + -install_name $(LIBPATH)/$(OLDSOMAJ) \ + -current_version 3 -compatibility_version 3 \ + -o $(OLDSOVER) \ + $(OBJSDLL) -L$(ZLIBLIB) -lz + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + $(RANLIB) $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSO) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBNAME).$(PNGVER)*.dylib + -@$(RM_F) $(DL)/$(LIBNAME).$(PNGMAJ)*.dylib + -@$(RM_F) $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/libpng.3.$(PNGMIN)*.dylib + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(OLDSOVER) \ + libpng.pc $(LIBNAME).*dylib pngtesti + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.dec b/src/dep/src/irrlicht/libpng/scripts/makefile.dec new file mode 100644 index 0000000..26e4157 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.dec @@ -0,0 +1,210 @@ +# makefile for libpng on DEC Alpha Unix +# Copyright (C) 2000-2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) +LIBNAME = libpng12 + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=cc +MKDIR_P=mkdir +LN_SF=ln -f -s +RANLIB=ranlib +RM_F=/bin/rm -f + +# where make install puts libpng.a and png.h +prefix=/usr/local +exec_prefix=$(prefix) +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +CFLAGS=-std -w1 -I$(ZLIBINC) -O # -g -DPNG_DEBUG=1 +LDFLAGS=-L$(ZLIBLIB) -rpath $(ZLIBLIB) libpng.a -lz -lm + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: $(LIBSO) libpng.a pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo ccopts=\"-std\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJS) + $(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB) \ + -soname $(LIBSOMAJ) + +$(OLDSOVER): $(OBJS) + $(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB) \ + -soname $(OLDSOMAJ) + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h + -@/bin/rm -f $(DI)/libpng + (cd $(DI); $(LN_SF)(LIBNAME) libpng; $(LN_SF)(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@/bin/rm -f $(DL)/libpng.a + (cd $(DL); $(LN_SF)(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@/bin/rm -f $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@/bin/rm -f $(DL)/$(LIBSOMAJ) + -@/bin/rm -f $(DL)/$(OLDSO) + -@/bin/rm -f $(DL)/$(OLDSOMAJ) + -@/bin/rm -f $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF)(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF)(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc + -@/bin/rm -f $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF)(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@/bin/rm -f $(DM)/man3/libpng.3 + -@/bin/rm -f $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@/bin/rm -f $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@/bin/rm -f $(DB)/libpng-config + -@/bin/rm -f $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF)(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -w1 -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -w1 -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -R$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.dj2 b/src/dep/src/irrlicht/libpng/scripts/makefile.dj2 new file mode 100644 index 0000000..146d409 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.dj2 @@ -0,0 +1,55 @@ +# DJGPP (DOS gcc) makefile for libpng +# Copyright (C) 2002 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# where make install will put libpng.a and png.h +#prefix=/usr/local +prefix=. +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +CC=gcc +CFLAGS=-I../zlib -O +LDFLAGS=-L. -L../zlib/ -lpng -lz -lm + +RANLIB=ranlib + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o pngwtran.o \ + pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest + +libpng.a: $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + coff2exe pngtest + +test: pngtest + ./pngtest +clean: + rm -f *.o libpng.a pngtest pngout.png + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngpread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.elf b/src/dep/src/irrlicht/libpng/scripts/makefile.elf new file mode 100644 index 0000000..b728a4e --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.elf @@ -0,0 +1,271 @@ +# makefile for libpng.a and libpng12.so on Linux ELF with gcc +# Copyright (C) 1998, 1999, 2002, 2006 Greg Roelofs and Glenn Randers-Pehrson +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Modified for Debian by Junichi Uekawa and Josselin Mouette +# Major modifications are: +# * link libpng explicitly with libz and libm +# * $(OLDSO).3 is a symlink rather than a different library +# * versioned symbols + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +# where "make install" puts libpng12.a, libpng12.so*, +# libpng12/png.h and libpng12/pngconf.h +# Prefix must be a full pathname. +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located. +ZLIBLIB=/usr/local/lib +ZLIBINC=/usr/local/include +# ZLIBLIB=../zlib +# ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +CFLAGS=-Wall -D_REENTRANT -O2 \ + $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5 + +LDFLAGS=-L. -lpng12 +LDFLAGS_A=libpng.a -lz -lm +LIBADDFLAGS=-lz -lm + + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng.syms: png.h pngconf.h + $(CC) $(CFLAGS) -E -DPNG_BUILDSYMS -DPNG_INTERNAL png.h |\ + awk -F '[\t [\\]();]' -v PNGMAJ=$(PNGMAJ) 'BEGIN{printf("PNG12_%s {global:\n",PNGMAJ)}\ + { for (i=1;i+2<=NF;++i)\ + if ($$(i)=="PNG_FUNCTION_EXPORT" && $$(i+2)=="END")\ + print $$(i+1) ";";\ + for (i=1;i+1<=NF;++i)\ + if ($$(i)=="PNG_DATA_EXPORT")\ + print $$(i+1) ";";}\ + END{print "local: *; };"}' >$@.new + $(RM_F) $@ + mv $@.new $@ + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"\"; \ + echo R_opts=\"\"; \ + echo libs=\"-lpng12\"; \ + echo all_libs=\"-lpng12 $(LIBADDFLAGS)\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) libpng.syms + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) \ + -Wl,-version-script,libpng.syms \ + -o $(LIBSOVER) \ + $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) libpng.syms + $(CC) -shared -Wl,-soname,$(OLDSOMAJ) \ + -Wl,-version-script,libpng.syms \ + -o $(OLDSOVER) \ + $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +pngtest-static: pngtest.o libpng.a + $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A) + +test: pngtest pngtest-static + @echo "" + @echo " Running pngtest dynamically linked with $(LIBSO):" + @echo "" + LD_LIBRARY_PATH=".:${LD_LIBRARY_PATH}" ./pngtest + @echo "" + @echo " Running pngtest statically linked with libpng.a:" + @echo "" + ./pngtest-static + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a libpng.syms pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.freebsd b/src/dep/src/irrlicht/libpng/scripts/makefile.freebsd new file mode 100644 index 0000000..8767ce3 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.freebsd @@ -0,0 +1,48 @@ +# makefile for libpng under FreeBSD +# Copyright (C) 2002, 2007 Glenn Randers-Pehrson and Andrey A. Chernov +# For conditions of distribution and use, see copyright notice in png.h + +PREFIX?= /usr/local +SHLIB_VER?= 5 + +LIB= png +SHLIB_MAJOR= ${SHLIB_VER} +SHLIB_MINOR= 0 +NOPROFILE= YES +NOOBJ= YES + +# where make install puts libpng.a and png.h +DESTDIR= ${PREFIX} +LIBDIR= /lib +INCS= png.h pngconf.h +INCSDIR= /include/libpng +INCDIR= ${INCSDIR} # for 4.x bsd.lib.mk +MAN= libpng.3 libpngpf.3 png.5 +MANDIR= /man/man +SYMLINKS= libpng/png.h ${INCSDIR}/../png.h \ + libpng/pngconf.h ${INCSDIR}/../pngconf.h +LDADD+= -lm -lz +DPADD+= ${LIBM} ${LIBZ} + +CFLAGS+= -I. -DPNG_USE_PNGGCCRD +.if (${MACHINE_ARCH} != "i386") +CFLAGS+= -DPNG_NO_MMX_CODE +.endif + +SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \ + pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ + pngwtran.c pngmem.c pngerror.c pngpread.c pnggccrd.c + +pngtest: pngtest.o libpng.a + ${CC} ${CFLAGS} -L. -static -o pngtest pngtest.o -lpng -lz -lm + +CLEANFILES= pngtest pngtest.o pngout.png + +test: pngtest + ./pngtest + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +.include diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.gcc b/src/dep/src/irrlicht/libpng/scripts/makefile.gcc new file mode 100644 index 0000000..0ca7a86 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.gcc @@ -0,0 +1,79 @@ +# makefile for libpng using gcc (generic, static library) +# Copyright (C) 2000 Cosmin Truta +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# Location of the zlib library and include files +ZLIBINC = ../zlib +ZLIBLIB = ../zlib + +# Compiler, linker, lib and other tools +CC = gcc +LD = $(CC) +AR_RC = ar rcs +RANLIB = ranlib +RM_F = rm -f + +CDEBUG = -g -DPNG_DEBUG=5 +LDDEBUG = +CRELEASE = -O2 +LDRELEASE = -s +#CFLAGS = -Wall $(CDEBUG) +CFLAGS = -Wall $(CRELEASE) +#LDFLAGS = $(LDDEBUG) +LDFLAGS = $(LDRELEASE) +LIBS = -lz -lm + +# File extensions +O=.o +A=.a +EXE= + +# Variables +OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \ + pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \ + pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) + +# Targets +all: static + +.c$(O): + $(CC) -c $(CFLAGS) -I$(ZLIBINC) $< + +static: libpng$(A) pngtest$(EXE) + +shared: + @echo This is a generic makefile that cannot create shared libraries. + @echo Please use a configuration that is specific to your platform. + @false + +libpng$(A): $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +test: pngtest$(EXE) + ./pngtest$(EXE) + +pngtest$(EXE): pngtest$(O) libpng$(A) + $(LD) $(LDFLAGS) -L$(ZLIBLIB) -o $@ pngtest$(O) libpng$(A) $(LIBS) + +clean: + $(RM_F) *$(O) libpng$(A) pngtest$(EXE) pngout.png + +png$(O): png.h pngconf.h +pngerror$(O): png.h pngconf.h +pngget$(O): png.h pngconf.h +pngmem$(O): png.h pngconf.h +pngpread$(O): png.h pngconf.h +pngread$(O): png.h pngconf.h +pngrio$(O): png.h pngconf.h +pngrtran$(O): png.h pngconf.h +pngrutil$(O): png.h pngconf.h +pngset$(O): png.h pngconf.h +pngtest$(O): png.h pngconf.h +pngtrans$(O): png.h pngconf.h +pngwio$(O): png.h pngconf.h +pngwrite$(O): png.h pngconf.h +pngwtran$(O): png.h pngconf.h +pngwutil$(O): png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.gcmmx b/src/dep/src/irrlicht/libpng/scripts/makefile.gcmmx new file mode 100644 index 0000000..1afed82 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.gcmmx @@ -0,0 +1,275 @@ +# makefile for libpng.a and libpng12.so on Linux ELF with gcc using MMX +# assembler code +# Copyright 2002, 2006 Greg Roelofs and Glenn Randers-Pehrson +# Copyright 1998-2001 Greg Roelofs +# Copyright 1996-1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# CAUTION: Do not use this makefile with gcc versions 2.7.2.2 and earlier. + +# WARNING: The assembler code in pnggccrd.c may not be thread safe. + +# NOTE: When testing MMX performance on a multitasking system, make sure +# there are no floating-point programs (e.g., SETI@Home) running in +# the background! Context switches between MMX and FPU are expensive. + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +CC = gcc +LD = $(CC) +AR_RC = ar rc +LN_SF = ln -sf +MKDIR_P = mkdir -p +RANLIB = ranlib +RM_F = /bin/rm -f + +# where "make install" puts libpng12.a, libpng12.so*, +# libpng12/png.h and libpng12/pngconf.h +# Prefix must be a full pathname. +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located. +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +# Remove -DPNG_THREAD_UNSAFE_OK if you need thread safety +### for generic gcc: +CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall \ + -O3 $(ALIGN) -funroll-loops \ + -fomit-frame-pointer # $(WARNMORE) -g -DPNG_DEBUG=5 +### for gcc 2.95.2 on 686: +#CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall -O3 \ +# -mcpu=i686 -malign-double -ffast-math -fstrict-aliasing \ +# $(ALIGN) -funroll-loops -funroll-all-loops -fomit-frame-pointer +### for gcc 2.7.2.3 on 486 and up: +#CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall -O3 \ +# -m486 -malign-double -ffast-math \ +# $(ALIGN) -funroll-loops -funroll-all-loops -fomit-frame-pointer + +LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm +LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm + + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o pnggccrd.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo cppflags=\"-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +pnggccrd.o: pnggccrd.c png.h pngconf.h + $(CC) -c $(CFLAGS) -o $@ $*.c + +pnggccrd.pic.o: pnggccrd.c png.h pngconf.h + $(CC) -c $(CFLAGS) -fPIC -o $@ pnggccrd.c + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) \ + -o $(LIBSOVER) \ + $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(OLDSOMAJ) \ + -o $(OLDSOVER) \ + $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +pngtest-static: pngtest.o libpng.a + $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A) + +test: pngtest pngtest-static + @echo "" + @echo " Running pngtest dynamically linked with $(LIBSO):" + @echo "" + ./pngtest + @echo "" + @echo " Running pngtest statically linked with libpng.a:" + @echo "" + ./pngtest-static + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +png.o png.pic.o: png.h pngconf.h png.c +pngerror.o pngerror.pic.o: png.h pngconf.h pngerror.c +pngrio.o pngrio.pic.o: png.h pngconf.h pngrio.c +pngwio.o pngwio.pic.o: png.h pngconf.h pngwio.c +pngmem.o pngmem.pic.o: png.h pngconf.h pngmem.c +pngset.o pngset.pic.o: png.h pngconf.h pngset.c +pngget.o pngget.pic.o: png.h pngconf.h pngget.c +pngread.o pngread.pic.o: png.h pngconf.h pngread.c +pngrtran.o pngrtran.pic.o: png.h pngconf.h pngrtran.c +pngrutil.o pngrutil.pic.o: png.h pngconf.h pngrutil.c +pngtrans.o pngtrans.pic.o: png.h pngconf.h pngtrans.c +pngwrite.o pngwrite.pic.o: png.h pngconf.h pngwrite.c +pngwtran.o pngwtran.pic.o: png.h pngconf.h pngwtran.c +pngwutil.o pngwutil.pic.o: png.h pngconf.h pngwutil.c +pngpread.o pngpread.pic.o: png.h pngconf.h pngpread.c + +pngtest.o: png.h pngconf.h pngtest.c diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.hp64 b/src/dep/src/irrlicht/libpng/scripts/makefile.hp64 new file mode 100644 index 0000000..091367f --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.hp64 @@ -0,0 +1,231 @@ +# makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product. +# Copyright (C) 1999-2002 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42 +# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard +# For conditions of distribution and use, see copyright notice in png.h + +# Where the zlib library and include files are located +ZLIBLIB=/opt/zlib/lib +ZLIBINC=/opt/zlib/include + +# Note that if you plan to build a libpng shared library, zlib must also +# be a shared library, which zlib's configure does not do. After running +# zlib's configure, edit the appropriate lines of makefile to read: +# CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \ +# LDSHARED=ld -b +# SHAREDLIB=libz.sl + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).sl +LIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ) +LIBSOVER=$(LIBNAME).sl.$(PNGVER) +OLDSO=libpng.sl +OLDSOMAJ=libpng.sl.3 +OLDSOVER=libpng.sl.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=cc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +CFLAGS=-I$(ZLIBINC) -O -Ae -Wl,+vnocompatwarnings +DD64 \ +-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +Z -DHAVE_UNISTD_H -DUSE_MMAP +# Caution: be sure you have built zlib with the same CFLAGS. +CCFLAGS=-I$(ZLIBINC) -O -Ae -Wl,+vnocompatwarnings +DD64 \ +-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +Z -DHAVE_UNISTD_H -DUSE_MMAP + +LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm + +# where make install puts libpng.a, libpng12.sl, and png.h +prefix=/opt/libpng +exec_prefix=$(prefix) +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) +z -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo ccopts=\"-Ae +DA1.1 +DS2.0\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(LIBSOMAJ) -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(OLDSOMAJ) -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) $(CCFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) $(CCFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.hpgcc b/src/dep/src/irrlicht/libpng/scripts/makefile.hpgcc new file mode 100644 index 0000000..041f5a8 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.hpgcc @@ -0,0 +1,241 @@ +# makefile for libpng on HP-UX using GCC with the HP ANSI/C linker. +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 2001, Laurent faillie +# Copyright (C) 1998, 1999 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).sl +LIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ) +LIBSOVER=$(LIBNAME).sl.$(PNGVER) +OLDSO=libpng.sl +OLDSOMAJ=libpng.sl.3 +OLDSOVER=libpng.sl.3.$(PNGMIN) + +# Utilities: +CC=gcc +LD=ld +AR_RC=ar rc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +# where "make install" puts libpng.a, $(OLDSO)*, png.h and pngconf.h +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +ZLIBLIB=/opt/zlib/lib +ZLIBINC=/opt/zlib/include + +# Note that if you plan to build a libpng shared library, zlib must also +# be a shared library, which zlib's configure does not do. After running +# zlib's configure, edit the appropriate lines of makefile to read: +# CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \ +# LDSHARED=ld -b +# SHAREDLIB=libz.sl + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \ + $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5 +#LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm +LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(LIBSOMAJ) -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(OLDSOMAJ) -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl,-rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.hpux b/src/dep/src/irrlicht/libpng/scripts/makefile.hpux new file mode 100644 index 0000000..975e80b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.hpux @@ -0,0 +1,228 @@ +# makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product. +# Copyright (C) 1999-2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42 +# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard +# For conditions of distribution and use, see copyright notice in png.h + +# Where the zlib library and include files are located +ZLIBLIB=/opt/zlib/lib +ZLIBINC=/opt/zlib/include + +# Note that if you plan to build a libpng shared library, zlib must also +# be a shared library, which zlib's configure does not do. After running +# zlib's configure, edit the appropriate lines of makefile to read: +# CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \ +# LDSHARED=ld -b +# SHAREDLIB=libz.sl + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).sl +LIBSOMAJ=$(LIBNAME).sl.$(PNGMAJ) +LIBSOVER=$(LIBNAME).sl.$(PNGVER) +OLDSO=libpng.sl +OLDSOMAJ=libpng.sl.3 +OLDSOVER=libpng.sl.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=cc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +# where make install puts libpng.a, libpng12.sl, and png.h +prefix=/opt/libpng +exec_prefix=$(prefix) +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +CFLAGS=-I$(ZLIBINC) -O -Ae +DA1.1 +DS2.0 +# Caution: be sure you have built zlib with the same CFLAGS. +CCFLAGS=-I$(ZLIBINC) -O -Ae +DA1.1 +DS2.0 +LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) +z -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo ccopts=\"-Ae +DA1.1 +DS2.0\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(LIBSOMAJ) -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(LD) -b +s \ + +h $(OLDSOMAJ) -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) $(CCFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) $(CCFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.ibmc b/src/dep/src/irrlicht/libpng/scripts/makefile.ibmc new file mode 100644 index 0000000..80929d2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.ibmc @@ -0,0 +1,71 @@ +# Makefile for libpng (static) +# IBM C version 3.x for Win32 and OS/2 +# Copyright (C) 2000 Cosmin Truta +# For conditions of distribution and use, see copyright notice in png.h +# Notes: +# Derived from makefile.std +# All modules are compiled in C mode +# Tested under Win32, expected to work under OS/2 +# Can be easily adapted for IBM VisualAge/C++ for AIX + +# Location of the zlib library and include files +ZLIBINC = ../zlib +ZLIBLIB = ../zlib + +# Compiler, linker, lib and other tools +CC = icc +LD = ilink +AR = ilib +RM = del + +CFLAGS = -I$(ZLIBINC) -Mc -O2 -W3 +LDFLAGS = + +# File extensions +O=.obj +A=.lib +E=.exe + +# Variables +OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \ + pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \ + pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) + +LIBS = libpng$(A) $(ZLIBLIB)/zlib$(A) + +# Targets +all: libpng$(A) pngtest$(E) + +libpng$(A): $(OBJS) + $(AR) -out:$@ $(OBJS) + +test: pngtest$(E) + pngtest$(E) + +pngtest: pngtest$(E) + +pngtest$(E): pngtest$(O) libpng$(A) + $(LD) $(LDFLAGS) pngtest$(O) $(LIBS) + +clean: + $(RM) *$(O) + $(RM) libpng$(A) + $(RM) pngtest$(E) + $(RM) pngout.png + +png$(O): png.h pngconf.h +pngerror$(O): png.h pngconf.h +pngget$(O): png.h pngconf.h +pngmem$(O): png.h pngconf.h +pngpread$(O): png.h pngconf.h +pngread$(O): png.h pngconf.h +pngrio$(O): png.h pngconf.h +pngrtran$(O): png.h pngconf.h +pngrutil$(O): png.h pngconf.h +pngset$(O): png.h pngconf.h +pngtest$(O): png.h pngconf.h +pngtrans$(O): png.h pngconf.h +pngwio$(O): png.h pngconf.h +pngwrite$(O): png.h pngconf.h +pngwtran$(O): png.h pngconf.h +pngwutil$(O): png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.intel b/src/dep/src/irrlicht/libpng/scripts/makefile.intel new file mode 100644 index 0000000..400ca07 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.intel @@ -0,0 +1,114 @@ +# Makefile for libpng +# Microsoft Visual C++ with Intel C/C++ Compiler 4.0 and later + +# Copyright (C) 2000, Pawel Mrochen, based on makefile.msc which is +# copyright 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# To use, do "nmake /f scripts\makefile.intel" + + +# ------------------- Intel C/C++ Compiler 4.0 and later ------------------- + +# Caution: the assembler code was introduced at libpng version 1.0.4 and has +# not yet been thoroughly tested. + +# Use assembler code +ASMCODE=-DPNG_USE_PNGVCRD + +# Where the zlib library and include files are located +ZLIBLIB=..\zlib +ZLIBINC=..\zlib + +# Target CPU +CPU=6 # Pentium II +#CPU=5 # Pentium + +# Calling convention +CALLING=r # __fastcall +#CALLING=z # __stdcall +#CALLING=d # __cdecl + +# Uncomment next to put error messages in a file +#ERRFILE=>>pngerrs + +# -------------------------------------------------------------------------- + + +CC=icl -c +CFLAGS=-O2 -G$(CPU)$(CALLING) -Qip -Qunroll4 -I$(ZLIBINC) $(ASMCODE) -nologo +LD=link +LDFLAGS=/SUBSYSTEM:CONSOLE /NOLOGO + +O=.obj + +OBJS=png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) \ +pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) \ +pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) pngvcrd$(O) + + +all: test + +png$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngset$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngget$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngread$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngpread$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrtran$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrutil$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngvcrd$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngerror$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngmem$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrio$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwio$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngtest$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngtrans$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwrite$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwtran$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwutil$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +libpng.lib: $(OBJS) + if exist libpng.lib del libpng.lib + lib /NOLOGO /OUT:libpng.lib $(OBJS) + +pngtest.exe: pngtest.obj libpng.lib + $(LD) $(LDFLAGS) /OUT:pngtest.exe pngtest.obj libpng.lib $(ZLIBLIB)\zlib.lib + +test: pngtest.exe + pngtest.exe + + +# End of makefile for libpng diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.knr b/src/dep/src/irrlicht/libpng/scripts/makefile.knr new file mode 100644 index 0000000..4a8d7d1 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.knr @@ -0,0 +1,99 @@ +# makefile for libpng +# Copyright (C) 2002 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# This makefile requires the file ansi2knr.c, which you can get +# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/ +# If you have libjpeg, you probably already have ansi2knr.c in the jpeg +# source distribution. + +# where make install puts libpng.a and png.h +prefix=/usr/local +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +CC=cc +CFLAGS=-I../zlib -O +LDFLAGS=-L. -L../zlib/ -lpng -lz -lm +# flags for ansi2knr +ANSI2KNRFLAGS= + +RANLIB=ranlib +#RANLIB=echo + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: ansi2knr libpng.a pngtest + +# general rule to allow ansi2knr to work +.c.o: + ./ansi2knr $*.c T$*.c + $(CC) $(CFLAGS) -c T$*.c + rm -f T$*.c $*.o + mv T$*.o $*.o + +ansi2knr: ansi2knr.c + $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c + +libpng.a: ansi2knr $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install: libpng.a + -@mkdir $(DESTDIR)$(INCPATH) + -@mkdir $(DESTDIR)$(INCPATH)/libpng + -@mkdir $(DESTDIR)$(LIBPATH) + -@rm -f $(DESTDIR)$(INCPATH)/png.h + -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h + cp png.h $(DESTDIR)$(INCPATH)/libpng + cp pngconf.h $(DESTDIR)$(INCPATH)/libpng + chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h + chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h + (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .) + cp libpng.a $(DESTDIR)$(LIBPATH) + chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a + +clean: + rm -f *.o libpng.a pngtest pngout.png ansi2knr + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngpread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.linux b/src/dep/src/irrlicht/libpng/scripts/makefile.linux new file mode 100644 index 0000000..e79f32d --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.linux @@ -0,0 +1,245 @@ +# makefile for libpng.a and libpng12.so on Linux ELF with gcc +# Copyright (C) 1998, 1999, 2002, 2006 Greg Roelofs and Glenn Randers-Pehrson +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +# where "make install" puts libpng12.a, libpng12.so*, +# libpng12/png.h and libpng12/pngconf.h +# Prefix must be a full pathname. +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located. +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \ + $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5 + +LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm +LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(OLDSOMAJ) \ + -o $(OLDSOVER) \ + $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +pngtest-static: pngtest.o libpng.a + $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A) + +test: pngtest pngtest-static + @echo "" + @echo " Running pngtest dynamically linked with $(LIBSO):" + @echo "" + ./pngtest + @echo "" + @echo " Running pngtest statically linked with libpng.a:" + @echo "" + ./pngtest-static + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.mingw b/src/dep/src/irrlicht/libpng/scripts/makefile.mingw new file mode 100644 index 0000000..6b074ac --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.mingw @@ -0,0 +1,312 @@ +# makefile for mingw on x86 +# Builds both dll (with import lib) and static lib versions +# of the library, and builds two copies of pngtest: one +# statically linked and one dynamically linked. +# +# Built from makefile.cygwin +# Copyright (C) 2002, 2006 Soren Anderson, Charles Wilson, +# and Glenn Randers-Pehrson, based on makefile for linux-elf w/mmx by: +# Copyright (C) 1998-2000 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# This makefile intends to support building outside the src directory +# if desired. When invoking it, specify an argument to SRCDIR on the +# command line that points to the top of the directory where your source +# is located. + +ifdef SRCDIR +VPATH = $(SRCDIR) +else +SRCDIR = . +endif + +# Override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. + +DESTDIR= + +# To enable assembler optimizations, add '-DPNG_USE_PNGGCCRD' to +# $CFLAGS, and include pnggccrd.o in $OBJS, below, and in the dependency +# list at the bottom of this makefile. + +CC=gcc + + +# Where "make install" puts libpng*.a, *png*.dll, png.h, and pngconf.h +ifndef prefix +prefix=/usr +$(warning You haven't specified a 'prefix=' location. Defaulting to "/usr") +endif +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +ZLIBLIB= /usr/lib +ZLIBINC= + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +### if you use the asm, add pnggccrd.o to the OBJS list +### +### if you don't need thread safety, but want the asm accel +#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD \ +# $(addprefix -I,$(ZLIBINC)) -Wall -O3 $(ALIGN) -funroll-loops \ +# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 +### if you need thread safety and want (minimal) asm accel +#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_USE_PNGGCCRD $(addprefix -I,$(ZLIBINC)) \ +# -Wall -O3 $(ALIGN) -funroll-loops \ +# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 +### Normal (non-asm) compilation +CFLAGS= $(strip $(MINGW_CCFLAGS) $(addprefix -I,$(ZLIBINC)) \ + -Wall -O3 $(ALIGN) -funroll-loops \ + -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5 + +LIBNAME = libpng12 +PNGMAJ = 0 +MINGDLL = 12 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +SHAREDLIB=libpng$(MINGDLL).dll +STATLIB=libpng.a +IMPLIB=libpng.dll.a +SHAREDDEF=libpng.def +LIBS=$(SHAREDLIB) $(STATLIB) +EXE=.exe + +LDFLAGS=$(strip -L. $(MINGW_LDFLAGS) -lpng $(addprefix -L,$(ZLIBLIB)) -lz) +LDSFLAGS=$(strip -shared -L. $(MINGW_LDFLAGS)) +LDEXTRA=-Wl,--out-implib=$(IMPLIB) $(addprefix -L,$(ZLIBLIB)) -lz + +MKDIR_P=/bin/mkdir -pv +RANLIB=ranlib +#RANLIB=echo + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib + +BINPATH=$(exec_prefix)/bin +MANPATH=$(prefix)/man +MAN3PATH=$(MANPATH)/man3 +MAN5PATH=$(MANPATH)/man5 + +# cosmetic: shortened strings: +S =$(SRCDIR) +D =$(DESTDIR) +DB =$(D)$(BINPATH) +DI =$(D)$(INCPATH) +DL =$(D)$(LIBPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o # pnggccrd.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +%.o : %.c + $(CC) -c $(CFLAGS) -o $@ $< +%.pic.o : CFLAGS += -DPNG_BUILD_DLL +%.pic.o : %.c + $(CC) -c $(CFLAGS) -o $@ $< + +all: all-static all-shared libpng.pc libpng-config libpng.pc libpng-config + +# Make this to verify that "make [...] install" will do what you want. +buildsetup-tell: + @echo VPATH is set to: \"$(VPATH)\" + @echo prefix is set to: \"$(prefix)\" + @echo -e INCPATH,LIBPATH, etc. are set to:'\n' \ + $(addprefix $(D),$(INCPATH)'\n' $(LIBPATH)'\n' $(BINPATH)'\n' \ + $(MANPATH)'\n' $(MAN3PATH)'\n' $(MAN5PATH)'\n')'\n' + +libpng.pc: scripts/libpng.pc.in + @echo -e Making pkg-config file for this libpng installation..'\n' \ + using PREFIX=\"$(prefix)\"'\n' + cat $(S)/scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \ + sed -e s/-lm// > libpng.pc + +libpng-config: scripts/libpng-config-head.in scripts/libpng-config-body.in + @echo -e Making $(LIBNAME) libpng-config file for this libpng \ + installation..'\n' using PREFIX=\"$(prefix)\"'\n' + ( cat $(S)/scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng$(MINGDLL) -lz\"; \ + cat $(S)/scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +static: all-static +shared: all-shared +all-static: $(STATLIB) pngtest-stat$(EXE) +all-shared: $(SHAREDLIB) pngtest$(EXE) + +pnggccrd.o: pnggccrd.c png.h pngconf.h + @echo "" + @echo ' You can ignore the "control reaches end of non-void function"' + @echo ' warning and " defined but not used" warnings:' + @echo "" + $(CC) -c $(CFLAGS) -o $@ $< + +pnggccrd.pic.o: pnggccrd.c png.h pngconf.h + @echo "" + @echo ' You can ignore the "control reaches end of non-void function"' + @echo ' warning and " defined but not used" warnings:' + @echo "" + $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $< + +$(STATLIB): $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +$(SHAREDDEF): scripts/pngw32.def + cat $< | sed -e '1{G;s/^\(.*\)\(\n\)/EXPORTS/;};2,/^EXPORTS/d' | \ + sed -e 's/\([^;]*\);/;/' > $@ + +$(SHAREDLIB): $(OBJSDLL) $(SHAREDDEF) + $(CC) $(LDSFLAGS) -o $@ $(OBJSDLL) -L. $(LDEXTRA) + +pngtest$(EXE): pngtest.pic.o $(SHAREDLIB) + $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@ + +pngtest-stat$(EXE): pngtest.o $(STATLIB) + $(CC) -static $(CFLAGS) $< $(LDFLAGS) -o $@ + +pngtest.pic.o: pngtest.c + $(CC) $(CFLAGS) -c $< -o $@ + +pngtest.o: pngtest.c + $(CC) $(CFLAGS) -c $< -o $@ + +test: test-static test-shared + +test-static: pngtest-stat$(EXE) + ./pngtest-stat $(S)/pngtest.png + +test-shared: pngtest$(EXE) + ./pngtest $(S)/pngtest.png + +install-static: $(STATLIB) install-headers install-man + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + install -m 644 $(STATLIB) $(DL)/$(LIBNAME).a + -@rm -f $(DL)/$(STATLIB) + (cd $(DL); ln -sf $(LIBNAME).a $(STATLIB)) + +install-shared: $(SHAREDLIB) libpng.pc libpng-config install-headers install-man + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc + -@/bin/rm -f $(DL)/pkgconfig/libpng.pc + install -m 644 $(IMPLIB) $(DL)/$(LIBNAME).dll.a + -@rm -f $(DL)/$(IMPLIB) + (cd $(DL); ln -sf $(LIBNAME).dll.a $(IMPLIB)) + install -s -m 755 $(SHAREDLIB) $(DB) + install -m 644 libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc) + +install-headers: + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + -@rm -f $(DI)/png.h + -@rm -f $(DI)/pngconf.h + install -m 644 $(S)/png.h $(S)/pngconf.h $(DI)/$(LIBNAME) + -@rm -f $(DI)/libpng + (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .) + +install-man: + -@if [ ! -d $(D)$(MAN3PATH) ]; then $(MKDIR_P) $(D)$(MAN3PATH); fi + -@if [ ! -d $(D)$(MAN5PATH) ]; then $(MKDIR_P) $(D)$(MAN5PATH); fi + install -m 644 $(S)/libpngpf.3 $(S)/libpng.3 $(D)$(MAN3PATH) + install -m 644 $(S)/png.5 $(D)$(MAN5PATH) + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@/bin/rm -f $(DB)/libpng-config + -@/bin/rm -f $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); ln -sf $(LIBNAME)-config libpng-config) + +# Run this to verify that a future `configure' run will pick up the settings +# you want. +test-config-install: SHELL=/bin/bash +test-config-install: $(DB)/libpng-config + @echo -e Testing libpng-config functions...'\n' + @ for TYRA in LDFLAGS CPPFLAGS CFLAGS LIBS VERSION; \ + do \ + printf "(%d)\t %10s =%s\n" $$(($$gytiu + 1)) $$TYRA \ + "$$($(DB)/libpng-config `echo --$$TYRA |tr '[:upper:]' '[:lower:]'`)"; \ + gytiu=$$(( $$gytiu + 1 )); \ + done + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) $(CFLAGS) \ + `$(BINPATH)/libpng12-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/libpng12-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CFLAGS) \ + `$(BINPATH)/libpng12-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti$(EXE) `$(BINPATH)/libpng12-config --ldflags` + ./pngtesti$(EXE) pngtest.png + +clean: + /bin/rm -f *.pic.o *.o $(STATLIB) $(IMPLIB) $(SHAREDLIB) \ + pngtest-stat$(EXE) pngtest$(EXE) pngout.png $(SHAREDDEF) \ + libpng-config libpng.pc pngtesti$(EXE) + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +.PHONY: buildsetup-tell libpng.pc libpng-config test-config-install clean + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h png.c +pngerror.o pngerror.pic.o: png.h pngconf.h pngerror.c +pngrio.o pngrio.pic.o: png.h pngconf.h pngrio.c +pngwio.o pngwio.pic.o: png.h pngconf.h pngwio.c +pngmem.o pngmem.pic.o: png.h pngconf.h pngmem.c +pngset.o pngset.pic.o: png.h pngconf.h pngset.c +pngget.o pngget.pic.o: png.h pngconf.h pngget.c +pngread.o pngread.pic.o: png.h pngconf.h pngread.c +pngrtran.o pngrtran.pic.o: png.h pngconf.h pngrtran.c +pngrutil.o pngrutil.pic.o: png.h pngconf.h pngrutil.c +pngtrans.o pngtrans.pic.o: png.h pngconf.h pngtrans.c +pngwrite.o pngwrite.pic.o: png.h pngconf.h pngwrite.c +pngwtran.o pngwtran.pic.o: png.h pngconf.h pngwtran.c +pngwutil.o pngwutil.pic.o: png.h pngconf.h pngwutil.c +pngpread.o pngpread.pic.o: png.h pngconf.h pngpread.c + +pngtest.o: png.h pngconf.h pngtest.c +pngtest-stat.o: png.h pngconf.h pngtest.c + + + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.mips b/src/dep/src/irrlicht/libpng/scripts/makefile.mips new file mode 100644 index 0000000..b77e006 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.mips @@ -0,0 +1,83 @@ +# makefile for libpng +# Copyright (C) Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# where make install puts libpng.a and png.h +prefix=/usr/local +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +CC=cc +CFLAGS=-I../zlib -O -systype sysv -DSYSV -w -Dmips +#CFLAGS=-O +LDFLAGS=-L. -L../zlib/ -lpng -lz -lm + +#RANLIB=ranlib +RANLIB=echo + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest + +libpng.a: $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install: libpng.a + -@mkdir $(DESTDIR)$(INCPATH) + -@mkdir $(DESTDIR)$(INCPATH)/libpng + -@mkdir $(DESTDIR)$(LIBPATH) + -@rm -f $(DESTDIR)$(INCPATH)/png.h + -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h + cp png.h $(DESTDIR)$(INCPATH)/libpng + cp pngconf.h $(DESTDIR)$(INCPATH)/libpng + chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h + chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h + (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .) + cp libpng.a $(DESTDIR)$(LIBPATH) + chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a + +clean: + rm -f *.o libpng.a pngtest pngout.png + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngpread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.msc b/src/dep/src/irrlicht/libpng/scripts/makefile.msc new file mode 100644 index 0000000..1741ed0 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.msc @@ -0,0 +1,86 @@ +# makefile for libpng +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h +# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib + +# -------- Microsoft C 5.1 and later, does not use assembler code -------- +MODEL=L +CFLAGS=-Oait -Gs -nologo -W3 -A$(MODEL) -I..\zlib +#-Ox generates bad code with MSC 5.1 +CC=cl +LD=link +LDFLAGS=/e/st:0x1500/noe +O=.obj + +#uncomment next to put error messages in a file +ERRFILE= >> pngerrs + +# variables +OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) +OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) +OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) + +all: libpng.lib + +png$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngset$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngget$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngpread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngerror$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngmem$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtest$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtrans$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwrite$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3) + del libpng.lib + lib libpng $(OBJS1); + lib libpng $(OBJS2); + lib libpng $(OBJS3); + +pngtest.exe: pngtest.obj libpng.lib + $(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\zlib\zlib.lib ; + +test: pngtest.exe + pngtest + +# End of makefile for libpng + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.ne12bsd b/src/dep/src/irrlicht/libpng/scripts/makefile.ne12bsd new file mode 100644 index 0000000..42adaca --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.ne12bsd @@ -0,0 +1,45 @@ +# makefile for libpng for NetBSD for the standard +# make obj && make depend && make && make test +# make includes && make install +# Copyright (C) 2002 Patrick R.L. Welche +# Copyright (C) 2007 Glenn Randers-Pehrson +# For conditions of distribution and use, see copyright notice in png.h + +# You should also run makefile.netbsd + +LOCALBASE?=/usr/local +LIBDIR= ${LOCALBASE}/lib +MANDIR= ${LOCALBASE}/man +INCSDIR=${LOCALBASE}/include/libpng12 + +LIB= png12 +SHLIB_MAJOR= 0 +SHLIB_MINOR= 1.2.18 +SRCS= pnggccrd.c png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \ + pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ + pngwtran.c pngmem.c pngerror.c pngpread.c +INCS= png.h pngconf.h +MAN= libpng.3 libpngpf.3 png.5 + +CPPFLAGS+=-I${.CURDIR} -DPNG_USE_PNGGCCRD + +# something like this for mmx assembler, but it core dumps for me at the moment +# .if ${MACHINE_ARCH} == "i386" +# CPPFLAGS+=-DPNG_THREAD_UNSAFE_OK +# MKLINT= no +# .else + CPPFLAGS+=-DPNG_NO_MMX_CODE +# .endif + +CLEANFILES+=pngtest.o pngtest + +pngtest.o: pngtest.c + ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} + +pngtest: pngtest.o libpng.a + ${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm + +test: pngtest + cd ${.CURDIR} && ${.OBJDIR}/pngtest + +.include diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.netbsd b/src/dep/src/irrlicht/libpng/scripts/makefile.netbsd new file mode 100644 index 0000000..89d6b35 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.netbsd @@ -0,0 +1,45 @@ +# makefile for libpng for NetBSD for the standard +# make obj && make depend && make && make test +# make includes && make install +# Copyright (C) 2002 Patrick R.L. Welche +# Copyright (C) 2007 Glenn Randers-Pehrson +# For conditions of distribution and use, see copyright notice in png.h + +# You should also run makefile.ne0bsd + +LOCALBASE?=/usr/local +LIBDIR= ${LOCALBASE}/lib +MANDIR= ${LOCALBASE}/man +INCSDIR=${LOCALBASE}/include/libpng + +LIB= png +SHLIB_MAJOR= 3 +SHLIB_MINOR= 1.2.18 +SRCS= pnggccrd.c png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \ + pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ + pngwtran.c pngmem.c pngerror.c pngpread.c +INCS= png.h pngconf.h +MAN= libpng.3 libpngpf.3 png.5 + +CPPFLAGS+=-I${.CURDIR} -DPNG_USE_PNGGCCRD + +# something like this for mmx assembler, but it core dumps for me at the moment +# .if ${MACHINE_ARCH} == "i386" +# CPPFLAGS+=-DPNG_THREAD_UNSAFE_OK +# MKLINT= no +# .else + CPPFLAGS+=-DPNG_NO_MMX_CODE +# .endif + +CLEANFILES+=pngtest.o pngtest + +pngtest.o: pngtest.c + ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} + +pngtest: pngtest.o libpng.a + ${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm + +test: pngtest + cd ${.CURDIR} && ${.OBJDIR}/pngtest + +.include diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.nommx b/src/dep/src/irrlicht/libpng/scripts/makefile.nommx new file mode 100644 index 0000000..30208d4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.nommx @@ -0,0 +1,248 @@ +# makefile for libpng.a and libpng12.so on Linux ELF with gcc +# Copyright (C) 1998, 1999, 2002, 2006, 2007 Greg Roelofs and +# Glenn Randers-Pehrson +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +RM_F=/bin/rm -f + +# where "make install" puts libpng12.a, libpng12.so*, +# libpng12/png.h and libpng12/pngconf.h +# Prefix must be a full pathname. +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located. +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \ + -DPNG_NO_MMX_CODE \ + $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5 + +LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm +LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s!@PREFIX@!$(prefix)! \ + | sed -e "s!Cflags: !Cflags: -DPNG_NO_MMX_CODE !"> libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME) -DPNG_NO_MMX_CODE\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(OLDSOMAJ) \ + -o $(OLDSOVER) \ + $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +pngtest-static: pngtest.o libpng.a + $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A) + +test: pngtest pngtest-static + @echo "" + @echo " Running pngtest dynamically linked with $(LIBSO):" + @echo "" + ./pngtest + @echo "" + @echo " Running pngtest statically linked with libpng.a:" + @echo "" + ./pngtest-static + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.openbsd b/src/dep/src/irrlicht/libpng/scripts/makefile.openbsd new file mode 100644 index 0000000..3ff3b0e --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.openbsd @@ -0,0 +1,73 @@ +# makefile for libpng +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# Copyright (C) 2007 Glenn Randers-Pehrson +# For conditions of distribution and use, see copyright notice in png.h + +PREFIX?= /usr/local +LIBDIR= ${PREFIX}/lib +MANDIR= ${PREFIX}/man/cat + +SHLIB_MAJOR= 0 +SHLIB_MINOR= 1.2.18 + +LIB= png +SRCS= png.c pngerror.c pnggccrd.c pngget.c pngmem.c pngpread.c \ + pngread.c pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c \ + pngwio.c pngwrite.c pngwtran.c pngwutil.c + +HDRS= png.h pngconf.h + +CFLAGS+= -Wall +CPPFLAGS+= -I${.CURDIR} -DPNG_NO_MMX_CODE -DPNG_USE_PNGGCCRD + +NOPROFILE= Yes + +CLEANFILES+= pngtest.o pngtest + +MAN= libpng.3 libpngpf.3 png.5 +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO libpng.txt + +pngtest.o: pngtest.c + ${CC} ${CPPFLAGS} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET} + +pngtest: pngtest.o + ${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} -L${.OBJDIR} -lpng -lz -lm + +test: pngtest + cd ${.OBJDIR} && env \ + LD_LIBRARY_PATH="${.OBJDIR}" ${.OBJDIR}/pngtest + +beforeinstall: + if [ ! -d ${DESTDIR}${PREFIX}/include/libpng ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/include/libpng; \ + fi + if [ ! -d ${DESTDIR}${LIBDIR} ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}; \ + fi + if [ ! -d ${DESTDIR}${LIBDIR}/debug ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}/debug; \ + fi + if [ ! -d ${DESTDIR}${MANDIR}3 ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}3; \ + fi + if [ ! -d ${DESTDIR}${MANDIR}5 ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}5; \ + fi + if [ ! -d ${DESTDIR}${PREFIX}/share/doc/png ]; then \ + ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/share/doc/png; \ + fi + +afterinstall: + @rm -f ${DESTDIR}${LIBDIR}/libpng_pic.a + @rm -f ${DESTDIR}${LIBDIR}/debug/libpng.a + @rm -f ${DESTDIR}${PREFIX}/include/png.h + @rm -f ${DESTDIR}${PREFIX}/include/pngconf.h + @rmdir ${DESTDIR}${LIBDIR}/debug 2>/dev/null || true + ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \ + -m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include/libpng + ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \ + -m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include + ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \ + -m ${NONBINMODE} ${DOCS} ${DESTDIR}${PREFIX}/share/doc/png + +.include diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.os2 b/src/dep/src/irrlicht/libpng/scripts/makefile.os2 new file mode 100644 index 0000000..e2eed69 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.os2 @@ -0,0 +1,69 @@ +# makefile for libpng on OS/2 with gcc +# For conditions of distribution and use, see copyright notice in png.h + +# Related files: pngos2.def + +CC=gcc -Zomf -s + +# Where the zlib library and include files are located +ZLIBLIB=../zlib +ZLIBINC=../zlib + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion +CFLAGS=-I$(ZLIBINC) -Wall -O6 -funroll-loops -malign-loops=2 \ + -malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5 +LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lzdll -Zcrtdll +AR=emxomfar + +PNGLIB=png.lib +IMPLIB=emximp +SHAREDLIB=png.dll +SHAREDLIBIMP=pngdll.lib + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +.SUFFIXES: .c .o + +all: $(PNGLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +$(PNGLIB): $(OBJS) + $(AR) rc $@ $(OBJS) + +$(SHAREDLIB): $(OBJS) pngos2.def + $(CC) $(LDFLAGS) -Zdll -o $@ $^ + +$(SHAREDLIBIMP): pngos2.def + $(IMPLIB) -o $@ $^ + +pngtest.exe: pngtest.o png.dll pngdll.lib + $(CC) -o $@ $(CFLAGS) $< $(LDFLAGS) + +test: pngtest.exe + ./pngtest.exe + +clean: + rm -f *.o $(PNGLIB) png.dll pngdll.lib pngtest.exe pngout.png + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.sco b/src/dep/src/irrlicht/libpng/scripts/makefile.sco new file mode 100644 index 0000000..d2cb1d1 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.sco @@ -0,0 +1,225 @@ +# makefile for SCO OSr5 ELF and Unixware 7 with Native cc +# Contributed by Mike Hopkirk (hops@sco.com) modified from Makefile.lnx +# force ELF build dynamic linking, SONAME setting in lib and RPATH in app +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1998 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +CC=cc +AR_RC=ar rc +MKDIR_P=mkdir +LN_SF=ln -f -s +RANLIB=echo +RM_F=/bin/rm -f + +# where make install puts libpng.a, $(OLDSO)*, and png.h +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +CFLAGS= -dy -belf -I$(ZLIBINC) -O3 +LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz -lm + +INCPATH=$(prefix)/include/libpng +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo ccopts=\"-belf\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + $(CC) -G -Wl,-h,$(LIBSOMAJ) -o $(LIBSOVER) \ + $(OBJSDLL) + +$(OLDSOVER): $(OBJSDLL) + $(CC) -G -Wl,-h,$(OLDSOMAJ) -o $(OLDSOVER) \ + $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + LD_RUN_PATH=.:$(ZLIBLIB) $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + -@$(RM_F) $(DI)/png.h + -@$(RM_F) $(DI)/pngconf.h + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) $(CFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.sggcc b/src/dep/src/irrlicht/libpng/scripts/makefile.sggcc new file mode 100644 index 0000000..b4c1a4b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.sggcc @@ -0,0 +1,238 @@ +# makefile for libpng.a and libpng12.so, SGI IRIX with 'cc' +# Copyright (C) 2001-2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME=libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=echo +RM_F=/bin/rm -f + +# Where make install puts libpng.a, libpng12.so, and libpng12/png.h +# Prefix must be a full pathname. + +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib32 +#ZLIBINC=/usr/local/include +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +# ABI can be blank to use default for your system, -32, -o32, -n32, or -64 +# See "man abi". zlib must be built with the same ABI. +ABI= + +WARNMORE= # -g -DPNG_DEBUG=5 +CFLAGS=$(ABI) -I$(ZLIBINC) -O2 $(WARNMORE) -fPIC -mabi=n32 +LDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm +LDSHARED=cc $(ABI) -shared -soname $(LIBSOMAJ) \ + -set_version sgi$(PNGMAJ).0 +LDLEGACY=cc $(ABI) -shared -soname $(OLDSOMAJ) \ + -set_version sgi$3.0 +# See "man dso" for info about shared objects + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +#LIBPATH=$(exec_prefix)/lib32 +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = pnggccrd.o png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest shared libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +shared: $(LIBSOVER) + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo ccopts=\"$(ABI)\"; \ + echo ldopts=\"$(ABI)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libdir=\"$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + $(RM_F) $(LIBSO) $(LIBSOMAJ) + +$(OLDSOVER): $(OBJS) + $(LDLEGACY) -o $@ $(OBJS) + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + echo + echo Testing local static library. + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -rpath $(ZLIBLIB):$(DL) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -rpath $(ZLIBLIB):`$(BINPATH)/$(LIBNAME)-config --libdir` \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) libpng.a pngtest pngtesti pngout.png libpng.pc libpng-config \ + $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + so_locations + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h +pnggccrd.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.sgi b/src/dep/src/irrlicht/libpng/scripts/makefile.sgi new file mode 100644 index 0000000..1811914 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.sgi @@ -0,0 +1,243 @@ +# makefile for libpng.a and libpng12.so, SGI IRIX with 'cc' +# Copyright (C) 2001-2002, 2006, 2007 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME=libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=cc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=echo +RM_F=/bin/rm -f + +# Where make install puts libpng.a, libpng12.so, and libpng12/png.h +# Prefix must be a full pathname. + +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib32 +#ZLIBINC=/usr/local/include +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +# ABI can be blank to use default for your system, -32, -o32, -n32, or -64 +# See "man abi". zlib must be built with the same ABI. +ABI= + +WARNMORE=-fullwarn +# Note: -KPIC is the default anyhow +#CFLAGS= $(ABI) -I$(ZLIBINC) -O $(WARNMORE) -KPIC -DPNG_USE_PNGGCCRD # -g -DPNG_DEBUG=5 +CFLAGS=$(ABI) -I$(ZLIBINC) -O $(WARNMORE) -DPNG_USE_PNGGCCRD \ + -DPNG_NO_MMX_CODE +LDFLAGS_A=$(ABI) -L. -L$(ZLIBLIB) -lpng12 -lz -lm +LDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm +LDSHARED=cc $(ABI) -shared -soname $(LIBSOMAJ) \ + -set_version sgi$(PNGMAJ).0 +LDLEGACY=cc $(ABI) -shared -soname $(OLDSOMAJ) \ + -set_version sgi$3.0 +# See "man dso" for info about shared objects + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +#LIBPATH=$(exec_prefix)/lib32 +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = pnggccrd.o png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest shared libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +shared: $(LIBSOVER) + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo cppflags=\"-DPNG_USE_PNGGCCRD -DPNG_NO_MMX_CODE\"; \ + echo ccopts=\"$(ABI)\"; \ + echo ldopts=\"$(ABI)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo libdir=\"$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + $(RM_F) $(LIBSO) $(LIBSOMAJ) + +$(OLDSOVER): $(OBJS) + $(LDLEGACY) -o $@ $(OBJS) + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + echo + echo Testing local static library. + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) \ + -rpath $(ZLIBLIB):$(DL) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) \ + -rpath $(ZLIBLIB):`$(BINPATH)/$(LIBNAME)-config --libdir` \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png libpng.pc libpng-config \ + $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + so_locations + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h +pnggccrd.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.so9 b/src/dep/src/irrlicht/libpng/scripts/makefile.so9 new file mode 100644 index 0000000..5128fbd --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.so9 @@ -0,0 +1,247 @@ +# makefile for libpng on Solaris 9 (beta) with Forte cc +# Updated by Chad Schrock for Solaris 9 +# Contributed by William L. Sebok, based on makefile.linux +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1998-2001 Greg Roelofs +# Copyright (C) 1996-1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) +LIBNAME = libpng12 + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +# gcc 2.95 doesn't work. +CC=cc +AR_RC=ar rc +MKDIR_P=mkdir -p +LN_SF=ln -f -s +RANLIB=echo +RM_F=/bin/rm -f + +# Where make install puts libpng.a, $(OLDSO)*, and png.h +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +# Changing these to ../zlib poses a security risk. If you want +# to have zlib in an adjacent directory, specify the full path instead of "..". +#ZLIBLIB=../zlib +#ZLIBINC=../zlib +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +#Use the preinstalled zlib that comes with Solaris 9: +ZLIBLIB=/usr/lib +ZLIBINC=/usr/include + +#WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion +#CFLAGS=-I$(ZLIBINC) -Wall -O3 $(WARNMORE) -g -DPNG_DEBUG=5 +CFLAGS=-I$(ZLIBINC) -O3 +LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-R$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + @case "`type ld`" in *ucb*) \ + echo; \ + echo '## WARNING:'; \ + echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \ + echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \ + echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \ + echo '## The environment variable LD_LIBRARY_PATH should not be set'; \ + echo '## at all. If it is, things are likely to break because of'; \ + echo '## the libucb dependency that is created.'; \ + echo; \ + ;; \ + esac + $(LD) -G -h $(LIBSOMAJ) \ + -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJS) + $(LD) -G -h $(OLDSOMAJ) \ + -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ); \ + $(LN_SF) $(LIBSOMAJ) $(LIBSO)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL) + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.solaris b/src/dep/src/irrlicht/libpng/scripts/makefile.solaris new file mode 100644 index 0000000..0c6857b --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.solaris @@ -0,0 +1,244 @@ +# makefile for libpng on Solaris 2.x with gcc +# Copyright (C) 2004, 2006, 2007 Glenn Randers-Pehrson +# Contributed by William L. Sebok, based on makefile.linux +# Copyright (C) 1998 Greg Roelofs +# Copyright (C) 1996, 1997 Andreas Dilger +# For conditions of distribution and use, see copyright notice in png.h + +# Library name: +LIBNAME = libpng12 +PNGMAJ = 0 +PNGMIN = 1.2.18 +PNGVER = $(PNGMAJ).$(PNGMIN) + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOVER=$(LIBNAME).so.$(PNGVER) +OLDSO=libpng.so +OLDSOMAJ=libpng.so.3 +OLDSOVER=libpng.so.3.$(PNGMIN) + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -f -s +RANLIB=echo +RM_F=/bin/rm -f + +# Where make install puts libpng.a, libpng12.so*, and png.h +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located +# Changing these to ../zlib poses a security risk. If you want +# to have zlib in an adjacent directory, specify the full path instead of "..". +#ZLIBLIB=../zlib +#ZLIBINC=../zlib + +ZLIBLIB=/usr/local/lib +ZLIBINC=/usr/local/include + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes #-Wconversion +CFLAGS=-I$(ZLIBINC) -Wall -O \ + # $(WARNMORE) -g -DPNG_DEBUG=5 +LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.pic.o: + $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo cppflags=\"-DPNG_USE_PNGGCCRD -DPNG_NO_MMX_CODE\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-R$(LIBPATH)\"; \ + echo libs=\"-lpng12 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(LIBSOVER) + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ) + +$(LIBSOVER): $(OBJSDLL) + @case "`type ld`" in *ucb*) \ + echo; \ + echo '## WARNING:'; \ + echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \ + echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \ + echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \ + echo '## The environment variable LD_LIBRARY_PATH should not be set'; \ + echo '## at all. If it is, things are likely to break because of'; \ + echo '## the libucb dependency that is created.'; \ + echo; \ + ;; \ + esac + $(LD) -G -h $(LIBSOMAJ) \ + -o $(LIBSOVER) $(OBJSDLL) + +$(OLDSOVER): $(OBJS) + $(LD) -G -h $(OLDSOMAJ) \ + -o $(OLDSOVER) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install-headers: png.h pngconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOVER) libpng.pc \ + $(OLDSOVER) + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSOVER)* $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOMAJ) + -@$(RM_F) $(DL)/$(OLDSO) + -@$(RM_F) $(DL)/$(OLDSOMAJ) + -@$(RM_F) $(DL)/$(OLDSOVER)* + cp $(LIBSOVER) $(DL) + cp $(OLDSOVER) $(DL) + chmod 755 $(DL)/$(LIBSOVER) + chmod 755 $(DL)/$(OLDSOVER) + (cd $(DL); \ + $(LN_SF) $(OLDSOVER) $(OLDSOMAJ); \ + $(LN_SF) $(OLDSOMAJ) $(OLDSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSO); \ + $(LN_SF) $(LIBSOVER) $(LIBSOMAJ)) + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL) + ./pngtestd pngtest.png + +test-installed: + echo + echo Testing installed dynamic shared library. + $(CC) -I$(ZLIBINC) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \ + -L$(ZLIBLIB) -R$(ZLIBLIB) + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \ + libpng-config $(LIBSO) $(LIBSOMAJ)* \ + $(OLDSOVER) \ + libpng.pc + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h +pngerror.o pngerror.pic.o: png.h pngconf.h +pngrio.o pngrio.pic.o: png.h pngconf.h +pngwio.o pngwio.pic.o: png.h pngconf.h +pngmem.o pngmem.pic.o: png.h pngconf.h +pngset.o pngset.pic.o: png.h pngconf.h +pngget.o pngget.pic.o: png.h pngconf.h +pngread.o pngread.pic.o: png.h pngconf.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h +pngpread.o pngpread.pic.o: png.h pngconf.h + +pngtest.o: png.h pngconf.h diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.std b/src/dep/src/irrlicht/libpng/scripts/makefile.std new file mode 100644 index 0000000..eb0aea3 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.std @@ -0,0 +1,92 @@ +# makefile for libpng +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# where make install puts libpng.a and png.h +prefix=/usr/local +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +CC=cc +AR_RC=ar rc +MKDIR_P=mkdir +LN_SF=ln -sf +RANLIB=ranlib +RM_F=rm -f + +CFLAGS=-I$(ZLIBINC) -O # -g -DPNG_DEBUG=5 +LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install: libpng.a + -@$(MKDIR_P) $(DESTDIR)$(INCPATH) + -@$(MKDIR_P) $(DESTDIR)$(INCPATH)/libpng + -@$(MKDIR_P) $(DESTDIR)$(LIBPATH) + -@$(RM_F) $(DESTDIR)$(INCPATH)/png.h + -@$(RM_F) $(DESTDIR)$(INCPATH)/pngconf.h + cp png.h $(DESTDIR)$(INCPATH)/libpng + cp pngconf.h $(DESTDIR)$(INCPATH)/libpng + chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h + chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h + (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .) + cp libpng.a $(DESTDIR)$(LIBPATH) + chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.sunos b/src/dep/src/irrlicht/libpng/scripts/makefile.sunos new file mode 100644 index 0000000..fad81fc --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.sunos @@ -0,0 +1,97 @@ +# makefile for libpng +# Copyright (C) 2002, 2006 Glenn Randers-Pehrson +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# where make install puts libpng.a and png.h +prefix=/usr/local +INCPATH=$(prefix)/include +LIBPATH=$(prefix)/lib + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +# Where the zlib library and include files are located +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + + +WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \ + -Wmissing-declarations -Wtraditional -Wcast-align \ + -Wstrict-prototypes -Wmissing-prototypes + +CC=gcc +AR_RC=ar rc +MKDIR_P=mkdir -p +LN_SF=ln -f -s +RANLIB=ranlib +RM_F=/bin/rm -f + +CFLAGS=-I$(ZLIBINC) -O # $(WARNMORE) -DPNG_DEBUG=5 +LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o + +all: libpng.a pngtest + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o libpng.a + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest + +install: libpng.a + -@$(MKDIR_P) $(DESTDIR)$(INCPATH) + -@$(MKDIR_P) $(DESTDIR)$(INCPATH)/libpng + -@$(MKDIR_P) $(DESTDIR)$(LIBPATH) + -@$(RM_F) $(DESTDIR)$(INCPATH)/png.h + -@$(RM_F) $(DESTDIR)$(INCPATH)/pngconf.h + cp png.h $(DESTDIR)$(INCPATH)/libpng + cp pngconf.h $(DESTDIR)$(INCPATH)/libpng + chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h + chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h + (cd $(DESTDIR)$(INCPATH); $(LN_SF) libpng/* .) + cp libpng.a $(DESTDIR)$(LIBPATH) + chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h +pngrio.o: png.h pngconf.h +pngwio.o: png.h pngconf.h +pngmem.o: png.h pngconf.h +pngset.o: png.h pngconf.h +pngget.o: png.h pngconf.h +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.tc3 b/src/dep/src/irrlicht/libpng/scripts/makefile.tc3 new file mode 100644 index 0000000..cedefc4 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.tc3 @@ -0,0 +1,89 @@ +# Makefile for libpng +# TurboC/C++ (Note: All modules are compiled in C mode) + +# To use, do "make -fmakefile.tc3" + +# ----- Turbo C 3.00 (can be modified to work with earlier versions) ----- + +MODEL=l +CFLAGS=-O2 -Z -m$(MODEL) -I..\zlib +#CFLAGS=-D_NO_PROTO -O2 -Z -m$(MODEL) -I..\zlib # Turbo C older than 3.00 +CC=tcc +LD=tcc +LIB=tlib +LDFLAGS=-m$(MODEL) -L..\zlib +O=.obj +E=.exe + +# variables +OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) +OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) +OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) +OBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O) +OBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O) +OBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O) + +all: libpng$(MODEL).lib pngtest$(E) + +pngtest: pngtest$(E) + +test: pngtest$(E) + pngtest$(E) + +png$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngset$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngget$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngpread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngrtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngrutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngerror$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngmem$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngrio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngwio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngtest$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngtrans$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngwrite$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngwtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +pngwutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c + +libpng$(MODEL).lib: $(OBJS1) $(OBJS2) $(OBJS3) + $(LIB) libpng$(MODEL) +$(OBJSL1) + $(LIB) libpng$(MODEL) +$(OBJSL2) + $(LIB) libpng$(MODEL) +$(OBJSL3) + +pngtest$(E): pngtest$(O) libpng$(MODEL).lib + $(LD) $(LDFLAGS) pngtest.obj libpng$(MODEL).lib zlib_$(MODEL).lib + +# End of makefile for libpng diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.vcawin32 b/src/dep/src/irrlicht/libpng/scripts/makefile.vcawin32 new file mode 100644 index 0000000..89effe5 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.vcawin32 @@ -0,0 +1,103 @@ +# makefile for libpng +# Copyright (C) 1998 Tim Wegner +# For conditions of distribution and use, see copyright notice in png.h +# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib +# To use, do "nmake /f scripts\makefile.vcawin32" + +# -------- Microsoft Visual C++ 5.0 and later, uses assembler code -------- +# If you don't want to use assembler (MMX) code, use makefile.vcwin32 instead. + +# Compiler, linker, librarian, and other tools +CC = cl +LD = link +AR = lib +CFLAGS = -DPNG_USE_PNGVCRD -nologo -MD -O2 -W3 -I..\zlib +LDFLAGS = -nologo +ARFLAGS = -nologo +RM = del + +# File extensions +O=.obj + +#uncomment next to put error messages in a file +#ERRFILE= >> pngerrs.log + +# Variables +OBJS1 = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) +OBJS2 = pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) +OBJS3 = pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) +OBJS4 = pngvcrd$(O) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) + +# Targets +all: libpng.lib + +png$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngset$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngget$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngpread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngerror$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngmem$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtest$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtrans$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwrite$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngvcrd$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +libpng.lib: $(OBJS) + -$(RM) $@ + $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(ERRFILE) + +pngtest.exe: pngtest$(O) libpng.lib + $(LD) $(LDFLAGS) -out:$@ pngtest$(O) libpng.lib ..\zlib\zlib.lib $(ERRFILE) + +test: pngtest.exe + pngtest + +clean: + -$(RM) *$(O) + -$(RM) libpng.lib + -$(RM) pngtest.exe + -$(RM) pngout.png + +# End of makefile for libpng + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.vcwin32 b/src/dep/src/irrlicht/libpng/scripts/makefile.vcwin32 new file mode 100644 index 0000000..6148c83 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.vcwin32 @@ -0,0 +1,99 @@ +# makefile for libpng +# Copyright (C) 1998 Tim Wegner +# For conditions of distribution and use, see copyright notice in png.h +# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib +# To use, do "nmake /f scripts\makefile.vcwin32" + +# -------- Microsoft Visual C++ 2.0 and later, no assembler code -------- +# If you want to use assembler (MMX) code, use makefile.vcawin32 instead. + +# Compiler, linker, librarian, and other tools +CC = cl +LD = link +AR = lib +CFLAGS = -nologo -MD -O2 -W3 -I..\zlib +LDFLAGS = -nologo +ARFLAGS = -nologo +RM = del + +# File extensions +O=.obj + +#uncomment next to put error messages in a file +#ERRFILE= >> pngerrs.log + +# Variables +OBJS1 = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) +OBJS2 = pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) +OBJS3 = pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) + +# Targets +all: libpng.lib + +png$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngset$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngget$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngpread$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngerror$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngmem$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngrio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwio$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtest$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngtrans$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwrite$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwtran$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +pngwutil$(O): png.h pngconf.h + $(CC) -c $(CFLAGS) $*.c $(ERRFILE) + +libpng.lib: $(OBJS) + -$(RM) $@ + $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(ERRFILE) + +pngtest.exe: pngtest$(O) libpng.lib + $(LD) $(LDFLAGS) -out:$@ pngtest$(O) libpng.lib ..\zlib\zlib.lib $(ERRFILE) + +test: pngtest.exe + pngtest + +clean: + -$(RM) *$(O) + -$(RM) libpng.lib + -$(RM) pngtest.exe + -$(RM) pngout.png + +# End of makefile for libpng + diff --git a/src/dep/src/irrlicht/libpng/scripts/makefile.watcom b/src/dep/src/irrlicht/libpng/scripts/makefile.watcom new file mode 100644 index 0000000..32cd333 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makefile.watcom @@ -0,0 +1,109 @@ +# Makefile for libpng +# Watcom C/C++ 10.0 and later, 32-bit protected mode, flat memory model + +# Copyright (C) 2000, Pawel Mrochen, based on makefile.msc which is +# copyright 1995 Guy Eric Schalnat, Group 42, Inc. +# For conditions of distribution and use, see copyright notice in png.h + +# To use, do "wmake /f scripts\makefile.watcom" + + +# ---------------------- Watcom C/C++ 10.0 and later ----------------------- + +# Where the zlib library and include files are located +ZLIBLIB=..\zlib +ZLIBINC=..\zlib + +# Target OS +OS=DOS +#OS=NT + +# Target CPU +CPU=6 # Pentium Pro +#CPU=5 # Pentium + +# Calling convention +CALLING=r # registers +#CALLING=s # stack + +# Uncomment next to put error messages in a file +#ERRFILE=>>pngerrs + +# -------------------------------------------------------------------------- + + +CC=wcc386 +CFLAGS=-$(CPU)$(CALLING) -fp$(CPU) -fpi87 -oneatx -mf -bt=$(OS) -i=$(ZLIBINC) -zq +LD=wcl386 +LDFLAGS=-zq + +O=.obj + +OBJS1=png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) +OBJS2=pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) +OBJS3=pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) + + +all: test + +png$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngset$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngget$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngread$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngpread$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrtran$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrutil$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngerror$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngmem$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngrio$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwio$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngtest$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngtrans$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwrite$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwtran$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +pngwutil$(O): png.h pngconf.h + $(CC) $(CFLAGS) $*.c $(ERRFILE) + +libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3) + wlib -b -c -n -q libpng.lib $(OBJS1) + wlib -b -c -q libpng.lib $(OBJS2) + wlib -b -c -q libpng.lib $(OBJS3) + +pngtest.exe: pngtest.obj libpng.lib + $(LD) $(LDFLAGS) pngtest.obj libpng.lib $(ZLIBLIB)\zlib.lib + +test: pngtest.exe .symbolic + pngtest.exe + + +# End of makefile for libpng diff --git a/src/dep/src/irrlicht/libpng/scripts/makevms.com b/src/dep/src/irrlicht/libpng/scripts/makevms.com new file mode 100644 index 0000000..8061ba8 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/makevms.com @@ -0,0 +1,144 @@ +$! make libpng under VMS +$! +$! +$! Check for MMK/MMS +$! +$! This procedure accepts one parameter (contrib), which causes it to build +$! the programs from the contrib directory instead of libpng. +$! +$ p1 = f$edit(p1,"UPCASE") +$ if p1 .eqs. "CONTRIB" +$ then +$ set def [.contrib.gregbook] +$ @makevms +$ set def [-.pngminus] +$ @makevms +$ set def [--] +$ exit +$ endif +$ Make = "" +$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" +$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" +$! +$! Look for the compiler used +$! +$ zlibsrc = "[-.zlib]" +$ ccopt="/include=''zlibsrc'" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" +$ then +$ comp = "__gcc__=1" +$ CC :== GCC +$ else +$ comp = "__vaxc__=1" +$ endif +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$! +$! Build the thing plain or with mms/mmk +$! +$ write sys$output "Compiling Libpng sources ..." +$ if make.eqs."" +$ then +$ dele pngtest.obj;* +$ CALL MAKE png.OBJ "cc ''CCOPT' png" - + png.c png.h pngconf.h +$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" - + pngpread.c png.h pngconf.h +$ CALL MAKE pngset.OBJ "cc ''CCOPT' pngset" - + pngset.c png.h pngconf.h +$ CALL MAKE pngget.OBJ "cc ''CCOPT' pngget" - + pngget.c png.h pngconf.h +$ CALL MAKE pngread.OBJ "cc ''CCOPT' pngread" - + pngread.c png.h pngconf.h +$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" - + pngpread.c png.h pngconf.h +$ CALL MAKE pngrtran.OBJ "cc ''CCOPT' pngrtran" - + pngrtran.c png.h pngconf.h +$ CALL MAKE pngrutil.OBJ "cc ''CCOPT' pngrutil" - + pngrutil.c png.h pngconf.h +$ CALL MAKE pngerror.OBJ "cc ''CCOPT' pngerror" - + pngerror.c png.h pngconf.h +$ CALL MAKE pngmem.OBJ "cc ''CCOPT' pngmem" - + pngmem.c png.h pngconf.h +$ CALL MAKE pngrio.OBJ "cc ''CCOPT' pngrio" - + pngrio.c png.h pngconf.h +$ CALL MAKE pngwio.OBJ "cc ''CCOPT' pngwio" - + pngwio.c png.h pngconf.h +$ CALL MAKE pngtrans.OBJ "cc ''CCOPT' pngtrans" - + pngtrans.c png.h pngconf.h +$ CALL MAKE pngwrite.OBJ "cc ''CCOPT' pngwrite" - + pngwrite.c png.h pngconf.h +$ CALL MAKE pngwtran.OBJ "cc ''CCOPT' pngwtran" - + pngwtran.c png.h pngconf.h +$ CALL MAKE pngwutil.OBJ "cc ''CCOPT' pngwutil" - + pngwutil.c png.h pngconf.h +$ write sys$output "Building Libpng ..." +$ CALL MAKE libpng.OLB "lib/crea libpng.olb *.obj" *.OBJ +$ write sys$output "Building pngtest..." +$ CALL MAKE pngtest.OBJ "cc ''CCOPT' pngtest" - + pngtest.c png.h pngconf.h +$ call make pngtest.exe - + "LINK pngtest,libpng.olb/lib,''zlibsrc'libz.olb/lib" - + pngtest.obj libpng.olb +$ write sys$output "Testing Libpng..." +$ run pngtest +$ else +$ if f$search("DESCRIP.MMS") .eqs. "" then copy/nolog [.SCRIPTS]DESCRIP.MMS [] +$ 'make'/macro=('comp',zlibsrc='zlibsrc') +$ endif +$ write sys$output "Libpng build completed" +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/src/dep/src/irrlicht/libpng/scripts/pngos2.def b/src/dep/src/irrlicht/libpng/scripts/pngos2.def new file mode 100644 index 0000000..4e7f073 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/pngos2.def @@ -0,0 +1,258 @@ +;---------------------------------------- +; PNG.LIB module definition file for OS/2 +;---------------------------------------- + +; Version 1.2.18 + +LIBRARY PNG +DESCRIPTION "PNG image compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + + + png_build_grayscale_palette + png_check_sig + png_chunk_error + png_chunk_warning + png_convert_from_struct_tm + png_convert_from_time_t + png_create_info_struct + png_create_read_struct + png_create_write_struct + png_data_freer + png_destroy_info_struct + png_destroy_read_struct + png_destroy_write_struct + png_error + png_free + png_free_data + png_get_IHDR + png_get_PLTE + png_get_bKGD + png_get_bit_depth + png_get_cHRM + png_get_cHRM_fixed + png_get_channels + png_get_color_type + png_get_compression_buffer_size + png_get_compression_type + png_get_copyright + png_get_error_ptr + png_get_filter_type + png_get_gAMA + png_get_gAMA_fixed + png_get_hIST + png_get_header_ver + png_get_header_version + png_get_iCCP + png_get_image_height + png_get_image_width + png_get_interlace_type + png_get_io_ptr + png_get_libpng_ver + png_get_oFFs + png_get_pCAL + png_get_pHYs + png_get_pixel_aspect_ratio + png_get_pixels_per_meter + png_get_progressive_ptr + png_get_rgb_to_gray_status + png_get_rowbytes + png_get_rows + png_get_sBIT + png_get_sCAL + png_get_sPLT + png_get_sRGB + png_get_signature + png_get_tIME + png_get_tRNS + png_get_text + png_get_unknown_chunks + png_get_user_chunk_ptr + png_get_user_transform_ptr + png_get_valid + png_get_x_offset_microns + png_get_x_offset_pixels + png_get_x_pixels_per_meter + png_get_y_offset_microns + png_get_y_offset_pixels + png_get_y_pixels_per_meter + png_malloc + png_memcpy_check + png_memset_check + png_permit_empty_plte + png_process_data + png_progressive_combine_row + png_read_end + png_read_image + png_read_info +; png_read_init ; deprecated + png_read_png + png_read_row + png_read_rows + png_read_update_info + png_reset_zstream + png_set_IHDR + png_set_PLTE + png_set_bKGD + png_set_background + png_set_bgr + png_set_cHRM + png_set_cHRM_fixed + png_set_compression_buffer_size + png_set_compression_level + png_set_compression_mem_level + png_set_compression_method + png_set_compression_strategy + png_set_compression_window_bits + png_set_crc_action + png_set_dither + png_set_error_fn + png_set_expand + png_set_filler + png_set_filter + png_set_filter_heuristics + png_set_flush + png_set_gAMA + png_set_gAMA_fixed + png_set_gamma +; png_set_gray_1_2_4_to_8 ; deprecated as of libpng-1.2.9 + png_set_gray_to_rgb + png_set_hIST + png_set_iCCP + png_set_interlace_handling + png_set_invert_alpha + png_set_invert_mono + png_set_keep_unknown_chunks + png_set_oFFs + png_set_pCAL + png_set_pHYs + png_set_packing + png_set_packswap + png_set_palette_to_rgb + png_set_progressive_read_fn + png_set_read_fn + png_set_read_status_fn + png_set_read_user_chunk_fn + png_set_read_user_transform_fn + png_set_rgb_to_gray + png_set_rgb_to_gray_fixed + png_set_rows + png_set_sBIT + png_set_sCAL + png_set_sPLT + png_set_sRGB + png_set_sRGB_gAMA_and_cHRM + png_set_shift + png_set_sig_bytes + png_set_strip_16 + png_set_strip_alpha + png_set_swap + png_set_swap_alpha + png_set_tIME + png_set_tRNS + png_set_tRNS_to_alpha + png_set_text + png_set_unknown_chunk_location + png_set_unknown_chunks + png_set_user_transform_info + png_set_write_fn + png_set_write_status_fn + png_set_write_user_transform_fn + png_sig_cmp + png_start_read_image + png_warning + png_write_chunk + png_write_chunk_data + png_write_chunk_end + png_write_chunk_start + png_write_end + png_write_flush + png_write_image + png_write_info + png_write_info_before_PLTE +; png_write_init ; deprecated + png_write_png + png_write_row + png_write_rows + png_read_init_2 + png_write_init_2 + png_access_version_number + png_init_io + png_convert_to_rfc1123 + png_set_invalid + +; Added at version 1.2.0: + png_mmx_support + png_permit_empty_plte + png_permit_mng_features + png_get_mmx_flagmask + png_get_asm_flagmask + png_get_asm_flags + png_get_mmx_bitdepth_threshold + png_get_mmx_rowbytes_threshold + png_set_asm_flags + png_init_mmx_flags + +; Added at version 1.2.2: + png_handle_as_unknown + +; Added at version 1.2.2 and deleted from 1.2.3: +; png_zalloc +; png_zfree + +; Added at version 1.2.4 + png_malloc_warn + +; Added at version 1.2.6 + png_set_user_limits + png_get_user_height_max + png_get_user_width_max +; Added at version 1.2.7 + png_set_add_alpha + +; Added at version 1.2.9 + png_get_uint_32 + png_save_uint_32 + png_get_uint_16 + png_save_uint_16 + png_get_int_32 + png_save_int_32 + png_get_uint_31 + png_set_expand_gray_1_2_4_to_8 + +; These are not present when libpng is compiled with PNG_NO_GLOBAL_ARRAYS + png_libpng_ver + png_pass_start + png_pass_inc + png_pass_ystart + png_pass_yinc + png_pass_mask + png_pass_dsp_mask +; png_pass_width +; png_pass_height + +; These are not present when libpng is compiled with PNG_NO_GLOBAL_ARRAYS + png_IHDR + png_IDAT + png_IEND + png_PLTE + png_bKGD + png_cHRM + png_gAMA + png_hIST + png_iCCP + png_iTXt + png_oFFs + png_pCAL + png_pHYs + png_sBIT + png_sCAL + png_sPLT + png_sRGB + png_tEXt + png_tIME + png_tRNS + png_zTXt diff --git a/src/dep/src/irrlicht/libpng/scripts/pngw32.def b/src/dep/src/irrlicht/libpng/scripts/pngw32.def new file mode 100644 index 0000000..f66d9c2 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/pngw32.def @@ -0,0 +1,236 @@ +;------------------------------------------ +; LIBPNG module definition file for Windows +;------------------------------------------ + +LIBRARY + +EXPORTS +;Version 1.2.18 + png_build_grayscale_palette @1 + png_check_sig @2 + png_chunk_error @3 + png_chunk_warning @4 + png_convert_from_struct_tm @5 + png_convert_from_time_t @6 + png_create_info_struct @7 + png_create_read_struct @8 + png_create_write_struct @9 + png_data_freer @10 + png_destroy_info_struct @11 + png_destroy_read_struct @12 + png_destroy_write_struct @13 + png_error @14 + png_free @15 + png_free_data @16 + png_get_IHDR @17 + png_get_PLTE @18 + png_get_bKGD @19 + png_get_bit_depth @20 + png_get_cHRM @21 + png_get_cHRM_fixed @22 + png_get_channels @23 + png_get_color_type @24 + png_get_compression_buffer_size @25 + png_get_compression_type @26 + png_get_copyright @27 + png_get_error_ptr @28 + png_get_filter_type @29 + png_get_gAMA @30 + png_get_gAMA_fixed @31 + png_get_hIST @32 + png_get_header_ver @33 + png_get_header_version @34 + png_get_iCCP @35 + png_get_image_height @36 + png_get_image_width @37 + png_get_interlace_type @38 + png_get_io_ptr @39 + png_get_libpng_ver @40 + png_get_oFFs @41 + png_get_pCAL @42 + png_get_pHYs @43 + png_get_pixel_aspect_ratio @44 + png_get_pixels_per_meter @45 + png_get_progressive_ptr @46 + png_get_rgb_to_gray_status @47 + png_get_rowbytes @48 + png_get_rows @49 + png_get_sBIT @50 + png_get_sCAL @51 + png_get_sPLT @52 + png_get_sRGB @53 + png_get_signature @54 + png_get_tIME @55 + png_get_tRNS @56 + png_get_text @57 + png_get_unknown_chunks @58 + png_get_user_chunk_ptr @59 + png_get_user_transform_ptr @60 + png_get_valid @61 + png_get_x_offset_microns @62 + png_get_x_offset_pixels @63 + png_get_x_pixels_per_meter @64 + png_get_y_offset_microns @65 + png_get_y_offset_pixels @66 + png_get_y_pixels_per_meter @67 + png_malloc @68 + png_memcpy_check @69 + png_memset_check @70 +; png_permit_empty_plte is deprecated + png_permit_empty_plte @71 + png_process_data @72 + png_progressive_combine_row @73 + png_read_end @74 + png_read_image @75 + png_read_info @76 +; png_read_init is deprecated + png_read_init @77 + png_read_png @78 + png_read_row @79 + png_read_rows @80 + png_read_update_info @81 + png_reset_zstream @82 + png_set_IHDR @83 + png_set_PLTE @84 + png_set_bKGD @85 + png_set_background @86 + png_set_bgr @87 + png_set_cHRM @88 + png_set_cHRM_fixed @89 + png_set_compression_buffer_size @90 + png_set_compression_level @91 + png_set_compression_mem_level @92 + png_set_compression_method @93 + png_set_compression_strategy @94 + png_set_compression_window_bits @95 + png_set_crc_action @96 + png_set_dither @97 + png_set_error_fn @98 + png_set_expand @99 + png_set_filler @100 + png_set_filter @101 + png_set_filter_heuristics @102 + png_set_flush @103 + png_set_gAMA @104 + png_set_gAMA_fixed @105 + png_set_gamma @106 +; png_set_gray_1_2_4_to_8 is deprecated + png_set_gray_1_2_4_to_8 @107 + png_set_gray_to_rgb @108 + png_set_hIST @109 + png_set_iCCP @110 + png_set_interlace_handling @111 + png_set_invert_alpha @112 + png_set_invert_mono @113 + png_set_keep_unknown_chunks @114 + png_set_oFFs @115 + png_set_pCAL @116 + png_set_pHYs @117 + png_set_packing @118 + png_set_packswap @119 + png_set_palette_to_rgb @120 + png_set_progressive_read_fn @121 + png_set_read_fn @122 + png_set_read_status_fn @123 + png_set_read_user_chunk_fn @124 + png_set_read_user_transform_fn @125 + png_set_rgb_to_gray @126 + png_set_rgb_to_gray_fixed @127 + png_set_rows @128 + png_set_sBIT @129 + png_set_sCAL @130 + png_set_sPLT @131 + png_set_sRGB @132 + png_set_sRGB_gAMA_and_cHRM @133 + png_set_shift @134 + png_set_sig_bytes @135 + png_set_strip_16 @136 + png_set_strip_alpha @137 + png_set_swap @138 + png_set_swap_alpha @139 + png_set_tIME @140 + png_set_tRNS @141 + png_set_tRNS_to_alpha @142 + png_set_text @143 + png_set_unknown_chunk_location @144 + png_set_unknown_chunks @145 + png_set_user_transform_info @146 + png_set_write_fn @147 + png_set_write_status_fn @148 + png_set_write_user_transform_fn @149 + png_sig_cmp @150 + png_start_read_image @151 + png_warning @152 + png_write_chunk @153 + png_write_chunk_data @154 + png_write_chunk_end @155 + png_write_chunk_start @156 + png_write_end @157 + png_write_flush @158 + png_write_image @159 + png_write_info @160 + png_write_info_before_PLTE @161 +; png_write_init is deprecated + png_write_init @162 + png_write_png @163 + png_write_row @164 + png_write_rows @165 +; png_read_init_2 and png_write_init_2 are deprecated. + png_read_init_2 @166 + png_write_init_2 @167 + png_access_version_number @168 +; png_sig_bytes @169 + png_libpng_ver @170 + png_init_io @171 + png_convert_to_rfc1123 @172 + png_set_invalid @173 +; Added at version 1.0.12 +; For compatibility with 1.0.7-1.0.11 +; png_info_init @174 + png_read_init_3 @175 + png_write_init_3 @176 + png_info_init_3 @177 + png_destroy_struct @178 +; Added at version 1.2.0 +; For use with PNG_USER_MEM_SUPPORTED + png_destroy_struct_2 @179 + png_create_read_struct_2 @180 + png_create_write_struct_2 @181 + png_malloc_default @182 + png_free_default @183 +; MNG features + png_permit_mng_features @184 +; MMX support + png_mmx_support @185 +; png_get_mmx_flagmask @186 + png_get_asm_flagmask @187 + png_get_asm_flags @188 +; png_get_mmx_bitdepth_threshold @189 +; png_get_mmx_rowbytes_threshold @190 + png_set_asm_flags @191 +; png_init_mmx_flags @192 +; Strip error numbers + png_set_strip_error_numbers @193 +; Added at version 1.2.2 + png_handle_as_unknown @194 +; Added at version 1.2.2 and deleted from 1.2.3 +; png_zalloc @195 +; png_zfree @196 +; Added at version 1.2.4 + png_malloc_warn @195 +; Added at version 1.2.6 + png_malloc_warn @195 + png_get_user_height_max @196 + png_get_user_width_max @197 + png_set_user_limits @198 +; Added at version 1.2.7 + png_set_add_alpha @199 +; Added at version 1.2.9 + png_get_uint_32 @200 + png_save_uint_32 @201 + png_get_uint_16 @202 + png_save_uint_16 @203 + png_get_int_32 @204 + png_save_int_32 @205 + png_get_uint_31 @206 + png_set_expand_gray_1_2_4_to_8 @207 diff --git a/src/dep/src/irrlicht/libpng/scripts/pngw32.rc b/src/dep/src/irrlicht/libpng/scripts/pngw32.rc new file mode 100644 index 0000000..f6cb0f0 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/pngw32.rc @@ -0,0 +1,112 @@ +#define PNG_VERSION_INFO_ONLY + +#include +#include "../png.h" + +#define _QUOTE(x) # x +#define QUOTE(x) _QUOTE(x) + +#define PNG_LIBPNG_DLLFNAME "LIBPNG" + +/* Support deprecated PRIVATEBUILD macro */ +#if defined(PRIVATEBUILD) && !defined(PNG_USER_PRIVATEBUILD) +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif + +#if defined(PNG_USER_DLLFNAME_POSTFIX) && !defined(PNG_USER_PRIVATEBUILD) +# error "PNG_USER_PRIVATEBUILD must be defined as a string describing the\ + custom changes made to the library." +#endif + +/* Prioritize PNG_USER_x over PNG_LIBPNG_x */ +#ifdef PNG_USER_DLLFNAME_POSTFIX +# undef PNG_LIBPNG_DLLFNAME_POSTFIX +# define PNG_LIBPNG_DLLFNAME_POSTFIX PNG_USER_DLLFNAME_POSTFIX +#endif + +#ifdef PNG_USER_VERSIONINFO_COMMENTS +# undef PNG_LIBPNG_VERSIONINFO_COMMENTS +# define PNG_LIBPNG_VERSIONINFO_COMMENTS PNG_USER_VERSIONINFO_COMMENTS +#endif + +#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) +# define VS_DEBUG VS_FF_DEBUG +# ifndef PNG_LIBPNG_DLLFNAME_POSTFIX +# define PNG_LIBPNG_DLLFNAME_POSTFIX "D" +# endif /* PNG_LIBPNG_DLLFNAME_POSTFIX */ +# ifndef PNG_LIBPNG_VERSIONINFO_COMMENTS +# define PNG_LIBPNG_VERSIONINFO_COMMENTS "PNG_DEBUG=" QUOTE(PNG_DEBUG) +# endif /* PNG_LIBPNG_VERSIONINFO_COMMENTS */ +#else +# define VS_DEBUG 0 +# ifndef PNG_LIBPNG_DLLFNAME_POSTFIX +# define PNG_LIBPNG_DLLFNAME_POSTFIX +# endif /* PNG_LIBPNG_DLLFNAME_POSTFIX */ +#endif /* defined(DEBUG)... */ + +#ifdef PNG_USER_PRIVATEBUILD +# define VS_PRIVATEBUILD VS_FF_PRIVATEBUILD +#else +# define VS_PRIVATEBUILD 0 +#endif /* PNG_USER_PRIVATEBUILD */ + +#ifdef PNG_LIBPNG_SPECIALBUILD +# define VS_SPECIALBUILD VS_FF_SPECIALBUILD +#else +# define VS_SPECIALBUILD 0 +#endif /* PNG_LIBPNG_BUILD_SPECIAL */ + +#if ((PNG_LIBPNG_BUILD_BASE_TYPE & PNG_LIBPNG_RELEASE_STATUS_MASK) !=\ + PNG_LIBPNG_BUILD_STABLE) +# define VS_PRERELEASE VS_FF_PRERELEASE +# define VS_PATCHED 0 +#else +# define VS_PRERELEASE 0 +# if (PNG_LIBPNG_BUILD_BASE_TYPE & PNG_LIBPNG_BUILD_PATCHED) +# define VS_PATCHED VS_FF_PATCHED +# else +# define VS_PATCHED 0 +# endif +#endif + +VS_VERSION_INFO VERSIONINFO +FILEVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD +PRODUCTVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS VS_DEBUG | VS_PRIVATEBUILD | VS_SPECIALBUILD | VS_PRERELEASE | VS_PATCHED +FILEOS VOS__WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN BLOCK "040904E4" /* Language type = U.S English(0x0409) and Character Set = Windows, Multilingual(0x04E4) */ + BEGIN +#ifdef PNG_LIBPNG_VERSIONINFO_COMMENTS + VALUE "Comments", PNG_LIBPNG_VERSIONINFO_COMMENTS "\000" +#endif /* PNG_LIBPNG_VERSIONINFO_COMMENTS */ +#ifdef PNG_USER_VERSIONINFO_COMPANYNAME + VALUE "CompanyName", PNG_USER_VERSIONINFO_COMPANYNAME "\000" +#endif /* PNG_USER_VERSIONINFO_COMPANYNAME */ + VALUE "FileDescription", "PNG image compression library\000" + VALUE "FileVersion", PNG_LIBPNG_VER_STRING "\000" + VALUE "InternalName", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_DLLNUM) PNG_LIBPNG_DLLFNAME_POSTFIX " (Windows 32 bit)\000" + VALUE "LegalCopyright", "\251 1998-2004 Glenn Randers-Pehrson et al.\000" +#ifdef PNG_USER_VERSIONINFO_LEGALTRADEMARKS + VALUE "LegalTrademarks", PNG_USER_VERSIONINFO_LEGALTRADEMARKS "\000" +#endif /* PNG_USER_VERSIONINFO_LEGALTRADEMARKS */ + VALUE "OriginalFilename", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_DLLNUM) PNG_LIBPNG_DLLFNAME_POSTFIX ".DLL\000" +#ifdef PNG_USER_PRIVATEBUILD + VALUE "PrivateBuild", PNG_USER_PRIVATEBUILD "\000" +#endif /* PNG_USER_PRIVATEBUILD */ + VALUE "ProductName", "LibPNG\000" + VALUE "ProductVersion", "1\000" +#ifdef PNG_LIBPNG_SPECIALBUILD + VALUE "SpecialBuild", PNG_LIBPNG_SPECIALBUILD "\000" +#endif /* PNG_LIBPNG_SPECIALBUILD */ + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04E4 + END +END diff --git a/src/dep/src/irrlicht/libpng/scripts/smakefile.ppc b/src/dep/src/irrlicht/libpng/scripts/smakefile.ppc new file mode 100644 index 0000000..2bc2178 --- /dev/null +++ b/src/dep/src/irrlicht/libpng/scripts/smakefile.ppc @@ -0,0 +1,30 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert +# For conditions of distribution and use, see copyright notice in png.h + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL IDIR /zlib \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 +LIBNAME = libpng.a +AR = ppc-amigaos-ar +AR_FLAGS = cr +RANLIB = ppc-amigaos-ranlib +LDFLAGS = -r -o +LDLIBS = ../zlib/libzip.a LIB:scppc.a +LN = ppc-amigaos-ld +RM = delete quiet +MKDIR = makedir + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngread.o \ +pngerror.o pngpread.o pngwrite.o pngrtran.o pngwtran.o pngrio.o pngwio.o pngmem.o + +all: $(LIBNAME) pngtest + +$(LIBNAME): $(OBJS) + $(AR) $(AR_FLAGS) $@ $(OBJS) + $(RANLIB) $@ + +pngtest: pngtest.o $(LIBNAME) + $(LN) $(LDFLAGS) pngtest LIB:c_ppc.o pngtest.o $(LIBNAME) $(LDLIBS) \ +LIB:end.o diff --git a/src/dep/src/irrlicht/os.cpp b/src/dep/src/irrlicht/os.cpp new file mode 100644 index 0000000..afee872 --- /dev/null +++ b/src/dep/src/irrlicht/os.cpp @@ -0,0 +1,299 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "os.h" +#include "irrString.h" +#include "IrrCompileConfig.h" +#include "irrMath.h" + +#if defined(_IRR_USE_SDL_DEVICE_) + #include + #define bswap_16(X) SDL_Swap16(X) + #define bswap_32(X) SDL_Swap32(X) +#elif defined(_IRR_WINDOWS_API_) + #if (defined(_MSC_VER) && (_MSC_VER > 1298)) + #include + #define bswap_16(X) _byteswap_ushort(X) + #define bswap_32(X) _byteswap_ulong(X) + #else + #define bswap_16(X) ((((X)&0xFF) << 8) | (((X)&=0xFF00) >> 8)) + #define bswap_32(X) ( (((X)&0x000000FF)<<24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8)) + #endif +#else + #ifdef MACOSX + #define bswap_16(X) OSReadSwapInt16(&X,0) + #define bswap_32(X) OSReadSwapInt32(&X,0) + #elif defined(__FreeBSD__) + #include + #define bswap_16(X) bswap16(X) + #define bswap_32(X) bswap32(X) + #elif !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__PPC__) + #include + #else + #define bswap_16(X) ((((X)&0xFF) << 8) | (((X)&=0xFF00) >> 8)) + #define bswap_32(X) ( (((X)&0x000000FF)<<24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8)) + #endif +#endif + +namespace irr +{ +namespace os +{ + u16 Byteswap::byteswap(u16 num) {return bswap_16(num);} + s16 Byteswap::byteswap(s16 num) {return bswap_16(num);} + u32 Byteswap::byteswap(u32 num) {return bswap_32(num);} + s32 Byteswap::byteswap(s32 num) {return bswap_32(num);} + f32 Byteswap::byteswap(f32 num) {u32 tmp=bswap_32(*((u32*)&num)); return *((f32*)&tmp);} +} +} + +#if defined(_IRR_WINDOWS_API_) +// ---------------------------------------------------------------- +// Windows specific functions +// ---------------------------------------------------------------- + +#ifdef _IRR_XBOX_PLATFORM_ +#include +#else +#define WIN32_LEAN_AND_MEAN +#include +#endif + +namespace irr +{ +namespace os +{ + //! prints a debuginfo string + void Printer::print(const c8* message) + { + c8* tmp = new c8[strlen(message) + 2]; + sprintf(tmp, "%s\n", message); + OutputDebugString(tmp); + printf(tmp); + delete [] tmp; + } + + LARGE_INTEGER HighPerformanceFreq; + BOOL HighPerformanceTimerSupport = FALSE; + + void Timer::initTimer() + { + // disable hires timer on multiple core systems, bios bugs result in bad hires timers. + SYSTEM_INFO sysinfo; + DWORD affinity, sysaffinity; + GetSystemInfo(&sysinfo); + s32 affinityCount = 0; + + // count the processors that can be used by this process + if (GetProcessAffinityMask( GetCurrentProcess(), &affinity, &sysaffinity )) + { + for (u32 i=0; i<32; ++i) + { + if ((1< +#include +#include + +namespace irr +{ +namespace os +{ + + //! prints a debuginfo string + void Printer::print(const c8* message) + { + printf("%s\n", message); + } + + void Timer::initTimer() + { + initVirtualTimer(); + } + + u32 Timer::getRealTime() + { + timeval tv; + gettimeofday(&tv, 0); + return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000); + } + +} // end namespace os + +#endif // end linux / windows + +namespace os +{ + // The platform independent implementation of the printer + ILogger* Printer::Logger = 0; + + void Printer::log(const c8* message, ELOG_LEVEL ll) + { + if (Logger) + Logger->log(message, ll); + } + + void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll) + { + if (!Logger) + return; + + Logger->log(message, hint, ll); + } + + void Printer::log(const wchar_t* message, ELOG_LEVEL ll) + { + if (Logger) + Logger->log(message, ll); + } + + + // our Randomizer is not really os specific, so we + // code one for all, which should work on every platform the same, + // which is desireable. + + s32 Randomizer::seed = 0x0f0f0f0f; + + //! generates a pseudo random number + s32 Randomizer::rand() + { + const s32 m = 2147483399; // a non-Mersenne prime + const s32 a = 40692; // another spectral success story + const s32 q = m/a; + const s32 r = m%a; // again less than q + + seed = a * (seed%q) - r* (seed/q); + if (seed<0) seed += m; + + return seed; + } + + //! resets the randomizer + void Randomizer::reset() + { + seed = 0x0f0f0f0f; + } + + + // ------------------------------------------------------ + // virtual timer implementation + + f32 Timer::VirtualTimerSpeed = 1.0f; + s32 Timer::VirtualTimerStopCounter = 0; + u32 Timer::LastVirtualTime = 0; + u32 Timer::StartRealTime = 0; + u32 Timer::StaticTime = 0; + + //! returns current virtual time + u32 Timer::getTime() + { + if (isStopped()) + return LastVirtualTime; + + return LastVirtualTime + (u32)((StaticTime - StartRealTime) * VirtualTimerSpeed); + } + + //! ticks, advances the virtual timer + void Timer::tick() + { + StaticTime = getRealTime(); + } + + //! sets the current virtual time + void Timer::setTime(u32 time) + { + StaticTime = getRealTime(); + LastVirtualTime = time; + StartRealTime = StaticTime; + } + + //! stops the virtual timer + void Timer::stopTimer() + { + if (!isStopped()) + { + // stop the virtual timer + LastVirtualTime = getTime(); + } + + --VirtualTimerStopCounter; + } + + //! starts the virtual timer + void Timer::startTimer() + { + ++VirtualTimerStopCounter; + + if (!isStopped()) + { + // restart virtual timer + setTime(LastVirtualTime); + } + } + + //! sets the speed of the virtual timer + void Timer::setSpeed(f32 speed) + { + setTime(getTime()); + + VirtualTimerSpeed = speed; + if (VirtualTimerSpeed < 0.0f) + VirtualTimerSpeed = 0.0f; + } + + //! gets the speed of the virtual timer + f32 Timer::getSpeed() + { + return VirtualTimerSpeed; + } + + //! returns if the timer currently is stopped + bool Timer::isStopped() + { + return VirtualTimerStopCounter != 0; + } + + void Timer::initVirtualTimer() + { + StaticTime = getRealTime(); + StartRealTime = StaticTime; + } + +} // end namespace os +} // end namespace irr + diff --git a/src/dep/src/irrlicht/os.h b/src/dep/src/irrlicht/os.h new file mode 100644 index 0000000..5c3b8c2 --- /dev/null +++ b/src/dep/src/irrlicht/os.h @@ -0,0 +1,107 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_OS_H_INCLUDED__ +#define __IRR_OS_H_INCLUDED__ + +#include "IrrCompileConfig.h" // for endian check +#include "irrTypes.h" +#include "ILogger.h" + +namespace irr +{ + +namespace os +{ + class Byteswap + { + public: + static u16 byteswap(u16 num); + static s16 byteswap(s16 num); + static u32 byteswap(u32 num); + static s32 byteswap(s32 num); + static f32 byteswap(f32 num); + }; + + class Printer + { + public: + // prints out a string to the console out stdout or debug log or whatever + static void print(const c8* message); + static void log(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION); + static void log(const c8* message, const c8* hint, ELOG_LEVEL ll = ELL_INFORMATION); + static void log(const wchar_t* message, ELOG_LEVEL ll = ELL_INFORMATION); + static ILogger* Logger; + }; + + + class Randomizer + { + public: + + //! resets the randomizer + static void reset(); + + //! generates a pseudo random number + static s32 rand(); + + private: + + static s32 seed; + }; + + + + + class Timer + { + public: + + //! returns the current time in milliseconds + static u32 getTime(); + + //! initializes the real timer + static void initTimer(); + + //! sets the current virtual (game) time + static void setTime(u32 time); + + //! stops the virtual (game) timer + static void stopTimer(); + + //! starts the game timer + static void startTimer(); + + //! sets the speed of the virtual timer + static void setSpeed(f32 speed); + + //! gets the speed of the virtual timer + static f32 getSpeed(); + + //! returns if the timer currently is stopped + static bool isStopped(); + + //! makes the virtual timer update the time value based on the real time + static void tick(); + + //! returns the current real time in milliseconds + static u32 getRealTime(); + + private: + + static void initVirtualTimer(); + + static f32 VirtualTimerSpeed; + static s32 VirtualTimerStopCounter; + static u32 StartRealTime; + static u32 LastVirtualTime; + static u32 StaticTime; + }; + +} // end namespace os +} // end namespace irr + + +#endif + diff --git a/src/dep/src/irrlicht/source.txt b/src/dep/src/irrlicht/source.txt new file mode 100644 index 0000000..f1a06be --- /dev/null +++ b/src/dep/src/irrlicht/source.txt @@ -0,0 +1,40 @@ +Source code of the Irrlicht Engine + +The complete source of the Irrlicht Engine can be found when decompressing +the .zip file included in this directory. +Please note that YOU DO NOT NEED THIS SOURCE to develop 3d applications with +the Irrlicht Engine. Instead, please use the .dll in the \bin directory, the +.lib in the \lib directory and the header files in the \include directory. + +You will find a good tutorial how to set up your development environment and to +use the engine in the \examples directory. (Try 1.helloworld) + +The source of the engine is only included because of the following reasons: + + - To let developers be able to debug the engine. + - To let developers be able to make changes to the engine. + - To let developers be able to compile their own versions of the engine. + + + +HOW TO COMPILE THE ENGINE WITH LINUX + +If you wish to compile the engine in linux yourself, unzip the source source.zip +file in the \source directory. Run a 'make' in the now existing new subfolder 'Irrlicht'. +After this, you should be able to make all example applications in \examples. +Then just start an X Server and run them, from the directory where they are. + +If you get a compiling/linking problem like + + undefined reference to `glXGetProcAddress' + +Then there are several solutions: +A) This disables the use of OpenGL extensions: + Open the file IrrCompileConfig.h, comment out _IRR_OPENGL_USE_EXTPOINTER_, + and recompile Irrlicht using + make clean + make +B) Replace all occurrences of 'glXGetProcAddress' with 'glXGetProcAddressARB' and run a + make + This will solve the issue but keep the OpenGL extension enabled. + diff --git a/src/dep/src/irrlicht/zlib/ChangeLog b/src/dep/src/irrlicht/zlib/ChangeLog new file mode 100644 index 0000000..1ac9463 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/ChangeLog @@ -0,0 +1,855 @@ + + ChangeLog file for zlib + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/src/dep/src/irrlicht/zlib/FAQ b/src/dep/src/irrlicht/zlib/FAQ new file mode 100644 index 0000000..15d0436 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/FAQ @@ -0,0 +1,339 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. + See the file win32/DLL_FAQ.txt in the zlib distribution. + Pointers to the precompiled DLL are found in the zlib web site at + http://www.zlib.org. + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact us (zlib@gzip.org). Examples of zlib usage are in the files + example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to it. + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . + To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip + formats use the same compressed data format internally, but have different + headers and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about + a single file, such as the name and last modification date. The zlib + format on the other hand was designed for in-memory and communication + channel applications, and has a much more compact header and trailer and + uses a faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode + the gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's Init functions allow + for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + It should. It has been tested on 64-bit machines, and has no dependence + on any data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format + than does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically + use Z_FULL_FLUSH, carefully write all the pending data at those points, + and keep an index of those locations, then you can start decompression + at those points. You have to be careful to not use Z_FULL_FLUSH too + often, since it can significantly degrade compression. + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + We don't know for sure. We have heard occasional reports of success on + these systems. If you do use it on one of these, please provide us with + a report, instructions, and patches that we can reference when we get + these questions. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at + to understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit + only if the compiler's "long" type is 32 bits. If the compiler's "long" + type is 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib + is compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of a 4K string space, other than the caller of + gzprintf() assuring that the output will not exceed 4K. On the other + hand, if zlib is compiled to use snprintf() or vsnprintf(), which should + normally be the case, then there is no vulnerability. The ./configure + script will display warnings if an insecure variation of sprintf() will + be used by gzprintf(). Also the zlibCompileFlags() function will return + information on what variant of sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://www.zlib.org/ + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly. So now, we simply make sure that the code always + works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of + deflate is not affected. This only started showing up recently since + zlib 1.2.x uses malloc() by default for allocations, whereas earlier + versions used calloc(), which zeros out the allocated memory. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very weak + and can be broken with freely available programs. To get strong encryption, + use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. + For PKZIP compatible "encryption", look at http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion + with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specficiation in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. + In any case, the compression improvements are so modest compared to other + more modern approaches, that it's not worth the effort to implement. + +41. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/src/dep/src/irrlicht/zlib/INDEX b/src/dep/src/irrlicht/zlib/INDEX new file mode 100644 index 0000000..4d7eac4 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/INDEX @@ -0,0 +1,51 @@ +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +zconf.in.h template for zconf.h (used by configure) + +amiga/ makefiles for Amiga SAS C +as400/ makefiles for IBM AS/400 +msdos/ makefiles for MSDOS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +projects/ projects for various Integrated Development Environments +qnx/ makefiles for QNX +win32/ makefiles for Windows + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzio.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties +See contrib/README.contrib diff --git a/src/dep/src/irrlicht/zlib/README b/src/dep/src/irrlicht/zlib/README new file mode 100644 index 0000000..80f71ae --- /dev/null +++ b/src/dep/src/irrlicht/zlib/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, 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 notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/src/dep/src/irrlicht/zlib/adler32.c b/src/dep/src/irrlicht/zlib/adler32.c new file mode 100644 index 0000000..f201d67 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/src/dep/src/irrlicht/zlib/algorithm.txt b/src/dep/src/irrlicht/zlib/algorithm.txt new file mode 100644 index 0000000..9f6b068 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/src/dep/src/irrlicht/zlib/compress.c b/src/dep/src/irrlicht/zlib/compress.c new file mode 100644 index 0000000..d37e84f --- /dev/null +++ b/src/dep/src/irrlicht/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/src/dep/src/irrlicht/zlib/crc32.c b/src/dep/src/irrlicht/zlib/crc32.c new file mode 100644 index 0000000..32814c2 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/src/dep/src/irrlicht/zlib/crc32.h b/src/dep/src/irrlicht/zlib/crc32.h new file mode 100644 index 0000000..5de49bc --- /dev/null +++ b/src/dep/src/irrlicht/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/src/dep/src/irrlicht/zlib/deflate.c b/src/dep/src/irrlicht/zlib/deflate.c new file mode 100644 index 0000000..529f716 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/src/dep/src/irrlicht/zlib/deflate.h b/src/dep/src/irrlicht/zlib/deflate.h new file mode 100644 index 0000000..222c53e --- /dev/null +++ b/src/dep/src/irrlicht/zlib/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/src/dep/src/irrlicht/zlib/gzio.c b/src/dep/src/irrlicht/zlib/gzio.c new file mode 100644 index 0000000..5e20a4a --- /dev/null +++ b/src/dep/src/irrlicht/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/src/dep/src/irrlicht/zlib/infback.c b/src/dep/src/irrlicht/zlib/infback.c new file mode 100644 index 0000000..1e03e1b --- /dev/null +++ b/src/dep/src/irrlicht/zlib/infback.c @@ -0,0 +1,623 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/src/dep/src/irrlicht/zlib/inffast.c b/src/dep/src/irrlicht/zlib/inffast.c new file mode 100644 index 0000000..fa31cad --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/src/dep/src/irrlicht/zlib/inffast.h b/src/dep/src/irrlicht/zlib/inffast.h new file mode 100644 index 0000000..614fa78 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/src/dep/src/irrlicht/zlib/inffixed.h b/src/dep/src/irrlicht/zlib/inffixed.h new file mode 100644 index 0000000..423d5c5 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/src/dep/src/irrlicht/zlib/inflate.c b/src/dep/src/irrlicht/zlib/inflate.c new file mode 100644 index 0000000..33ea902 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/src/dep/src/irrlicht/zlib/inflate.h b/src/dep/src/irrlicht/zlib/inflate.h new file mode 100644 index 0000000..fbbc871 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/src/dep/src/irrlicht/zlib/inftrees.c b/src/dep/src/irrlicht/zlib/inftrees.c new file mode 100644 index 0000000..38ded81 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/dep/src/irrlicht/zlib/inftrees.h b/src/dep/src/irrlicht/zlib/inftrees.h new file mode 100644 index 0000000..dc0fd56 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/dep/src/irrlicht/zlib/trees.c b/src/dep/src/irrlicht/zlib/trees.c new file mode 100644 index 0000000..7a04802 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/src/dep/src/irrlicht/zlib/trees.h b/src/dep/src/irrlicht/zlib/trees.h new file mode 100644 index 0000000..1ca868b --- /dev/null +++ b/src/dep/src/irrlicht/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/src/dep/src/irrlicht/zlib/uncompr.c b/src/dep/src/irrlicht/zlib/uncompr.c new file mode 100644 index 0000000..ad6db0a --- /dev/null +++ b/src/dep/src/irrlicht/zlib/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/src/dep/src/irrlicht/zlib/zconf.h b/src/dep/src/irrlicht/zlib/zconf.h new file mode 100644 index 0000000..e3b0c96 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/dep/src/irrlicht/zlib/zlib.3 b/src/dep/src/irrlicht/zlib/zlib.3 new file mode 100644 index 0000000..f6b0da1 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/zlib.3 @@ -0,0 +1,159 @@ +.TH ZLIB 3 "18 July 2005" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later +and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I example.c +and +.IR minigzip.c . +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source, +and are concerned primarily with bug fixes and portability enhancements. +.LP +A Java implementation of +.I zlib +is available in the Java Development Kit 1.1: +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://www.cpan.org/modules/by-module/Compress/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://www.python.org/doc/lib/module-zlib.html +.LP +A +.I zlib +binding for +.IR tcl (1), +written by Andreas Kupries (a.kupries@westend.com), +is availlable at: +.IP +http://www.westend.com/~kupries/doc/trf/man/man.html +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/unzip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +web site. +.SH "SEE ALSO" +The +.I zlib +web site can be found at either of these locations: +.IP +http://www.zlib.org +.br +http://www.gzip.org/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) +.br +http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) +.br +http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.LP +Mark Nelson (markn@ieee.org) wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://dogma.net/markn/articles/zlibtool/zlibtool.htm +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://www.gzip.org/zlib/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.3 +Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/src/dep/src/irrlicht/zlib/zlib.h b/src/dep/src/irrlicht/zlib/zlib.h new file mode 100644 index 0000000..62d0e46 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, 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 notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/dep/src/irrlicht/zlib/zutil.c b/src/dep/src/irrlicht/zlib/zutil.c new file mode 100644 index 0000000..0f4bd78 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/src/dep/src/irrlicht/zlib/zutil.h b/src/dep/src/irrlicht/zlib/zutil.h new file mode 100644 index 0000000..0ba6e02 --- /dev/null +++ b/src/dep/src/irrlicht/zlib/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */